Minor loplugin:stringconstant improvements
Change-Id: I0b39526c0f0854ddbb29e77ece303cf2bdd842c4
This commit is contained in:
@@ -75,6 +75,24 @@ bool hasOverloads(FunctionDecl const * decl, unsigned arguments) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CXXConstructExpr const * lookForCXXConstructExpr(Expr const * expr) {
|
||||||
|
if (auto e = dyn_cast<MaterializeTemporaryExpr>(expr)) {
|
||||||
|
expr = e->GetTemporaryExpr();
|
||||||
|
}
|
||||||
|
if (auto e = dyn_cast<CXXFunctionalCastExpr>(expr)) {
|
||||||
|
expr = e->getSubExpr();
|
||||||
|
}
|
||||||
|
if (auto e = dyn_cast<CXXBindTemporaryExpr>(expr)) {
|
||||||
|
expr = e->getSubExpr();
|
||||||
|
}
|
||||||
|
return dyn_cast<CXXConstructExpr>(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
char const * adviseNonArray(bool nonArray) {
|
||||||
|
return nonArray
|
||||||
|
? ", and turn the non-array string constant into an array" : "";
|
||||||
|
}
|
||||||
|
|
||||||
class StringConstant:
|
class StringConstant:
|
||||||
public RecursiveASTVisitor<StringConstant>, public loplugin::RewritePlugin
|
public RecursiveASTVisitor<StringConstant>, public loplugin::RewritePlugin
|
||||||
{
|
{
|
||||||
@@ -113,7 +131,7 @@ private:
|
|||||||
|
|
||||||
void reportChange(
|
void reportChange(
|
||||||
Expr const * expr, ChangeKind kind, std::string const & original,
|
Expr const * expr, ChangeKind kind, std::string const & original,
|
||||||
std::string const & replacement, PassThrough pass,
|
std::string const & replacement, PassThrough pass, bool nonArray,
|
||||||
char const * rewriteFrom, char const * rewriteTo);
|
char const * rewriteFrom, char const * rewriteTo);
|
||||||
|
|
||||||
void checkEmpty(
|
void checkEmpty(
|
||||||
@@ -134,6 +152,9 @@ private:
|
|||||||
CallExpr const * expr, unsigned arg, FunctionDecl const * callee,
|
CallExpr const * expr, unsigned arg, FunctionDecl const * callee,
|
||||||
bool explicitFunctionalCastNotation);
|
bool explicitFunctionalCastNotation);
|
||||||
|
|
||||||
|
void handleFunArgOstring(
|
||||||
|
CallExpr const * expr, unsigned arg, FunctionDecl const * callee);
|
||||||
|
|
||||||
std::stack<Expr const *> calls_;
|
std::stack<Expr const *> calls_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -490,7 +511,7 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
|
|||||||
if (non) {
|
if (non) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with string constant argument containging"
|
("call of '%0' with string constant argument containging"
|
||||||
" non-ASCII characters"),
|
" non-ASCII characters"),
|
||||||
expr->getExprLoc())
|
expr->getExprLoc())
|
||||||
<< fdecl->getQualifiedNameAsString() << expr->getSourceRange();
|
<< fdecl->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
@@ -498,16 +519,16 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
|
|||||||
if (emb) {
|
if (emb) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with string constant argument containging embedded"
|
("call of '%0' with string constant argument containging"
|
||||||
" NULs"),
|
" embedded NULs"),
|
||||||
expr->getExprLoc())
|
expr->getExprLoc())
|
||||||
<< fdecl->getQualifiedNameAsString() << expr->getSourceRange();
|
<< fdecl->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
}
|
}
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite call of %0 with empty string constant argument as"
|
("rewrite call of '%0' with empty string constant argument as"
|
||||||
" call of rtl::OUString::isEmpty"),
|
" call of 'rtl::OUString::isEmpty'"),
|
||||||
expr->getExprLoc())
|
expr->getExprLoc())
|
||||||
<< fdecl->getQualifiedNameAsString() << expr->getSourceRange();
|
<< fdecl->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
return true;
|
return true;
|
||||||
@@ -531,7 +552,7 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
|
|||||||
if (non) {
|
if (non) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with string constant argument containging"
|
("call of '%0' with string constant argument containging"
|
||||||
" non-ASCII characters"),
|
" non-ASCII characters"),
|
||||||
expr->getExprLoc())
|
expr->getExprLoc())
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
@@ -540,7 +561,7 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
|
|||||||
if (emb) {
|
if (emb) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with string constant argument containging"
|
("call of '%0' with string constant argument containging"
|
||||||
" embedded NULs"),
|
" embedded NULs"),
|
||||||
expr->getExprLoc())
|
expr->getExprLoc())
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
@@ -549,8 +570,8 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
|
|||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite call of %0 with empty string constant argument as"
|
("rewrite call of '%0' with empty string constant argument"
|
||||||
" call of rtl::OUString::isEmpty"),
|
" as call of 'rtl::OUString::isEmpty'"),
|
||||||
expr->getExprLoc())
|
expr->getExprLoc())
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
<< expr->getSourceRange();
|
<< expr->getSourceRange();
|
||||||
@@ -576,7 +597,7 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
|
|||||||
if (non) {
|
if (non) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with string constant argument containging"
|
("call of '%0' with string constant argument containging"
|
||||||
" non-ASCII characters"),
|
" non-ASCII characters"),
|
||||||
expr->getExprLoc())
|
expr->getExprLoc())
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
@@ -585,7 +606,7 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
|
|||||||
if (emb) {
|
if (emb) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with string constant argument containging"
|
("call of '%0' with string constant argument containging"
|
||||||
" embedded NULs"),
|
" embedded NULs"),
|
||||||
expr->getExprLoc())
|
expr->getExprLoc())
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
@@ -594,8 +615,8 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
|
|||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite call of %0 with empty string constant argument as"
|
("rewrite call of '%0' with empty string constant argument"
|
||||||
" call of !rtl::OUString::isEmpty"),
|
" as call of '!rtl::OUString::isEmpty'"),
|
||||||
expr->getExprLoc())
|
expr->getExprLoc())
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
<< expr->getSourceRange();
|
<< expr->getSourceRange();
|
||||||
@@ -620,7 +641,7 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
|
|||||||
if (non) {
|
if (non) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with string constant argument containging"
|
("call of '%0' with string constant argument containging"
|
||||||
" non-ASCII characters"),
|
" non-ASCII characters"),
|
||||||
expr->getExprLoc())
|
expr->getExprLoc())
|
||||||
<< fdecl->getQualifiedNameAsString() << expr->getSourceRange();
|
<< fdecl->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
@@ -628,16 +649,16 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
|
|||||||
if (emb) {
|
if (emb) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with string constant argument containging embedded"
|
("call of '%0' with string constant argument containging"
|
||||||
" NULs"),
|
" embedded NULs"),
|
||||||
expr->getExprLoc())
|
expr->getExprLoc())
|
||||||
<< fdecl->getQualifiedNameAsString() << expr->getSourceRange();
|
<< fdecl->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
}
|
}
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite call of %0 with empty string constant argument as"
|
("rewrite call of '%0' with empty string constant argument as"
|
||||||
" call of rtl::OUString::clear"),
|
" call of 'rtl::OUString::clear'"),
|
||||||
expr->getExprLoc())
|
expr->getExprLoc())
|
||||||
<< fdecl->getQualifiedNameAsString() << expr->getSourceRange();
|
<< fdecl->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
return true;
|
return true;
|
||||||
@@ -669,47 +690,8 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
|
|||||||
{
|
{
|
||||||
switch (fdecl->getNumParams()) {
|
switch (fdecl->getNumParams()) {
|
||||||
case 1:
|
case 1:
|
||||||
{
|
handleFunArgOstring(expr, 0, fdecl);
|
||||||
// char const * const s = "foo"; b.append(s) ->
|
break;
|
||||||
// char const s[] = "foo"; b.append(s):
|
|
||||||
unsigned n;
|
|
||||||
bool nonArray;
|
|
||||||
bool non;
|
|
||||||
bool emb;
|
|
||||||
bool trm;
|
|
||||||
if (!isStringConstant(
|
|
||||||
expr->getArg(0)->IgnoreParenImpCasts(), &n, &nonArray,
|
|
||||||
&non, &emb, &trm))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (non || emb) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!trm) {
|
|
||||||
report(
|
|
||||||
DiagnosticsEngine::Warning,
|
|
||||||
("call of %0 with string constant argument lacking a"
|
|
||||||
" terminating NUL"),
|
|
||||||
getMemberLocation(expr))
|
|
||||||
<< fdecl->getQualifiedNameAsString()
|
|
||||||
<< expr->getSourceRange();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
std::string repl;
|
|
||||||
checkEmpty(expr, fdecl, TreatEmpty::Error, n, &repl);
|
|
||||||
if (nonArray) {
|
|
||||||
report(
|
|
||||||
DiagnosticsEngine::Warning,
|
|
||||||
("in call of %0 with non-array string constant"
|
|
||||||
" argument, change that argument into an array"),
|
|
||||||
getMemberLocation(expr))
|
|
||||||
<< fdecl->getQualifiedNameAsString()
|
|
||||||
<< expr->getSourceRange();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
// b.append("foo", 3) -> b.append("foo"):
|
// b.append("foo", 3) -> b.append("foo"):
|
||||||
@@ -725,11 +707,32 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
|
|||||||
handleCharLen(
|
handleCharLen(
|
||||||
expr, 0, 1, fdecl, "rtl::OStringBuffer::append",
|
expr, 0, 1, fdecl, "rtl::OStringBuffer::append",
|
||||||
TreatEmpty::Error);
|
TreatEmpty::Error);
|
||||||
return true;
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (dc.Function("insert").Class("OStringBuffer").Namespace("rtl")
|
||||||
|
.GlobalNamespace())
|
||||||
|
{
|
||||||
|
switch (fdecl->getNumParams()) {
|
||||||
|
case 2:
|
||||||
|
handleFunArgOstring(expr, 1, fdecl);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
// b.insert(i, "foo", 3) -> b.insert(i, "foo"):
|
||||||
|
handleCharLen(
|
||||||
|
expr, 1, 2, fdecl, "rtl::OStringBuffer::insert",
|
||||||
|
TreatEmpty::Error);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return true;
|
break;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -903,9 +906,9 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) {
|
|||||||
{
|
{
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite call of %0 with construction of"
|
("rewrite call of '%0' with construction of"
|
||||||
" %1 with empty string constant argument"
|
" %1 with empty string constant argument"
|
||||||
" as call of rtl::OUString::isEmpty"),
|
" as call of 'rtl::OUString::isEmpty'"),
|
||||||
getMemberLocation(call))
|
getMemberLocation(call))
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
<< classdecl << call->getSourceRange();
|
<< classdecl << call->getSourceRange();
|
||||||
@@ -916,9 +919,9 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) {
|
|||||||
{
|
{
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite call of %0 with construction of"
|
("rewrite call of '%0' with construction of"
|
||||||
" %1 with empty string constant argument"
|
" %1 with empty string constant argument"
|
||||||
" as call of !rtl::OUString::isEmpty"),
|
" as call of '!rtl::OUString::isEmpty'"),
|
||||||
getMemberLocation(call))
|
getMemberLocation(call))
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
<< classdecl << call->getSourceRange();
|
<< classdecl << call->getSourceRange();
|
||||||
@@ -931,8 +934,9 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) {
|
|||||||
{
|
{
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with suspicous construction of"
|
("call of '%0' with suspicous construction"
|
||||||
" %1 with empty string constant argument"),
|
" of %1 with empty string constant"
|
||||||
|
" argument"),
|
||||||
getMemberLocation(call))
|
getMemberLocation(call))
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
<< classdecl << call->getSourceRange();
|
<< classdecl << call->getSourceRange();
|
||||||
@@ -943,9 +947,9 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) {
|
|||||||
{
|
{
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite call of %0 with construction of"
|
("rewrite call of '%0' with construction of"
|
||||||
" %1 with empty string constant argument"
|
" %1 with empty string constant argument"
|
||||||
" as call of rtl::OUString::clear"),
|
" as call of 'rtl::OUString::clear'"),
|
||||||
getMemberLocation(call))
|
getMemberLocation(call))
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
<< classdecl << call->getSourceRange();
|
<< classdecl << call->getSourceRange();
|
||||||
@@ -958,13 +962,12 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) {
|
|||||||
{
|
{
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
(("rewrite call of %0 with construction of"
|
("rewrite call of '%0' with construction of"
|
||||||
" %1 with ")
|
" %1 with %2 as 'operator =='"),
|
||||||
+ describeChangeKind(kind)
|
|
||||||
+ " as operator =="),
|
|
||||||
getMemberLocation(call))
|
getMemberLocation(call))
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
<< classdecl << call->getSourceRange();
|
<< classdecl << describeChangeKind(kind)
|
||||||
|
<< call->getSourceRange();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((dc.Operator(OO_Plus).Namespace("rtl")
|
if ((dc.Operator(OO_Plus).Namespace("rtl")
|
||||||
@@ -1013,22 +1016,20 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) {
|
|||||||
if (kind == ChangeKind::SingleChar) {
|
if (kind == ChangeKind::SingleChar) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite construction of %0 with "
|
("rewrite construction of %0 with %1 in"
|
||||||
+ describeChangeKind(kind)
|
" call of '%2' as construction of"
|
||||||
+ (" in call of %1 as construction of"
|
" 'OUStringLiteral1'"),
|
||||||
" OUStringLiteral1")),
|
|
||||||
getMemberLocation(expr))
|
getMemberLocation(expr))
|
||||||
<< classdecl
|
<< classdecl << describeChangeKind(kind)
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
<< expr->getSourceRange();
|
<< expr->getSourceRange();
|
||||||
} else {
|
} else {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("elide construction of %0 with "
|
("elide construction of %0 with %1 in"
|
||||||
+ describeChangeKind(kind)
|
" call of '%2'"),
|
||||||
+ " in call of %1"),
|
|
||||||
getMemberLocation(expr))
|
getMemberLocation(expr))
|
||||||
<< classdecl
|
<< classdecl << describeChangeKind(kind)
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
<< expr->getSourceRange();
|
<< expr->getSourceRange();
|
||||||
}
|
}
|
||||||
@@ -1220,8 +1221,8 @@ bool StringConstant::isZero(Expr const * expr) {
|
|||||||
|
|
||||||
void StringConstant::reportChange(
|
void StringConstant::reportChange(
|
||||||
Expr const * expr, ChangeKind kind, std::string const & original,
|
Expr const * expr, ChangeKind kind, std::string const & original,
|
||||||
std::string const & replacement, PassThrough pass, char const * rewriteFrom,
|
std::string const & replacement, PassThrough pass, bool nonArray,
|
||||||
char const * rewriteTo)
|
char const * rewriteFrom, char const * rewriteTo)
|
||||||
{
|
{
|
||||||
assert((rewriteFrom == nullptr) == (rewriteTo == nullptr));
|
assert((rewriteFrom == nullptr) == (rewriteTo == nullptr));
|
||||||
if (pass != PassThrough::No && !calls_.empty()) {
|
if (pass != PassThrough::No && !calls_.empty()) {
|
||||||
@@ -1259,11 +1260,11 @@ void StringConstant::reportChange(
|
|||||||
{
|
{
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite call of %0 with call of " + original
|
("rewrite call of '%0' with call of %1 with"
|
||||||
+ (" with empty string constant argument as"
|
" empty string constant argument as call of"
|
||||||
" call of rtl::OUString::isEmpty")),
|
" 'rtl::OUString::isEmpty'"),
|
||||||
getMemberLocation(call))
|
getMemberLocation(call))
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString() << original
|
||||||
<< call->getSourceRange();
|
<< call->getSourceRange();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1272,11 +1273,11 @@ void StringConstant::reportChange(
|
|||||||
{
|
{
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite call of %0 with call of " + original
|
("rewrite call of '%0' with call of %1 with"
|
||||||
+ (" with empty string constant argument as"
|
" empty string constant argument as call of"
|
||||||
" call of !rtl::OUString::isEmpty")),
|
" '!rtl::OUString::isEmpty'"),
|
||||||
getMemberLocation(call))
|
getMemberLocation(call))
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString() << original
|
||||||
<< call->getSourceRange();
|
<< call->getSourceRange();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1287,10 +1288,10 @@ void StringConstant::reportChange(
|
|||||||
{
|
{
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with suspicous call of " + original
|
("call of '%0' with suspicous call of %1 with"
|
||||||
+ " with empty string constant argument"),
|
" empty string constant argument"),
|
||||||
getMemberLocation(call))
|
getMemberLocation(call))
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString() << original
|
||||||
<< call->getSourceRange();
|
<< call->getSourceRange();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1299,11 +1300,11 @@ void StringConstant::reportChange(
|
|||||||
{
|
{
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite call of %0 with call of " + original
|
("rewrite call of '%0' with call of %1 with"
|
||||||
+ (" with empty string constant argument as"
|
" empty string constant argument as call of"
|
||||||
" call of rtl::OUString::call")),
|
" rtl::OUString::call"),
|
||||||
getMemberLocation(call))
|
getMemberLocation(call))
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString() << original
|
||||||
<< call->getSourceRange();
|
<< call->getSourceRange();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1326,20 +1327,19 @@ void StringConstant::reportChange(
|
|||||||
{
|
{
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("elide call of " + original + " with "
|
"elide call of %0 with %1 in call of '%2'",
|
||||||
+ describeChangeKind(kind) + " in call of %0"),
|
|
||||||
getMemberLocation(expr))
|
getMemberLocation(expr))
|
||||||
|
<< original << describeChangeKind(kind)
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
<< expr->getSourceRange();
|
<< expr->getSourceRange();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite call of " + original + " with "
|
("rewrite call of %0 with %1 in call of '%2' as"
|
||||||
+ describeChangeKind(kind)
|
" (implicit) construction of 'OUString'"),
|
||||||
+ (" in call of %0 as (implicit) construction of"
|
|
||||||
" rtl::OUString")),
|
|
||||||
getMemberLocation(expr))
|
getMemberLocation(expr))
|
||||||
|
<< original << describeChangeKind(kind)
|
||||||
<< fdecl->getQualifiedNameAsString()
|
<< fdecl->getQualifiedNameAsString()
|
||||||
<< expr->getSourceRange();
|
<< expr->getSourceRange();
|
||||||
return;
|
return;
|
||||||
@@ -1356,23 +1356,21 @@ void StringConstant::reportChange(
|
|||||||
if (pass == PassThrough::EmptyConstantString) {
|
if (pass == PassThrough::EmptyConstantString) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite construction of %0 with call of "
|
("rewrite construction of %0 with call of %1"
|
||||||
+ original
|
" with empty string constant argument as"
|
||||||
+ (" with empty string constant argument as"
|
" default construction of %0"),
|
||||||
" default construction of %0")),
|
|
||||||
getMemberLocation(call))
|
getMemberLocation(call))
|
||||||
<< classdecl->getQualifiedNameAsString()
|
<< classdecl << original
|
||||||
<< call->getSourceRange();
|
<< call->getSourceRange();
|
||||||
} else {
|
} else {
|
||||||
assert(pass == PassThrough::NonEmptyConstantString);
|
assert(pass == PassThrough::NonEmptyConstantString);
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("elide call of " + original + " with "
|
("elide call of %0 with %1 in construction of"
|
||||||
+ describeChangeKind(kind)
|
" %2"),
|
||||||
+ " in construction of %0"),
|
|
||||||
getMemberLocation(expr))
|
getMemberLocation(expr))
|
||||||
<< classdecl->getQualifiedNameAsString()
|
<< original << describeChangeKind(kind)
|
||||||
<< expr->getSourceRange();
|
<< classdecl << expr->getSourceRange();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1382,7 +1380,7 @@ void StringConstant::reportChange(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rewriter != nullptr && rewriteFrom != nullptr) {
|
if (rewriter != nullptr && !nonArray && rewriteFrom != nullptr) {
|
||||||
SourceLocation loc = getMemberLocation(expr);
|
SourceLocation loc = getMemberLocation(expr);
|
||||||
while (compiler.getSourceManager().isMacroArgExpansion(loc)) {
|
while (compiler.getSourceManager().isMacroArgExpansion(loc)) {
|
||||||
loc = compiler.getSourceManager().getImmediateMacroCallerLoc(loc);
|
loc = compiler.getSourceManager().getImmediateMacroCallerLoc(loc);
|
||||||
@@ -1401,10 +1399,10 @@ void StringConstant::reportChange(
|
|||||||
}
|
}
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("rewrite call of " + original + " with " + describeChangeKind(kind)
|
"rewrite call of '%0' with %1 as call of '%2'%3",
|
||||||
+ " as call of " + replacement),
|
|
||||||
getMemberLocation(expr))
|
getMemberLocation(expr))
|
||||||
<< expr->getSourceRange();
|
<< original << describeChangeKind(kind) << replacement
|
||||||
|
<< adviseNonArray(nonArray) << expr->getSourceRange();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringConstant::checkEmpty(
|
void StringConstant::checkEmpty(
|
||||||
@@ -1423,7 +1421,7 @@ void StringConstant::checkEmpty(
|
|||||||
case TreatEmpty::Error:
|
case TreatEmpty::Error:
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
"call of %0 with suspicous empty string constant argument",
|
"call of '%0' with suspicous empty string constant argument",
|
||||||
getMemberLocation(expr))
|
getMemberLocation(expr))
|
||||||
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
break;
|
break;
|
||||||
@@ -1450,7 +1448,7 @@ void StringConstant::handleChar(
|
|||||||
if (non) {
|
if (non) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with string constant argument containging non-ASCII"
|
("call of '%0' with string constant argument containging non-ASCII"
|
||||||
" characters"),
|
" characters"),
|
||||||
getMemberLocation(expr))
|
getMemberLocation(expr))
|
||||||
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
@@ -1459,7 +1457,7 @@ void StringConstant::handleChar(
|
|||||||
if (emb) {
|
if (emb) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with string constant argument containging embedded"
|
("call of '%0' with string constant argument containging embedded"
|
||||||
" NULs"),
|
" NULs"),
|
||||||
getMemberLocation(expr))
|
getMemberLocation(expr))
|
||||||
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
@@ -1468,7 +1466,7 @@ void StringConstant::handleChar(
|
|||||||
if (!trm) {
|
if (!trm) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with string constant argument lacking a terminating"
|
("call of '%0' with string constant argument lacking a terminating"
|
||||||
" NUL"),
|
" NUL"),
|
||||||
getMemberLocation(expr))
|
getMemberLocation(expr))
|
||||||
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
@@ -1483,7 +1481,7 @@ void StringConstant::handleChar(
|
|||||||
? PassThrough::EmptyConstantString
|
? PassThrough::EmptyConstantString
|
||||||
: PassThrough::NonEmptyConstantString)
|
: PassThrough::NonEmptyConstantString)
|
||||||
: PassThrough::No),
|
: PassThrough::No),
|
||||||
rewriteFrom, rewriteTo);
|
nonArray, rewriteFrom, rewriteTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringConstant::handleCharLen(
|
void StringConstant::handleCharLen(
|
||||||
@@ -1543,7 +1541,7 @@ void StringConstant::handleCharLen(
|
|||||||
if (non) {
|
if (non) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("call of %0 with string constant argument containging non-ASCII"
|
("call of '%0' with string constant argument containging non-ASCII"
|
||||||
" characters"),
|
" characters"),
|
||||||
getMemberLocation(expr))
|
getMemberLocation(expr))
|
||||||
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
@@ -1555,7 +1553,7 @@ void StringConstant::handleCharLen(
|
|||||||
checkEmpty(expr, callee, treatEmpty, n, &repl);
|
checkEmpty(expr, callee, treatEmpty, n, &repl);
|
||||||
reportChange(
|
reportChange(
|
||||||
expr, ChangeKind::CharLen, callee->getQualifiedNameAsString(), repl,
|
expr, ChangeKind::CharLen, callee->getQualifiedNameAsString(), repl,
|
||||||
PassThrough::No, nullptr, nullptr);
|
PassThrough::No, nonArray, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringConstant::handleOUStringCtor(
|
void StringConstant::handleOUStringCtor(
|
||||||
@@ -1588,8 +1586,8 @@ void StringConstant::handleOUStringCtor(
|
|||||||
if (e3->getNumArgs() == 0) {
|
if (e3->getNumArgs() == 0) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("in call of %0, replace default-constructed OUString with an empty"
|
("in call of '%0', replace default-constructed 'OUString' with an"
|
||||||
" string literal"),
|
" empty string literal"),
|
||||||
e3->getExprLoc())
|
e3->getExprLoc())
|
||||||
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
return;
|
return;
|
||||||
@@ -1605,8 +1603,8 @@ void StringConstant::handleOUStringCtor(
|
|||||||
if (!explicitFunctionalCastNotation) {
|
if (!explicitFunctionalCastNotation) {
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("in call of %0, replace OUString constructed from a"
|
("in call of '%0', replace 'OUString' constructed from a"
|
||||||
" sal_Unicode with an OUStringLiteral1"),
|
" 'sal_Unicode' with an 'OUStringLiteral1'"),
|
||||||
e3->getExprLoc())
|
e3->getExprLoc())
|
||||||
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
}
|
}
|
||||||
@@ -1695,12 +1693,114 @@ void StringConstant::handleOUStringCtor(
|
|||||||
}
|
}
|
||||||
report(
|
report(
|
||||||
DiagnosticsEngine::Warning,
|
DiagnosticsEngine::Warning,
|
||||||
("in call of %0, replace OUString constructed from a string literal"
|
("in call of '%0', replace 'OUString' constructed from a string literal"
|
||||||
" directly with the string literal"),
|
" directly with the string literal"),
|
||||||
e3->getExprLoc())
|
e3->getExprLoc())
|
||||||
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StringConstant::handleFunArgOstring(
|
||||||
|
CallExpr const * expr, unsigned arg, FunctionDecl const * callee)
|
||||||
|
{
|
||||||
|
auto argExpr = expr->getArg(arg)->IgnoreParenImpCasts();
|
||||||
|
unsigned n;
|
||||||
|
bool nonArray;
|
||||||
|
bool non;
|
||||||
|
bool emb;
|
||||||
|
bool trm;
|
||||||
|
if (isStringConstant(argExpr, &n, &nonArray, &non, &emb, &trm)) {
|
||||||
|
if (non || emb) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!trm) {
|
||||||
|
report(
|
||||||
|
DiagnosticsEngine::Warning,
|
||||||
|
("call of '%0' with string constant argument lacking a"
|
||||||
|
" terminating NUL"),
|
||||||
|
getMemberLocation(expr))
|
||||||
|
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string repl;
|
||||||
|
checkEmpty(expr, callee, TreatEmpty::Error, n, &repl);
|
||||||
|
if (nonArray) {
|
||||||
|
report(
|
||||||
|
DiagnosticsEngine::Warning,
|
||||||
|
("in call of '%0' with non-array string constant argument,"
|
||||||
|
" turn the non-array string constant into an array"),
|
||||||
|
getMemberLocation(expr))
|
||||||
|
<< callee->getQualifiedNameAsString() << expr->getSourceRange();
|
||||||
|
}
|
||||||
|
} else if (auto cexpr = lookForCXXConstructExpr(argExpr)) {
|
||||||
|
auto classdecl = cexpr->getConstructor()->getParent();
|
||||||
|
if (loplugin::DeclCheck(classdecl).Class("OString").Namespace("rtl")
|
||||||
|
.GlobalNamespace())
|
||||||
|
{
|
||||||
|
switch (cexpr->getConstructor()->getNumParams()) {
|
||||||
|
case 0:
|
||||||
|
report(
|
||||||
|
DiagnosticsEngine::Warning,
|
||||||
|
("in call of '%0', replace empty %1 constructor with empty"
|
||||||
|
" string literal"),
|
||||||
|
cexpr->getLocation())
|
||||||
|
<< callee->getQualifiedNameAsString() << classdecl
|
||||||
|
<< expr->getSourceRange();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (isStringConstant(
|
||||||
|
cexpr->getArg(0)->IgnoreParenImpCasts(), &n, &nonArray,
|
||||||
|
&non, &emb, &trm))
|
||||||
|
{
|
||||||
|
APSInt res;
|
||||||
|
if (cexpr->getArg(1)->EvaluateAsInt(
|
||||||
|
res, compiler.getASTContext()))
|
||||||
|
{
|
||||||
|
if (res == n && !emb && trm) {
|
||||||
|
report(
|
||||||
|
DiagnosticsEngine::Warning,
|
||||||
|
("in call of '%0', elide explicit %1"
|
||||||
|
" constructor%2"),
|
||||||
|
cexpr->getLocation())
|
||||||
|
<< callee->getQualifiedNameAsString()
|
||||||
|
<< classdecl << adviseNonArray(nonArray)
|
||||||
|
<< expr->getSourceRange();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (emb) {
|
||||||
|
report(
|
||||||
|
DiagnosticsEngine::Warning,
|
||||||
|
("call of %0 constructor with string constant"
|
||||||
|
" argument containing embedded NULs"),
|
||||||
|
cexpr->getLocation())
|
||||||
|
<< classdecl << cexpr->getSourceRange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!trm) {
|
||||||
|
report(
|
||||||
|
DiagnosticsEngine::Warning,
|
||||||
|
("call of %0 constructor with string constant"
|
||||||
|
" argument lacking a terminating NUL"),
|
||||||
|
cexpr->getLocation())
|
||||||
|
<< classdecl << cexpr->getSourceRange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
report(
|
||||||
|
DiagnosticsEngine::Warning,
|
||||||
|
"in call of '%0', elide explicit %1 constructor%2",
|
||||||
|
cexpr->getLocation())
|
||||||
|
<< callee->getQualifiedNameAsString() << classdecl
|
||||||
|
<< adviseNonArray(nonArray)
|
||||||
|
<< expr->getSourceRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loplugin::Plugin::Registration< StringConstant > X("stringconstant", true);
|
loplugin::Plugin::Registration< StringConstant > X("stringconstant", true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
52
compilerplugins/clang/test/stringconstant.cxx
Normal file
52
compilerplugins/clang/test/stringconstant.cxx
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||||
|
/*
|
||||||
|
* This file is part of the LibreOffice project.
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sal/config.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "com/sun/star/uno/Reference.hxx"
|
||||||
|
#include "rtl/strbuf.hxx"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
char const s1[] = "foo";
|
||||||
|
char const * const s2 = "foo";
|
||||||
|
|
||||||
|
OStringBuffer sb;
|
||||||
|
|
||||||
|
sb.append(OString()); // expected-error {{in call of 'rtl::OStringBuffer::append', replace empty 'OString' constructor with empty string literal [loplugin:stringconstant]}}
|
||||||
|
sb.append(OString("foo")); // expected-error {{in call of 'rtl::OStringBuffer::append', elide explicit 'OString' constructor [loplugin:stringconstant]}}
|
||||||
|
sb.append(OString(s1)); // expected-error {{in call of 'rtl::OStringBuffer::append', elide explicit 'OString' constructor [loplugin:stringconstant]}}
|
||||||
|
sb.append(OString(s2)); // expected-error {{in call of 'rtl::OStringBuffer::append', elide explicit 'OString' constructor, and turn the non-array string constant into an array [loplugin:stringconstant]}}
|
||||||
|
sb.append(OString("foo", std::strlen("foo"))); // expected-error {{in call of 'rtl::OStringBuffer::append', elide explicit 'OString' constructor [loplugin:stringconstant]}}
|
||||||
|
sb.append(OString(s1, std::strlen(s1))); // expected-error {{in call of 'rtl::OStringBuffer::append', elide explicit 'OString' constructor [loplugin:stringconstant]}}
|
||||||
|
sb.append(OString(s2, std::strlen(s2))); // expected-error {{in call of 'rtl::OStringBuffer::append', elide explicit 'OString' constructor, and turn the non-array string constant into an array [loplugin:stringconstant]}}
|
||||||
|
sb.append("foo");
|
||||||
|
sb.append(s1);
|
||||||
|
sb.append(s2); // expected-error {{in call of 'rtl::OStringBuffer::append' with non-array string constant argument, turn the non-array string constant into an array [loplugin:stringconstant]}}
|
||||||
|
sb.append("foo", std::strlen("foo")); // expected-error {{rewrite call of 'rtl::OStringBuffer::append' with string constant and matching length arguments as call of 'rtl::OStringBuffer::append' [loplugin:stringconstant]}}
|
||||||
|
sb.append(s1, std::strlen(s1)); // expected-error {{rewrite call of 'rtl::OStringBuffer::append' with string constant and matching length arguments as call of 'rtl::OStringBuffer::append' [loplugin:stringconstant]}}
|
||||||
|
sb.append(s2, std::strlen(s2)); // expected-error {{rewrite call of 'rtl::OStringBuffer::append' with string constant and matching length arguments as call of 'rtl::OStringBuffer::append', and turn the non-array string constant into an array [loplugin:stringconstant]}}
|
||||||
|
|
||||||
|
sb.insert(0, OString()); // expected-error {{in call of 'rtl::OStringBuffer::insert', replace empty 'OString' constructor with empty string literal [loplugin:stringconstant]}}
|
||||||
|
sb.insert(0, OString("foo")); // expected-error {{in call of 'rtl::OStringBuffer::insert', elide explicit 'OString' constructor [loplugin:stringconstant]}}
|
||||||
|
sb.insert(0, OString(s1)); // expected-error {{in call of 'rtl::OStringBuffer::insert', elide explicit 'OString' constructor [loplugin:stringconstant]}}
|
||||||
|
sb.insert(0, OString(s2)); // expected-error {{in call of 'rtl::OStringBuffer::insert', elide explicit 'OString' constructor, and turn the non-array string constant into an array [loplugin:stringconstant]}}
|
||||||
|
sb.insert(0, OString("foo", std::strlen("foo"))); // expected-error {{in call of 'rtl::OStringBuffer::insert', elide explicit 'OString' constructor [loplugin:stringconstant]}}
|
||||||
|
sb.insert(0, OString(s1, std::strlen(s1))); // expected-error {{in call of 'rtl::OStringBuffer::insert', elide explicit 'OString' constructor [loplugin:stringconstant]}}
|
||||||
|
sb.insert(0, OString(s2, std::strlen(s2))); // expected-error {{in call of 'rtl::OStringBuffer::insert', elide explicit 'OString' constructor, and turn the non-array string constant into an array [loplugin:stringconstant]}}
|
||||||
|
sb.insert(0, "foo");
|
||||||
|
sb.insert(0, s1);
|
||||||
|
sb.insert(0, s2); // expected-error {{in call of 'rtl::OStringBuffer::insert' with non-array string constant argument, turn the non-array string constant into an array [loplugin:stringconstant]}}
|
||||||
|
sb.insert(0, "foo", std::strlen("foo")); // expected-error {{rewrite call of 'rtl::OStringBuffer::insert' with string constant and matching length arguments as call of 'rtl::OStringBuffer::insert' [loplugin:stringconstant]}}
|
||||||
|
sb.insert(0, s1, std::strlen(s1)); // expected-error {{rewrite call of 'rtl::OStringBuffer::insert' with string constant and matching length arguments as call of 'rtl::OStringBuffer::insert' [loplugin:stringconstant]}}
|
||||||
|
sb.insert(0, s2, std::strlen(s2)); // expected-error {{rewrite call of 'rtl::OStringBuffer::insert' with string constant and matching length arguments as call of 'rtl::OStringBuffer::insert', and turn the non-array string constant into an array [loplugin:stringconstant]}}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
@@ -3482,7 +3482,7 @@ void ScInterpreter::ScBahtText()
|
|||||||
lclAppendBlock( aBlock, nBlock );
|
lclAppendBlock( aBlock, nBlock );
|
||||||
// add leading "million", if there will come more blocks
|
// add leading "million", if there will come more blocks
|
||||||
if( fBaht > 0.0 )
|
if( fBaht > 0.0 )
|
||||||
aBlock.insert( 0, OString(UTF8_TH_1E6 ) );
|
aBlock.insert( 0, UTF8_TH_1E6 );
|
||||||
|
|
||||||
aText.insert(0, aBlock.makeStringAndClear());
|
aText.insert(0, aBlock.makeStringAndClear());
|
||||||
}
|
}
|
||||||
@@ -3502,7 +3502,7 @@ void ScInterpreter::ScBahtText()
|
|||||||
|
|
||||||
// add the minus sign
|
// add the minus sign
|
||||||
if( bMinus )
|
if( bMinus )
|
||||||
aText.insert( 0, OString( UTF8_TH_MINUS ) );
|
aText.insert( 0, UTF8_TH_MINUS );
|
||||||
|
|
||||||
PushString( OStringToOUString(aText.makeStringAndClear(), RTL_TEXTENCODING_UTF8) );
|
PushString( OStringToOUString(aText.makeStringAndClear(), RTL_TEXTENCODING_UTF8) );
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@ $(eval $(call gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
|
|||||||
compilerplugins/clang/test/oslendian-2 \
|
compilerplugins/clang/test/oslendian-2 \
|
||||||
compilerplugins/clang/test/oslendian-3 \
|
compilerplugins/clang/test/oslendian-3 \
|
||||||
compilerplugins/clang/test/salbool \
|
compilerplugins/clang/test/salbool \
|
||||||
|
compilerplugins/clang/test/stringconstant \
|
||||||
compilerplugins/clang/test/unnecessaryoverride-dtor \
|
compilerplugins/clang/test/unnecessaryoverride-dtor \
|
||||||
compilerplugins/clang/test/vclwidgets \
|
compilerplugins/clang/test/vclwidgets \
|
||||||
))
|
))
|
||||||
|
Reference in New Issue
Block a user