summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2023-10-13 08:44:49 +0200
committerStephan Bergmann <sbergman@redhat.com>2023-10-15 21:15:49 +0200
commitb4844c310bd9897fef59e8a4da0513100ea86096 (patch)
tree379a43d012894ff06d29d79c7d4d8009b7853501 /compilerplugins
parent8797ba5e5d63151837ba443e1aea9d0997b6b7ab (diff)
Repurpose loplugin:stringstatic for O[U]String vars that can be constexpr
...now that warning about O[U]String vars that could be O[U]StringLiteral is no longer useful Change-Id: I389e72038171f28482049b41f6224257dd11f452 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157992 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/stringstatic.cxx142
-rw-r--r--compilerplugins/clang/test/stringstatic.cxx21
-rw-r--r--compilerplugins/clang/test/stringstatic.hxx23
3 files changed, 16 insertions, 170 deletions
diff --git a/compilerplugins/clang/stringstatic.cxx b/compilerplugins/clang/stringstatic.cxx
index 5ad225b68d80..a7439608d556 100644
--- a/compilerplugins/clang/stringstatic.cxx
+++ b/compilerplugins/clang/stringstatic.cxx
@@ -12,16 +12,7 @@
#include "check.hxx"
#include "plugin.hxx"
-#include "config_clang.h"
-
-#include <unordered_set>
-
-/** Look for static O*String and O*String[], they can be more efficiently declared as:
-
- static constexpr OUStringLiteral our_aLBEntryMap[] = {u" ", u", "};
- static constexpr OUStringLiteral sName(u"name");
-
- which is more efficient at startup time.
+/** Look for static O*String and O*String[] which can be constepxr.
*/
namespace {
@@ -34,17 +25,7 @@ public:
FilteringPlugin(rData) {}
void run() override;
- bool preRun() override;
- void postRun() override;
bool VisitVarDecl(VarDecl const*);
- bool VisitReturnStmt(ReturnStmt const*);
- bool VisitDeclRefExpr(DeclRefExpr const*);
- bool VisitMemberExpr(MemberExpr const*);
- bool VisitUnaryOperator(UnaryOperator const*);
-
-private:
- std::unordered_set<VarDecl const *> potentialVars;
- std::unordered_set<VarDecl const *> excludeVars;
};
void StringStatic::run()
@@ -54,51 +35,17 @@ void StringStatic::run()
postRun();
}
-bool StringStatic::preRun()
-{
- StringRef fn(handler.getMainFileName());
- // passing around pointers to global OUString
- if (loplugin::hasPathnamePrefix(fn, SRCDIR "/filter/source/svg/"))
- return false;
- // call replaceAll on a 'const OUString", for which there is no OUStringLiteral equivalent
- if (loplugin::hasPathnamePrefix(fn, SRCDIR "/i18npool/qa/cppunit/test_breakiterator.cxx"))
- return false;
- if (loplugin::hasPathnamePrefix(fn, SRCDIR "/sd/qa/unit/export-tests-ooxml2.cxx"))
- return false;
- return true;
-}
-
-void StringStatic::postRun()
-{
- for (auto const & pVarDecl : excludeVars) {
- potentialVars.erase(pVarDecl);
- }
- for (auto const & varDecl : potentialVars) {
- report(DiagnosticsEngine::Warning,
- "rather declare this using OUStringLiteral/OStringLiteral/char[]",
- varDecl->getLocation())
- << varDecl->getSourceRange();
- }
-}
-
bool StringStatic::VisitVarDecl(VarDecl const* varDecl)
{
if (ignoreLocation(varDecl))
return true;
QualType qt = varDecl->getType();
if (!varDecl->isThisDeclarationADefinition()
- || !qt.isConstQualified())
+ || !qt.isConstQualified() || varDecl->isConstexpr())
return true;
if (varDecl->hasGlobalStorage())
{
- if (varDecl->hasGlobalStorage() && !varDecl->isStaticLocal()) {
- //TODO: For a non-public static member variable from an included file, we could still
- // examine it further if all its uses must be seen in that included file:
- if (!compiler.getSourceManager().isInMainFile(varDecl->getLocation())) {
- return true;
- }
- }
if (qt->isArrayType())
qt = qt->getAsArrayTypeUnsafe()->getElementType();
@@ -154,91 +101,14 @@ bool StringStatic::VisitVarDecl(VarDecl const* varDecl)
return true;
}
}
- potentialVars.insert(varDecl);
+ report(DiagnosticsEngine::Warning,
+ "rather declare this as constexpr",
+ varDecl->getLocation())
+ << varDecl->getSourceRange();
return true;
}
-bool StringStatic::VisitReturnStmt(ReturnStmt const * returnStmt)
-{
- if (ignoreLocation(returnStmt)) {
- return true;
- }
- if (!returnStmt->getRetValue()) {
- return true;
- }
- DeclRefExpr const * declRef = dyn_cast<DeclRefExpr>(returnStmt->getRetValue());
- if (!declRef) {
- return true;
- }
- VarDecl const * varDecl = dyn_cast<VarDecl>(declRef->getDecl());
- if (varDecl) {
- excludeVars.insert(varDecl);
- }
- return true;
-}
-
-bool StringStatic::VisitDeclRefExpr(DeclRefExpr const * declRef)
-{
- if (ignoreLocation(declRef))
- return true;
- VarDecl const * varDecl = dyn_cast<VarDecl>(declRef->getDecl());
- if (!varDecl)
- return true;
- if (potentialVars.count(varDecl) == 0)
- return true;
- // ignore globals that are used in CPPUNIT_ASSERT expressions, otherwise we can end up
- // trying to compare an OUStringLiteral and an OUString, and CPPUNIT can't handle that
- auto loc = declRef->getBeginLoc();
- if (compiler.getSourceManager().isMacroArgExpansion(loc))
- {
- StringRef name { Lexer::getImmediateMacroName(loc, compiler.getSourceManager(), compiler.getLangOpts()) };
- if (name.startswith("CPPUNIT_ASSERT"))
- excludeVars.insert(varDecl);
- }
- return true;
-}
-
-bool StringStatic::VisitMemberExpr(MemberExpr const * expr)
-{
- if (ignoreLocation(expr))
- return true;
- auto const declRef = dyn_cast<DeclRefExpr>(expr->getBase());
- if (declRef == nullptr) {
- return true;
- }
- VarDecl const * varDecl = dyn_cast<VarDecl>(declRef->getDecl());
- if (!varDecl)
- return true;
- if (potentialVars.count(varDecl) == 0)
- return true;
- auto const id = expr->getMemberDecl()->getIdentifier();
- if (id == nullptr || id->getName() != "pData") {
- return true;
- }
- excludeVars.insert(varDecl);
- return true;
-}
-
-bool StringStatic::VisitUnaryOperator(UnaryOperator const * expr)
-{
- if (ignoreLocation(expr))
- return true;
- if (expr->getOpcode() != UO_AddrOf)
- return true;
- if (this->ignoreLocation(expr))
- return true;
- auto const dre = dyn_cast<DeclRefExpr>(
- expr->getSubExpr()->IgnoreParenImpCasts());
- if (!dre)
- return true;
- auto const vd = dyn_cast<VarDecl>(dre->getDecl());
- if (!vd)
- return true;
- excludeVars.insert(vd->getCanonicalDecl());
- return true;
-}
-
loplugin::Plugin::Registration<StringStatic> stringstatic("stringstatic");
} // namespace
diff --git a/compilerplugins/clang/test/stringstatic.cxx b/compilerplugins/clang/test/stringstatic.cxx
index bfe92b69f598..7e2089a17da7 100644
--- a/compilerplugins/clang/test/stringstatic.cxx
+++ b/compilerplugins/clang/test/stringstatic.cxx
@@ -9,22 +9,21 @@
#include <rtl/ustring.hxx>
-#include "stringstatic.hxx"
-
-// expected-error@+1 {{rather declare this using OUStringLiteral/OStringLiteral/char[] [loplugin:stringstatic]}}
+// expected-error@+1 {{rather declare this as constexpr [loplugin:stringstatic]}}
static const OUString TEST1 = "xxx";
-
-void f(rtl_uString const*);
-void f(const OUString&);
+static constexpr OUString TEST2 = u"xxx"_ustr;
void test2()
{
- // expected-error@+1 {{rather declare this using OUStringLiteral/OStringLiteral/char[] [loplugin:stringstatic]}}
+ (void)TEST2;
+ // expected-error@+1 {{rather declare this as constexpr [loplugin:stringstatic]}}
static const OUString XXX = "xxx";
- // expected-error@+1 {{rather declare this using OUStringLiteral/OStringLiteral/char[] [loplugin:stringstatic]}}
- static const OUString XXX2 = "xxx";
+ static constexpr OUString XXX2 = u"xxx"_ustr;
(void)XXX;
(void)XXX2;
- static const OUString DATA = "xxx";
- f(DATA.pData);
+ // expected-error@+1 {{rather declare this as constexpr [loplugin:stringstatic]}}
+ static const OUString A1[1] = { u"xxx"_ustr };
+ static constexpr OUString A2[1] = { u"xxx"_ustr };
+ (void)A1;
+ (void)A2;
}
diff --git a/compilerplugins/clang/test/stringstatic.hxx b/compilerplugins/clang/test/stringstatic.hxx
deleted file mode 100644
index ec82a8bf5deb..000000000000
--- a/compilerplugins/clang/test/stringstatic.hxx
+++ /dev/null
@@ -1,23 +0,0 @@
-/* -*- 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 "rtl/ustring.hxx"
-
-OUString const INCLUDED = "xxx";
-
-inline void f()
-{
- // expected-error@+1 {{rather declare this using OUStringLiteral/OStringLiteral/char[] [loplugin:stringstatic]}}
- static OUString const XXX = "xxx";
- (void)XXX;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */