diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2021-05-14 08:30:01 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2021-05-14 09:51:04 +0200 |
commit | cbacdfd886e3556f7b02bc5165f76d4af97b6dfe (patch) | |
tree | edf171fd3f4b2a73d99f7fa179cd0be27bd5612f /compilerplugins | |
parent | b1099568ffe9ad199c3bf8f279bbac4d7ba445bb (diff) |
Improve loplugin:stringview diagnostic output
Say what the O[U]String is constructed from (to make it easier to decide on an
optimal rephrase of the whole surrounding expression), and find more cases that
could use O[U]StringChar.
Change-Id: I64a3851544498c26ca3f46f5df7f593d2fdcb0ee
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115579
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/stringview.cxx | 24 | ||||
-rw-r--r-- | compilerplugins/clang/test/stringview.cxx | 36 |
2 files changed, 40 insertions, 20 deletions
diff --git a/compilerplugins/clang/stringview.cxx b/compilerplugins/clang/stringview.cxx index 95d7d6368572..cc717079732f 100644 --- a/compilerplugins/clang/stringview.cxx +++ b/compilerplugins/clang/stringview.cxx @@ -165,6 +165,7 @@ void StringView::handleSubExprThatCouldBeView(Expr const* subExpr) void StringView::handleCXXConstructExpr(CXXConstructExpr const* expr) { + QualType argType; bool charArg = false; auto const d = expr->getConstructor(); switch (d->getNumParams()) @@ -176,6 +177,7 @@ void StringView::handleCXXConstructExpr(CXXConstructExpr const* expr) auto const t = d->getParamDecl(0)->getType(); if (t->isAnyCharacterType()) { + argType = expr->getArg(0)->IgnoreImplicit()->getType(); charArg = true; break; } @@ -194,6 +196,7 @@ void StringView::handleCXXConstructExpr(CXXConstructExpr const* expr) || tc.RvalueReference().Struct("OUStringNumber").Namespace("rtl").GlobalNamespace() || tc.ClassOrStruct("basic_string_view").StdNamespace()) { + argType = expr->getArg(0)->IgnoreImplicit()->getType(); break; } return; @@ -207,6 +210,19 @@ void StringView::handleCXXConstructExpr(CXXConstructExpr const* expr) if (t->isIntegralType(compiler.getASTContext()) && !(t->isBooleanType() || t->isAnyCharacterType())) { + auto const arg = expr->getArg(1); + if (!arg->isValueDependent()) + { + if (auto const val + = compat::getIntegerConstantExpr(arg, compiler.getASTContext())) + { + if (val->getExtValue() == 1) + { + charArg = true; + } + } + } + argType = expr->getArg(0)->IgnoreImplicit()->getType(); break; } } @@ -216,6 +232,7 @@ void StringView::handleCXXConstructExpr(CXXConstructExpr const* expr) .Namespace("rtl") .GlobalNamespace()) { + argType = expr->getArg(0)->IgnoreImplicit()->getType(); break; } return; @@ -224,10 +241,11 @@ void StringView::handleCXXConstructExpr(CXXConstructExpr const* expr) return; } report(DiagnosticsEngine::Warning, - "instead of an %0, pass a '%select{std::string_view|std::u16string_view}1'" - "%select{| (or an '%select{rtl::OStringChar|rtl::OUStringChar}1')}2", + "instead of an %0%select{| constructed from a %2}1, pass a" + " '%select{std::string_view|std::u16string_view}3'" + "%select{| (or an '%select{rtl::OStringChar|rtl::OUStringChar}3')}4", expr->getExprLoc()) - << expr->getType() + << expr->getType() << (argType.isNull() ? 0 : 1) << argType << (loplugin::TypeCheck(expr->getType()).Class("OString").Namespace("rtl").GlobalNamespace() ? 0 : 1) diff --git a/compilerplugins/clang/test/stringview.cxx b/compilerplugins/clang/test/stringview.cxx index 142bba799008..edd2305f2c69 100644 --- a/compilerplugins/clang/test/stringview.cxx +++ b/compilerplugins/clang/test/stringview.cxx @@ -102,41 +102,43 @@ void f5(char const* s1, sal_Int32 n1, char16_t const* s2, sal_Int32 n2) { // expected-error@+1 {{instead of an 'rtl::OString', pass a 'std::string_view' [loplugin:stringview]}} call_view(OString()); - // expected-error@+1 {{instead of an 'rtl::OString', pass a 'std::string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OString' constructed from a 'const char [4]', pass a 'std::string_view' [loplugin:stringview]}} call_view(OString("foo")); - // expected-error@+1 {{instead of an 'rtl::OString', pass a 'std::string_view' (or an 'rtl::OStringChar') [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OString' constructed from a 'const char', pass a 'std::string_view' (or an 'rtl::OStringChar') [loplugin:stringview]}} call_view(OString(*s1)); - // expected-error@+1 {{instead of an 'rtl::OString', pass a 'std::string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OString' constructed from a 'const char *', pass a 'std::string_view' [loplugin:stringview]}} call_view(OString(s1)); - // expected-error@+1 {{instead of an 'rtl::OString', pass a 'std::string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OString' constructed from a 'const char *', pass a 'std::string_view' [loplugin:stringview]}} call_view(OString(s1, n1)); constexpr OStringLiteral l1("foo"); - // expected-error@+1 {{instead of an 'rtl::OString', pass a 'std::string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OString' constructed from a 'const rtl::OStringLiteral<4>', pass a 'std::string_view' [loplugin:stringview]}} call_view(OString(l1)); - // expected-error@+1 {{instead of an 'rtl::OString', pass a 'std::string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OString' constructed from a 'std::string_view' (aka 'basic_string_view<char>'), pass a 'std::string_view' [loplugin:stringview]}} call_view(OString(std::string_view("foo"))); - // expected-error@+1 {{instead of an 'rtl::OString', pass a 'std::string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OString' constructed from a 'OStringNumber<int>', pass a 'std::string_view' [loplugin:stringview]}} call_view(OString(OString::number(0))); // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' [loplugin:stringview]}} call_view(OUString()); - // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'const char [4]', pass a 'std::u16string_view' [loplugin:stringview]}} call_view(OUString("foo")); - // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'const char16_t [4]', pass a 'std::u16string_view' [loplugin:stringview]}} call_view(OUString(u"foo")); - // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' (or an 'rtl::OUStringChar') [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'const char', pass a 'std::u16string_view' (or an 'rtl::OUStringChar') [loplugin:stringview]}} call_view(OUString(*s1)); - // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' (or an 'rtl::OUStringChar') [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'const char16_t', pass a 'std::u16string_view' (or an 'rtl::OUStringChar') [loplugin:stringview]}} call_view(OUString(*s2)); - // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'const char16_t *', pass a 'std::u16string_view' [loplugin:stringview]}} call_view(OUString(s2)); - // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'const char16_t *', pass a 'std::u16string_view' [loplugin:stringview]}} call_view(OUString(s2, n2)); + // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'const char16_t *', pass a 'std::u16string_view' (or an 'rtl::OUStringChar') [loplugin:stringview]}} + call_view(OUString(s2, 1)); constexpr OUStringLiteral l2(u"foo"); - // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'const rtl::OUStringLiteral<4>', pass a 'std::u16string_view' [loplugin:stringview]}} call_view(OUString(l2)); - // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'std::u16string_view' (aka 'basic_string_view<char16_t>'), pass a 'std::u16string_view' [loplugin:stringview]}} call_view(OUString(std::u16string_view(u"foo"))); - // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'OUStringNumber<int>', pass a 'std::u16string_view' [loplugin:stringview]}} call_view(OUString(OUString::number(0))); } @@ -148,7 +150,7 @@ void f5(OUString s) buf = s.copy(5); // expected-error@+1 {{rather than copy, pass with a view using subView() [loplugin:stringview]}} buf.append(s.copy(12)); - // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error@+1 {{instead of an 'rtl::OUString' constructed from a 'std::u16string_view' (aka 'basic_string_view<char16_t>'), pass a 'std::u16string_view' [loplugin:stringview]}} buf.append(OUString(std::u16string_view(u"foo"))); } |