summaryrefslogtreecommitdiff
path: root/compilerplugins/clang
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2021-07-09 13:04:19 +0200
committerStephan Bergmann <sbergman@redhat.com>2021-07-09 15:07:05 +0200
commitf020784e14a55c82418e4f231855040177ac9f82 (patch)
treea2d5c1d2b5778e564b9ee529de0453c73907ce70 /compilerplugins/clang
parentac7bba3cc1e13824732f5ab69af602848e4ba227 (diff)
Make loplugin:stringadd slightly more aggressive
...by assuming that all const member functions are side-effect free. (This presumably means that some of the special cases in StringAdd::isSideEffectFree are obsoleted by this more general case, but any such removal is postponed to later clean-up.) (Came across this when idly wondering why 8b7f948d9d79393bc6c1b11d239706666fd5d7de "sc, VmlFormControlExporter: avoid OStringBuffer style" had not been found by the plugin before.) Change-Id: I6bca10df53885b14a590543aabd61f23b3748572 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118675 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins/clang')
-rw-r--r--compilerplugins/clang/stringadd.cxx30
-rw-r--r--compilerplugins/clang/test/stringadd.cxx24
2 files changed, 54 insertions, 0 deletions
diff --git a/compilerplugins/clang/stringadd.cxx b/compilerplugins/clang/stringadd.cxx
index c25992928f1e..394139dbb354 100644
--- a/compilerplugins/clang/stringadd.cxx
+++ b/compilerplugins/clang/stringadd.cxx
@@ -378,6 +378,36 @@ bool StringAdd::isSideEffectFree(Expr const* expr)
}
}
}
+ // Aggressively assume that calls to const member functions are side effect free (if
+ // all of the call's sub-expressions are):
+ if (calleeMethodDecl->isConst())
+ {
+ auto sef = true;
+ // Other options besides CXXMemberCallExpr are e.g. CXXOperatorCallExpr which
+ // does not have such a target expression:
+ if (auto const mce = dyn_cast<CXXMemberCallExpr>(callExpr))
+ {
+ if (!isSideEffectFree(mce->getImplicitObjectArgument()))
+ {
+ sef = false;
+ }
+ }
+ if (sef)
+ {
+ for (unsigned i = 0; i != callExpr->getNumArgs(); ++i)
+ {
+ if (!isSideEffectFree(callExpr->getArg(i)))
+ {
+ sef = false;
+ break;
+ }
+ }
+ }
+ if (sef)
+ {
+ return true;
+ }
+ }
}
if (auto calleeFunctionDecl = dyn_cast_or_null<FunctionDecl>(callExpr->getCalleeDecl()))
if (calleeFunctionDecl && calleeFunctionDecl->getIdentifier())
diff --git a/compilerplugins/clang/test/stringadd.cxx b/compilerplugins/clang/test/stringadd.cxx
index fb805ce519b9..a20b64698433 100644
--- a/compilerplugins/clang/test/stringadd.cxx
+++ b/compilerplugins/clang/test/stringadd.cxx
@@ -235,4 +235,28 @@ void f2(char ch)
s = s + OString(ch);
}
}
+
+namespace test10
+{
+struct C
+{
+ OString constStringFunction(int) const;
+ OString nonConstStringFunction();
+ int constIntFunction() const;
+ int nonConstIntFunction();
+};
+
+C getC();
+
+void f1(C c)
+{
+ OString s;
+ // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}}
+ s += c.constStringFunction(c.constIntFunction());
+ s += c.constStringFunction(c.nonConstIntFunction());
+ s += c.nonConstStringFunction();
+ s += getC().constStringFunction(c.constIntFunction());
+}
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */