diff --git a/compilerplugins/clang/bufferadd.cxx b/compilerplugins/clang/bufferadd.cxx index 5327384c4ec3..9d49f7fdc40b 100644 --- a/compilerplugins/clang/bufferadd.cxx +++ b/compilerplugins/clang/bufferadd.cxx @@ -83,6 +83,7 @@ public: bool VisitStmt(Stmt const*); bool VisitCallExpr(CallExpr const*); + bool VisitCXXMemberCallExpr(CXXMemberCallExpr const*); bool VisitCXXConstructExpr(CXXConstructExpr const*); bool VisitUnaryOperator(UnaryOperator const*); @@ -143,6 +144,35 @@ bool BufferAdd::VisitCallExpr(CallExpr const* callExpr) return true; } +bool BufferAdd::VisitCXXMemberCallExpr(CXXMemberCallExpr const* expr) +{ + if (ignoreLocation(expr)) + { + return true; + } + auto const e = dyn_cast(expr->getImplicitObjectArgument()->IgnoreParenImpCasts()); + if (e == nullptr) + { + return true; + } + auto const d = dyn_cast(e->getDecl()); + if (d == nullptr) + { + return true; + } + auto const tc = loplugin::TypeCheck(d->getType()); + if (!(tc.Class("OStringBuffer").Namespace("rtl").GlobalNamespace() + || tc.Class("OUStringBuffer").Namespace("rtl").GlobalNamespace())) + { + return true; + } + if (!isMethodOkToMerge(expr)) + { + badMap.insert(d); + } + return true; +} + bool BufferAdd::VisitCXXConstructExpr(CXXConstructExpr const* callExpr) { if (ignoreLocation(callExpr)) diff --git a/compilerplugins/clang/test/bufferadd.cxx b/compilerplugins/clang/test/bufferadd.cxx index 464214461083..b7712b31f464 100644 --- a/compilerplugins/clang/test/bufferadd.cxx +++ b/compilerplugins/clang/test/bufferadd.cxx @@ -117,6 +117,16 @@ void f7() OStringBuffer noelf7("xxx"); noelf7 = "xxx" + noelf7 + "xxx"; } +char16_t rnd(); +void f8(sal_Int32 n) +{ + OUStringBuffer buf; + auto p = buf.appendUninitialized(n); + for (sal_Int32 i = 0; i != n; ++i) + { + *p++ = rnd(); + } +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */