diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2021-07-09 13:04:19 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2021-07-09 15:07:05 +0200 |
commit | f020784e14a55c82418e4f231855040177ac9f82 (patch) | |
tree | a2d5c1d2b5778e564b9ee529de0453c73907ce70 /compilerplugins/clang | |
parent | ac7bba3cc1e13824732f5ab69af602848e4ba227 (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.cxx | 30 | ||||
-rw-r--r-- | compilerplugins/clang/test/stringadd.cxx | 24 |
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: */ |