diff options
Diffstat (limited to 'compilerplugins/clang/test')
56 files changed, 1913 insertions, 210 deletions
diff --git a/compilerplugins/clang/test/casttovoid.cxx b/compilerplugins/clang/test/casttovoid.cxx index c3b5eee17c96..3d8c22b49c7e 100644 --- a/compilerplugins/clang/test/casttovoid.cxx +++ b/compilerplugins/clang/test/casttovoid.cxx @@ -115,6 +115,8 @@ int main() { int n8 = 0; ASSERT(USE(USE(n8 == 0))); (void) n8; + int volatile n9 = 0; + (void) n9; return n1 // expected-note 8 {{first consumption is here [loplugin:casttovoid]}} + n2 // expected-note {{first consumption is here [loplugin:casttovoid]}} + n3; diff --git a/compilerplugins/clang/test/weakobject.cxx b/compilerplugins/clang/test/constexprliteral.cxx index 7c7da55664d2..f33ab2ff7a74 100644 --- a/compilerplugins/clang/test/weakobject.cxx +++ b/compilerplugins/clang/test/constexprliteral.cxx @@ -7,25 +7,18 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "config_clang.h" +#include <sal/config.h> +#include <rtl/string.hxx> +#include <rtl/ustring.hxx> -namespace cppu +namespace test1 { -class OWeakObject +void f() { -}; + // expected-error@+1 {{OUStringLiteral should be declared constexpr [loplugin:constexprliteral]}} + const OUStringLiteral foo = u"foo"; + (void)foo; +} } - -class Foo1 : public cppu::OWeakObject -{ -}; -class Foo2 : public cppu::OWeakObject -{ -}; - -// expected-error@+1 {{more than one copy of cppu::OWeakObject inherited [loplugin:weakobject]}} -class Foo3 : public Foo1, public Foo2 -{ -}; /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/stringstatic.hxx b/compilerplugins/clang/test/constmove.cxx index ec82a8bf5deb..f6d2ed3ac9bf 100644 --- a/compilerplugins/clang/test/stringstatic.hxx +++ b/compilerplugins/clang/test/constmove.cxx @@ -7,17 +7,19 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "sal/config.h" +#include <utility> -#include "rtl/ustring.hxx" - -OUString const INCLUDED = "xxx"; +struct S +{ +}; -inline void f() +void f(S const& s1, S s2) { - // expected-error@+1 {{rather declare this using OUStringLiteral/OStringLiteral/char[] [loplugin:stringstatic]}} - static OUString const XXX = "xxx"; - (void)XXX; + // expected-error-re@+1 {{suspicious 'std::move' from 'const S' to const-qualified '{{.+}}' (aka 'const S') [loplugin:constmove]}} + S v1(std::move(s1)); + (void)v1; + S v2(std::move(s2)); + (void)v2; } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/cow_wrapper.cxx b/compilerplugins/clang/test/cow_wrapper.cxx index 705a4052ef66..5c95f87f04d9 100644 --- a/compilerplugins/clang/test/cow_wrapper.cxx +++ b/compilerplugins/clang/test/cow_wrapper.cxx @@ -9,6 +9,7 @@ #include "config_clang.h" #include "o3tl/cow_wrapper.hxx" +#include <utility> struct ImplBitmapPalette { @@ -27,6 +28,16 @@ struct BitmapPalette // no error expected mpImpl->foo(); } + void foo3() + { + // expected-error@+1 {{calling const method on o3tl::cow_wrapper impl class via non-const pointer, rather use std::as_const to prevent triggering an unnecessary copy [loplugin:cow_wrapper]}} + (*mpImpl).foo(); + } + void foo4() + { + // expected-error@+1 {{calling const method on o3tl::cow_wrapper impl class via non-const pointer, rather use std::as_const to prevent triggering an unnecessary copy [loplugin:cow_wrapper]}} + std::as_const(*mpImpl).foo(); + } o3tl::cow_wrapper<ImplBitmapPalette> mpImpl; }; diff --git a/compilerplugins/clang/test/cppunitassertequals.cxx b/compilerplugins/clang/test/cppunitassertequals.cxx index 48bea83f6088..401105465635 100644 --- a/compilerplugins/clang/test/cppunitassertequals.cxx +++ b/compilerplugins/clang/test/cppunitassertequals.cxx @@ -9,18 +9,23 @@ #include "sal/config.h" +#include <cstddef> + #include <cppunit/TestAssert.h> #include <cppunit/TestFixture.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/plugin/TestPlugIn.h> -#include "cppunitassertequals.hxx" +#include "rtl/ustring.hxx" #define TEST1 CPPUNIT_ASSERT(b1 == b2) #define TEST2(x) x +struct T { bool operator ==(T); }; + void test( - bool b1, bool b2, OUString const & s1, OUString const & s2, T t, void * p, std::nullptr_t n) + bool b1, bool b2, OUString const & s1, OUString const & s2, T t, void * p, std::nullptr_t n, + double d, int i) { CppUnit::Asserter::failIf(b1,""); CPPUNIT_ASSERT(b1 && b2); // expected-error {{rather split into two CPPUNIT_ASSERT [loplugin:cppunitassertequals]}} @@ -36,12 +41,12 @@ void test( CPPUNIT_ASSERT(!(b1 == b2)); CPPUNIT_ASSERT(!!(b1 == b2)); // expected-error {{rather call CPPUNIT_ASSERT_EQUAL when comparing 'bool' and 'bool' (or rewrite as an explicit operator == call when the operator itself is the topic) [loplugin:cppunitassertequals]}} CPPUNIT_ASSERT_MESSAGE("", b1 == b2); // expected-error {{rather call CPPUNIT_ASSERT_EQUAL_MESSAGE when comparing 'bool' and 'bool' (or rewrite as an explicit operator == call when the operator itself is the topic) [loplugin:cppunitassertequals]}} - CPPUNIT_ASSERT(s1 == s2); // expected-error {{rather call CPPUNIT_ASSERT_EQUAL when comparing 'const rtl::OUString' and 'const rtl::OUString' (or rewrite as an explicit operator == call when the operator itself is the topic) [loplugin:cppunitassertequals]}} + CPPUNIT_ASSERT(s1 == s2); // expected-error-re {{rather call CPPUNIT_ASSERT_EQUAL when comparing 'const {{(rtl::)?}}OUString' and 'const {{(rtl::)?}}OUString' (or rewrite as an explicit operator == call when the operator itself is the topic) [loplugin:cppunitassertequals]}} CPPUNIT_ASSERT(s1 != s2); - CPPUNIT_ASSERT((s1 == s2)); // expected-error {{rather call CPPUNIT_ASSERT_EQUAL when comparing 'const rtl::OUString' and 'const rtl::OUString' (or rewrite as an explicit operator == call when the operator itself is the topic) [loplugin:cppunitassertequals]}} - CPPUNIT_ASSERT(!(s1 != s2)); // expected-error {{rather call CPPUNIT_ASSERT_EQUAL when comparing 'const rtl::OUString' and 'const rtl::OUString' (or rewrite as an explicit operator != call when the operator itself is the topic) [loplugin:cppunitassertequals]}} + CPPUNIT_ASSERT((s1 == s2)); // expected-error-re {{rather call CPPUNIT_ASSERT_EQUAL when comparing 'const {{(rtl::)?}}OUString' and 'const {{(rtl::)?}}OUString' (or rewrite as an explicit operator == call when the operator itself is the topic) [loplugin:cppunitassertequals]}} + CPPUNIT_ASSERT(!(s1 != s2)); // expected-error-re {{rather call CPPUNIT_ASSERT_EQUAL when comparing 'const {{(rtl::)?}}OUString' and 'const {{(rtl::)?}}OUString' (or rewrite as an explicit operator != call when the operator itself is the topic) [loplugin:cppunitassertequals]}} CPPUNIT_ASSERT(!(s1 == s2)); - CPPUNIT_ASSERT(!!(s1 == s2)); // expected-error {{rather call CPPUNIT_ASSERT_EQUAL when comparing 'const rtl::OUString' and 'const rtl::OUString' (or rewrite as an explicit operator == call when the operator itself is the topic) [loplugin:cppunitassertequals]}} + CPPUNIT_ASSERT(!!(s1 == s2)); // expected-error-re {{rather call CPPUNIT_ASSERT_EQUAL when comparing 'const {{(rtl::)?}}OUString' and 'const {{(rtl::)?}}OUString' (or rewrite as an explicit operator == call when the operator itself is the topic) [loplugin:cppunitassertequals]}} TEST1; // expected-error {{rather call CPPUNIT_ASSERT_EQUAL when comparing 'bool' and 'bool' (or rewrite as an explicit operator == call when the operator itself is the topic) [loplugin:cppunitassertequals]}} TEST2(CPPUNIT_ASSERT(b1 == b2)); // expected-error {{rather call CPPUNIT_ASSERT_EQUAL when comparing 'bool' and 'bool' (or rewrite as an explicit operator == call when the operator itself is the topic) [loplugin:cppunitassertequals]}} TEST2(TEST1); // expected-error {{rather call CPPUNIT_ASSERT_EQUAL when comparing 'bool' and 'bool' (or rewrite as an explicit operator == call when the operator itself is the topic) [loplugin:cppunitassertequals]}} @@ -70,6 +75,19 @@ void test( CPPUNIT_ASSERT_EQUAL_MESSAGE("foo", s1, OUString("xxx")); // expected-error {{CPPUNIT_ASSERT_EQUALS parameters look switched, expected value should be first param [loplugin:cppunitassertequals]}} CPPUNIT_ASSERT_EQUAL(OUString("xxx"), s1); CPPUNIT_ASSERT_EQUAL_MESSAGE("foo", OUString("xxx"), s1); + + CPPUNIT_ASSERT_EQUAL(d, 1.0); // expected-error {{CPPUNIT_ASSERT_EQUALS parameters look switched, expected value should be first param [loplugin:cppunitassertequals]}} + CPPUNIT_ASSERT_EQUAL(1.0, d); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(d, 1.0, 0.1); // expected-error {{CPPUNIT_ASSERT_DOUBLES_EQUALS parameters look switched, expected value should be first param [loplugin:cppunitassertequals]}} + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("foo", d, 1.0, 0.1); // expected-error {{CPPUNIT_ASSERT_DOUBLES_EQUALS parameters look switched, expected value should be first param [loplugin:cppunitassertequals]}} + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, d, 0.1); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("foo", 1.0, d, 0.1); + + CPPUNIT_ASSERT_LESS(i, 1); // expected-error {{CPPUNIT_ASSERT_LESS parameters look switched, expected value should be first param [loplugin:cppunitassertequals]}} + CPPUNIT_ASSERT_LESSEQUAL(i, 1); // expected-error {{CPPUNIT_ASSERT_LESSEQUAL parameters look switched, expected value should be first param [loplugin:cppunitassertequals]}} + CPPUNIT_ASSERT_GREATER(i, 1); // expected-error {{CPPUNIT_ASSERT_GREATER parameters look switched, expected value should be first param [loplugin:cppunitassertequals]}} + CPPUNIT_ASSERT_GREATEREQUAL(i, 1); // expected-error {{CPPUNIT_ASSERT_GREATEREQUAL parameters look switched, expected value should be first param [loplugin:cppunitassertequals]}} } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/crosscast.cxx b/compilerplugins/clang/test/crosscast.cxx new file mode 100644 index 000000000000..113557337113 --- /dev/null +++ b/compilerplugins/clang/test/crosscast.cxx @@ -0,0 +1,96 @@ +/* -*- 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/. + */ + +struct Base +{ + virtual ~Base(); +}; + +struct Derived : Base +{ +}; + +struct Virtual1 : virtual Base +{ +}; + +struct Virtual2 : virtual Base +{ +}; + +struct Virtual2a : Virtual2 +{ +}; + +struct Other +{ + virtual ~Other(); +}; + +struct[[clang::annotate("loplugin:crosscast")]] Ok { virtual ~Ok(); }; + +Base* up(Derived* p) { return dynamic_cast<Base*>(p); } + +Base& up(Derived& p) { return dynamic_cast<Base&>(p); } + +Derived* down(Base* p) { return dynamic_cast<Derived*>(p); } + +Derived& down(Base& p) { return dynamic_cast<Derived&>(p); } + +Base* self(Base* p) { return dynamic_cast<Base*>(p); } + +Base& self(Base& p) { return dynamic_cast<Base&>(p); } + +Virtual1* crossVirtual(Virtual2a* p) { return dynamic_cast<Virtual1*>(p); } + +Virtual1& crossVirtual(Virtual2a& p) { return dynamic_cast<Virtual1&>(p); } + +Base* crossFromOther(Other* p) +{ + // expected-error@+1 {{suspicious dynamic cross cast from 'Other *' to 'Base *' [loplugin:crosscast]}} + return dynamic_cast<Base*>(p); +} + +Base& crossFromOther(Other& p) +{ + // expected-error@+1 {{suspicious dynamic cross cast from 'Other' to 'Base &' [loplugin:crosscast]}} + return dynamic_cast<Base&>(p); +} + +Other* crossToOther(Base* p) +{ + // expected-error@+1 {{suspicious dynamic cross cast from 'Base *' to 'Other *' [loplugin:crosscast]}} + return dynamic_cast<Other*>(p); +} + +Other& crossToOther(Base& p) +{ + // expected-error@+1 {{suspicious dynamic cross cast from 'Base' to 'Other &' [loplugin:crosscast]}} + return dynamic_cast<Other&>(p); +} + +Base* crossFromOk(Ok* p) { return dynamic_cast<Base*>(p); } + +Base& crossFromOk(Ok& p) { return dynamic_cast<Base&>(p); } + +Ok* crossToOk(Base* p) { return dynamic_cast<Ok*>(p); } + +Ok& crossToOk(Base& p) { return dynamic_cast<Ok&>(p); } + +void* mostDerived(Base* p) { return dynamic_cast<void*>(p); } + +template <typename T> T generic1(Base* p) { return dynamic_cast<T>(p); } + +template <typename T> T* generic2(Base* p) { return dynamic_cast<T*>(p); } + +template <typename T> Derived* generic3(T p) { return dynamic_cast<Derived*>(p); } + +template <typename T> Derived* generic4(T* p) { return dynamic_cast<Derived*>(p); } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/dbgunhandledexception.cxx b/compilerplugins/clang/test/dbgunhandledexception.cxx index 4ae15a58e55d..39206d4beaaa 100644 --- a/compilerplugins/clang/test/dbgunhandledexception.cxx +++ b/compilerplugins/clang/test/dbgunhandledexception.cxx @@ -7,7 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <sal/log.hxx> void func1(); diff --git a/compilerplugins/clang/test/elidestringvar.cxx b/compilerplugins/clang/test/elidestringvar.cxx index 0b21644724a4..913bfbc2ae03 100644 --- a/compilerplugins/clang/test/elidestringvar.cxx +++ b/compilerplugins/clang/test/elidestringvar.cxx @@ -15,12 +15,12 @@ template <sal_Unicode C> OUString f(sal_Unicode c, int n) { OUString s0(C); OUString s1(c); - // expected-note@+1 {{literal 'rtl::OUString' variable defined here [loplugin:elidestringvar]}} + // expected-note-re@+1 {{literal '{{(rtl::)?}}OUString' variable defined here [loplugin:elidestringvar]}} OUString s2('a'); - // expected-note@+1 {{literal 'rtl::OUString' variable defined here [loplugin:elidestringvar]}} + // expected-note-re@+1 {{literal '{{(rtl::)?}}OUString' variable defined here [loplugin:elidestringvar]}} OUString s3(u'a'); static constexpr OUStringLiteral s4lit(u"a"); - // expected-note@+1 {{literal 'rtl::OUString' variable defined here [loplugin:elidestringvar]}} + // expected-note-re@+1 {{literal '{{(rtl::)?}}OUString' variable defined here [loplugin:elidestringvar]}} OUString s4 = s4lit; switch (n) { @@ -29,13 +29,13 @@ template <sal_Unicode C> OUString f(sal_Unicode c, int n) case 1: return s1; case 2: - // expected-error@+1 {{replace single use of literal 'rtl::OUString' variable with a literal [loplugin:elidestringvar]}} + // expected-error-re@+1 {{replace single use of literal '{{(rtl::)?}}OUString' variable with a literal [loplugin:elidestringvar]}} return s2; case 3: - // expected-error@+1 {{replace single use of literal 'rtl::OUString' variable with a literal [loplugin:elidestringvar]}} + // expected-error-re@+1 {{replace single use of literal '{{(rtl::)?}}OUString' variable with a literal [loplugin:elidestringvar]}} return s3; default: - // expected-error@+1 {{replace single use of literal 'rtl::OUString' variable with a literal [loplugin:elidestringvar]}} + // expected-error-re@+1 {{replace single use of literal '{{(rtl::)?}}OUString' variable with a literal [loplugin:elidestringvar]}} return s4; } } diff --git a/compilerplugins/clang/test/fakebool.cxx b/compilerplugins/clang/test/fakebool.cxx index 936e970e5e85..144bf4a28a15 100644 --- a/compilerplugins/clang/test/fakebool.cxx +++ b/compilerplugins/clang/test/fakebool.cxx @@ -33,4 +33,18 @@ struct S3 { void f() { S2 s(b_); } }; +namespace { + +struct S4 { + sal_Bool b; +}; + +} + +void f() { + sal_Bool b; + (void) &b; + (void) &S4::b; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/fieldcast.cxx b/compilerplugins/clang/test/fieldcast.cxx new file mode 100644 index 000000000000..6d0437d04e6f --- /dev/null +++ b/compilerplugins/clang/test/fieldcast.cxx @@ -0,0 +1,63 @@ +/* -*- 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/. + */ + +#if defined _WIN32 //TODO, #include <sys/file.h> +// expected-no-diagnostics +#else + +#include <rtl/ustring.hxx> +#include <rtl/ref.hxx> +#include <memory> + +struct Foo +{ + virtual ~Foo(); +}; +struct Bar : public Foo +{ +}; + +class Test1 +{ + // expected-error@+1 {{cast Bar [loplugin:fieldcast]}} + Foo* m_p; + void test1() { (void)dynamic_cast<Bar*>(m_p); } +}; + +class Test2 +{ + // expected-error@+1 {{cast Bar [loplugin:fieldcast]}} + rtl::Reference<Foo> m_p; + void test1() { (void)dynamic_cast<Bar*>(m_p.get()); } +}; + +class Test3 +{ + // no warning expected, casting to a less specific type + rtl::Reference<Bar> m_p; + void test1() { (void)static_cast<Foo*>(m_p.get()); } +}; + +class Test4 +{ + // expected-error@+1 {{cast Bar [loplugin:fieldcast]}} + std::unique_ptr<Foo> m_p; + void test1() { (void)dynamic_cast<Bar*>(m_p.get()); } +}; + +class Test5 +{ + // expected-error@+1 {{cast Bar [loplugin:fieldcast]}} + std::shared_ptr<Foo> m_p; + void test1() { (void)dynamic_cast<Bar*>(m_p.get()); } +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/getstr.cxx b/compilerplugins/clang/test/getstr.cxx index 976d39c25c71..c10939202a9c 100644 --- a/compilerplugins/clang/test/getstr.cxx +++ b/compilerplugins/clang/test/getstr.cxx @@ -24,7 +24,9 @@ // "libstdc++: P1423R3 char8_t remediation (2/4)" for -std=c++2a; TODO: the checks here and the // relevant code in loplugin:getstr should eventually be removed once support for the deleted // operators is widespread): -#if __cplusplus > 201703L && (defined __GLIBCXX__ || defined _MSC_VER) +#if __cplusplus > 201703L \ + && (defined __GLIBCXX__ || defined _MSC_VER \ + || (defined _LIBCPP_VERSION && _LIBCPP_VERSION >= 16000)) #define HAVE_DELETED_OPERATORS true #else #define HAVE_DELETED_OPERATORS false @@ -37,11 +39,11 @@ void f(std::ostream& st, OString const& s1, OStringBuffer const& s2, OString* p1, OStringBuffer* p2, OUString* p3[[maybe_unused]], OUStringBuffer* p4[[maybe_unused]], S* p5, char const* (OString::*pf)() const) { - st << s1.getStr() // expected-error {{directly use object of type 'rtl::OString' in a call of 'operator <<', instead of calling 'getStr' first [loplugin:getstr]}} + st << s1.getStr() // expected-error-re {{directly use object of type '{{(rtl::)?}}OString' in a call of 'operator <<', instead of calling 'getStr' first [loplugin:getstr]}} << s2.getStr() #if !HAVE_DELETED_OPERATORS - << s3.getStr() // expected-error {{suspicious use of 'getStr' on an object of type 'rtl::OUString'; the result is implicitly cast to a void pointer in a call of 'operator <<' [loplugin:getstr]}} - << s4.getStr() // expected-error {{suspicious use of 'getStr' on an object of type 'rtl::OUStringBuffer'; the result is implicitly cast to a void pointer in a call of 'operator <<' [loplugin:getstr]}} + << s3.getStr() // expected-error-re {{suspicious use of 'getStr' on an object of type '{{(rtl::)?}}OUString'; the result is implicitly cast to a void pointer in a call of 'operator <<' [loplugin:getstr]}} + << s4.getStr() // expected-error-re {{suspicious use of 'getStr' on an object of type '{{(rtl::)?}}OUStringBuffer'; the result is implicitly cast to a void pointer in a call of 'operator <<' [loplugin:getstr]}} #endif << s5.getStr() // expected-error {{directly use object of type 'S' (aka 'rtl::OString') in a call of 'operator <<', instead of calling 'getStr' first [loplugin:getstr]}} << p1->getStr() // expected-error {{directly use object of type 'rtl::OString' in a call of 'operator <<', instead of calling 'getStr' first [loplugin:getstr]}} @@ -52,7 +54,7 @@ void f(std::ostream& st, OString const& s1, OStringBuffer const& s2, #endif << p5->getStr() // expected-error {{directly use object of type 'rtl::OString' in a call of 'operator <<', instead of calling 'getStr' first [loplugin:getstr]}} << (s1.*pf)(); - SAL_INFO( // expected-error 1+ {{directly use object of type 'rtl::OString' in a call of 'operator <<', instead of calling 'getStr' first [loplugin:getstr]}} + SAL_INFO( // expected-error-re 1+ {{directly use object of type '{{(rtl::)?}}OString' in a call of 'operator <<', instead of calling 'getStr' first [loplugin:getstr]}} "test", s1.getStr()); } diff --git a/compilerplugins/clang/test/implicitboolconversion.cxx b/compilerplugins/clang/test/implicitboolconversion.cxx index 47c015261fef..122ee363ae68 100644 --- a/compilerplugins/clang/test/implicitboolconversion.cxx +++ b/compilerplugins/clang/test/implicitboolconversion.cxx @@ -9,9 +9,11 @@ #include <sal/config.h> +#include <array> #include <atomic> #include <initializer_list> +#include <com/sun/star/uno/Sequence.hxx> #include <sal/types.h> template <typename T> struct Sequence @@ -35,6 +37,8 @@ template <typename T> struct Wrap2 bool g(); +void h(bool); + void f() { // expected-error@+1 {{implicit conversion (IntegralCast) from 'bool' to 'int' [loplugin:implicitboolconversion]}} @@ -63,13 +67,17 @@ void f() Sequence<Sequence<int>> s4{ { false } }; (void)s4; Wrap1<sal_Bool> w1{ false }; - (void)w1; Sequence<Wrap1<sal_Bool>> s5{ { false } }; (void)s5; Wrap2<sal_Bool> w2{ false }; (void)w2; Sequence<Wrap2<sal_Bool>> s6{ { false } }; (void)s6; + h(w1.element); + css::uno::Sequence<sal_Bool> s7(1); + h(s7[0]); + std::array<sal_Bool, 1> s8; + s8[0] = false; } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/implinheritancehelper.cxx b/compilerplugins/clang/test/implinheritancehelper.cxx new file mode 100644 index 000000000000..4ef976641c7e --- /dev/null +++ b/compilerplugins/clang/test/implinheritancehelper.cxx @@ -0,0 +1,26 @@ +/* -*- 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 <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <cppuhelper/implbase.hxx> +#include "com/sun/star/beans/XProperty.hpp" + +class VCLXDevice : public cppu::WeakImplHelper<css::lang::XUnoTunnel> +{ +}; + +// expected-error@+1 {{can probably use ImplInheritanceHelper here [loplugin:implinheritancehelper]}} +class VCLXCheckBox : public css::beans::XProperty, public VCLXDevice +{ +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/indentation.cxx b/compilerplugins/clang/test/indentation.cxx index 71b8c6f61e5a..1c57c6ceea98 100644 --- a/compilerplugins/clang/test/indentation.cxx +++ b/compilerplugins/clang/test/indentation.cxx @@ -7,8 +7,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "config_clang.h" - int foo(); int foo2(int); @@ -94,12 +92,10 @@ void attr() { foo(); } -#if CLANG_VERSION >= 100000 void attr_bad() { [[maybe_unused]] int i = foo(); // expected-note {{measured against this one [loplugin:indentation]}} foo(); // expected-error {{statement mis-aligned compared to neighbours [loplugin:indentation]}} } -#endif void xxx(); void test5(bool x) diff --git a/compilerplugins/clang/test/locking2.cxx b/compilerplugins/clang/test/locking2.cxx new file mode 100644 index 000000000000..5e6c36d4db26 --- /dev/null +++ b/compilerplugins/clang/test/locking2.cxx @@ -0,0 +1,56 @@ +/* -*- 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/. + */ + +#if defined _WIN32 //TODO, #include <sys/file.h> +// expected-no-diagnostics +#else + +#include <mutex> +#include <memory> +#include <osl/mutex.hxx> + +static std::mutex gSolarMutex; + +class SolarMutexGuard +{ + std::unique_lock<std::mutex> lock; + +public: + SolarMutexGuard() + : lock(gSolarMutex) + { + } +}; + +namespace test2 +{ +struct Foo +{ + std::mutex m_aMutex; + int m_foo; + std::shared_ptr<Foo> m_foo2; + + int bar3() + { + std::scoped_lock guard(m_aMutex); + // expected-error@+1 {{locked m_foo [loplugin:locking2]}} + return m_foo; + } + std::shared_ptr<Foo> bar4() + { + std::scoped_lock guard(m_aMutex); + // expected-error@+1 {{locked m_foo2 [loplugin:locking2]}} + return m_foo2; + } +}; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/logexceptionnicely.cxx b/compilerplugins/clang/test/logexceptionnicely.cxx index 458eef8c4d10..3a0d85f75280 100644 --- a/compilerplugins/clang/test/logexceptionnicely.cxx +++ b/compilerplugins/clang/test/logexceptionnicely.cxx @@ -7,7 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <sal/log.hxx> #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> #include <com/sun/star/uno/Exception.hpp> diff --git a/compilerplugins/clang/test/moveit.cxx b/compilerplugins/clang/test/moveit.cxx new file mode 100644 index 000000000000..9e4fa4f3d814 --- /dev/null +++ b/compilerplugins/clang/test/moveit.cxx @@ -0,0 +1,105 @@ +/* -*- 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 "config_clang.h" +#include <memory> + +// expected-note@+3 {{type declared here [loplugin:moveit]}} +// expected-note@+2 {{type declared here [loplugin:moveit]}} +// expected-note@+1 {{type declared here [loplugin:moveit]}} +struct Movable +{ + std::shared_ptr<int> x; + + void method1(); + + Movable(); + Movable(int); +}; + +namespace test1a +{ +struct F +{ + // expected-note@+1 {{passing to this param [loplugin:moveit]}} + void call_by_value(Movable); + void foo() + { + // expected-note@+1 {{local var declared here [loplugin:moveit]}} + Movable m; + // expected-error@+1 {{can std::move this var into this param [loplugin:moveit]}} + call_by_value(m); + } +}; +} + +namespace test1b +{ +struct F +{ + // expected-note@+1 {{passing to this param [loplugin:moveit]}} + F(Movable); + void foo() + { + // expected-note@+1 {{local var declared here [loplugin:moveit]}} + Movable m; + // expected-error@+1 {{can std::move this var into this param [loplugin:moveit]}} + F a(m); + (void)a; + } +}; +} + +namespace test2 +{ +struct F +{ + // expected-note@+1 {{passing to this param [loplugin:moveit]}} + F(Movable); + void foo() + { + // expected-note@+1 {{local var declared here [loplugin:moveit]}} + Movable m; + // expected-error@+1 {{can std::move this var into this param [loplugin:moveit]}} + F a(m); + (void)a; + } +}; +} + +// No error expected, because referencing after call +namespace test3 +{ +struct F +{ + F(Movable); + void foo() + { + Movable m; + F a(m); + m.method1(); + } +}; +} + +// No error expected, because constructing temporary(i.e. rvalue) to pass to param +namespace test4 +{ +struct F +{ + F(Movable); + void foo() + { + F a((Movable(5))); + (void)a; + } +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/noexceptmove.cxx b/compilerplugins/clang/test/noexceptmove.cxx index fda58deae403..c0742c8284b7 100644 --- a/compilerplugins/clang/test/noexceptmove.cxx +++ b/compilerplugins/clang/test/noexceptmove.cxx @@ -6,10 +6,6 @@ * 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 "config_clang.h" - -// clang before V9 does not have API to report exception spec type -#if CLANG_VERSION >= 90000 namespace test1 { @@ -96,7 +92,4 @@ class Bar }; }; -#else -// expected-no-diagnostics -#endif // CLANG_VERSION /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/nullptr.cxx b/compilerplugins/clang/test/nullptr.cxx index bf7376cb6562..392a930bf9b8 100644 --- a/compilerplugins/clang/test/nullptr.cxx +++ b/compilerplugins/clang/test/nullptr.cxx @@ -7,6 +7,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "sal/config.h" + +#include <compare> + struct S { void* p; @@ -18,6 +22,8 @@ int main() 0 // expected-error {{NullToPointer ValueDependentIsNotNull ZeroLiteral -> nullptr [loplugin:nullptr]}} }; (void)s; + + (void)(std::strong_order(0, 1) < 0); } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/optionalbool.cxx b/compilerplugins/clang/test/optionalbool.cxx new file mode 100644 index 000000000000..02c3a84cf962 --- /dev/null +++ b/compilerplugins/clang/test/optionalbool.cxx @@ -0,0 +1,27 @@ +/* -*- 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 "config_clang.h" +#include <optional> + +namespace test1 +{ +std::optional<bool> get_optional_bool(); +void foo1() +{ + // expected-error@+1 {{using conversion call to convert std::optional<bool> to bool probably does not do what you expect, rather use has_value() or value_or() [loplugin:optionalbool]}} + bool foo(get_optional_bool()); + (void)foo; + + // no warning expected + if (std::optional<bool> b = get_optional_bool()) + return; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/optvalue.cxx b/compilerplugins/clang/test/optvalue.cxx new file mode 100644 index 000000000000..6d1ad86e7535 --- /dev/null +++ b/compilerplugins/clang/test/optvalue.cxx @@ -0,0 +1,75 @@ +/* -*- 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 "config_clang.h" + +template <typename Type> class OptValue +{ +public: + OptValue() + : maValue() + , mbHasValue(false) + { + } + explicit OptValue(const Type& rValue) + : maValue(rValue) + , mbHasValue(true) + { + } + + bool has_value() const { return mbHasValue; } + bool operator!() const { return !mbHasValue; } + + const Type& value() const { return maValue; } + const Type& value_or(const Type& rDefValue) const { return mbHasValue ? maValue : rDefValue; } + + Type& operator*() { return maValue; } + Type& emplace() + { + mbHasValue = true; + maValue = Type(); + return maValue; + } + + OptValue& operator=(const Type& rValue) + { + maValue = rValue; + mbHasValue = true; + return *this; + } + bool operator==(const OptValue& rValue) const + { + return ((!mbHasValue && rValue.mbHasValue == false) + || (mbHasValue == rValue.mbHasValue && maValue == rValue.maValue)); + } + +private: + Type maValue; + bool mbHasValue; +}; + +struct AttributeList +{ + OptValue<int> getInteger(); +}; + +namespace test1 +{ +void foo(AttributeList& rAttrs) +{ + // expected-error@+1 {{call to OptValue::value() [loplugin:optvalue]}} + rAttrs.getInteger().value(); + + // no warning expected + OptValue<int> x; + x.value(); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/ostr.cxx b/compilerplugins/clang/test/ostr.cxx new file mode 100644 index 000000000000..e6e3a9b556e2 --- /dev/null +++ b/compilerplugins/clang/test/ostr.cxx @@ -0,0 +1,163 @@ +/* -*- 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 <string> +#include <string_view> + +#include "rtl/ustring.hxx" + +#define M(arg) f(arg, arg) + +struct S +{ + OUString s; +}; + +void takeOstring(OString const&); + +void takeOustring(OUString const&); + +void f(OUString const&, OUString const&); + +void takeStdString(std::string const&); + +void takeStdString(std::u16string const&); + +void takeStdView(std::string_view); + +void takeStdView(std::u16string_view); + +void f() +{ + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + OString s1o = "foo"; + (void)s1o; + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + OString s2o = (("foo")); + (void)s2o; + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + OString s3o("foo"); + (void)s3o; + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + OString s4o((("foo"))); + (void)s4o; + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + takeOstring(OString("foo")); + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + takeOstring(((OString((("foo")))))); + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + takeOstring(OString("foo", rtl::libreoffice_internal::Dummy())); + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + takeOstring(((OString((("foo")), rtl::libreoffice_internal::Dummy())))); + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + takeOstring("foo"); + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + takeOstring((("foo"))); + + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + OString s1o8 = u8"foo"; + (void)s1o8; + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + OString s2o8 = ((u8"foo")); + (void)s2o8; + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + OString s3o8(u8"foo"); + (void)s3o8; + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + OString s4o8(((u8"foo"))); + (void)s4o8; + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + takeOstring(OString(u8"foo")); + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + takeOstring(((OString(((u8"foo")))))); + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + takeOstring(OString(u8"foo", rtl::libreoffice_internal::Dummy())); + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + takeOstring(((OString(((u8"foo")), rtl::libreoffice_internal::Dummy())))); + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + takeOstring(u8"foo"); + // expected-error-re@+1 {{use a _ostr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OString' from an ordinary string literal [loplugin:ostr]}} + takeOstring(((u8"foo"))); + + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} + OUString s1u = "foo"; + (void)s1u; + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} + OUString s2u = (("foo")); + (void)s2u; + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} + OUString s3u("foo"); + (void)s3u; + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} + OUString s4u((("foo"))); + (void)s4u; + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} + takeOustring(OUString("foo")); + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} + takeOustring(((OUString((("foo")))))); + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} + takeOustring(OUString("foo", rtl::libreoffice_internal::Dummy())); + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} + takeOustring(((OUString((("foo")), rtl::libreoffice_internal::Dummy())))); + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} + takeOustring("foo"); + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} + takeOustring((("foo"))); + + OString s9; + // expected-error@+1 {{use a _ostr user-defined string literal instead of assigning from an ordinary string literal [loplugin:ostr]}} + s9 = "foo"; + // expected-error@+1 {{use a _ostr user-defined string literal instead of assigning from an ordinary string literal [loplugin:ostr]}} + s9 = (("foo")); + // expected-error@+1 {{use a _ostr user-defined string literal instead of assigning from an ordinary string literal [loplugin:ostr]}} + s9.operator=("foo"); + // expected-error@+1 {{use a _ostr user-defined string literal instead of assigning from an ordinary string literal [loplugin:ostr]}} + s9.operator=((("foo"))); + + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} + S s10 = { "foo" }; + + // Only generate one warning here, not two, for a macro argument used twice in the macro's + // expansion: + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} + M("foo"); + + // expected-note@+1 {{intermediary variable l1 declared here [loplugin:ostr]}} + constexpr OStringLiteral l1("foo"); + // expected-error@+1 {{directly use a _ostr user-defined string literal instead of introducing the intermediary 'OStringLiteral' variable l1 [loplugin:ostr]}} + (void)l1; + // expected-error@+1 {{use 'OString', created from a _ostr user-defined string literal, instead of 'OStringLiteral' for the variable l2 [loplugin:ostr]}} + constexpr OStringLiteral l2("foo"); + (void)l2; + (void)l2; + // expected-note@+1 {{intermediary variable l3 declared here [loplugin:ostr]}} + OUStringLiteral l3(u"foo"); + // expected-error@+1 {{directly use a _ustr user-defined string literal instead of introducing the intermediary 'OUStringLiteral' variable l3 [loplugin:ostr]}} + (void)l3; + // expected-error@+1 {{use 'OUString', created from a _ustr user-defined string literal, instead of 'OUStringLiteral' for the variable l4 [loplugin:ostr]}} + OUStringLiteral l4(u"foo"); + (void)l4; + (void)l4; +} + +void passLiteral() +{ + // expected-error-re@+1 {{directly use a 'std::string' (aka 'basic_string<char{{(, char_traits<char>, allocator<char>)?}}>') value instead of a _ostr user-defined string literal [loplugin:ostr]}} + takeStdString(std::string(""_ostr)); + // expected-error-re@+1 {{directly use a 'std::u16string' (aka 'basic_string<char16_t{{(, char_traits<char16_t>, allocator<char16_t>)?}}>') value instead of a _ustr user-defined string literal [loplugin:ostr]}} + takeStdString(std::u16string(u""_ustr)); + // expected-error@+1 {{directly use a 'std::string_view' (aka 'basic_string_view<char>') value instead of a _ostr user-defined string literal [loplugin:ostr]}} + takeStdView(""_ostr); + // expected-error@+1 {{directly use a 'std::u16string_view' (aka 'basic_string_view<char16_t>') value instead of a _ustr user-defined string literal [loplugin:ostr]}} + takeStdView(u""_ustr); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/putpoolitem.cxx b/compilerplugins/clang/test/putpoolitem.cxx new file mode 100644 index 000000000000..fb44612a00f4 --- /dev/null +++ b/compilerplugins/clang/test/putpoolitem.cxx @@ -0,0 +1,48 @@ +/* -*- 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 <memory> + +class SfxPoolItem +{ +public: + virtual ~SfxPoolItem(); +}; +class SfxPoolItemSubclass : public SfxPoolItem +{ +}; +class SfxItemSet +{ +public: + void Put(SfxPoolItem&); +}; + +void foo(SfxItemSet* pSet) +{ + std::unique_ptr<SfxPoolItemSubclass> foo; + SfxItemSet aSet; + // expected-error@+1 {{could use std::move? [loplugin:putpoolitem]}} + aSet.Put(*foo); + + // expected-error@+1 {{could use std::move? [loplugin:putpoolitem]}} + pSet->Put(*foo); +} + +class Foo2 +{ + std::unique_ptr<SfxPoolItemSubclass> m_foo; + void foo() + { + SfxItemSet aSet; + // no warning expected + aSet.Put(*m_foo); + } +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/rangedforcopy.cxx b/compilerplugins/clang/test/rangedforcopy.cxx new file mode 100644 index 000000000000..e9a836e2489c --- /dev/null +++ b/compilerplugins/clang/test/rangedforcopy.cxx @@ -0,0 +1,40 @@ +/* -*- 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 <vector> + +struct S +{ + int i1; + int i2; +}; + +void f(S const (&a)[2]) +{ + // expected-error-re@+1 {{Loop variable passed by value, pass by reference instead, e.g. 'const {{(struct )?}}S&' [loplugin:rangedforcopy]}} + for (auto i : a) + { + (void)i; + } + for (auto[i1, i2] : a) + { + (void)i1; + (void)i2; + } +} + +void f(std::vector<bool> const& v) +{ + for (auto b : v) + { + (void)b; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/redundantcast.cxx b/compilerplugins/clang/test/redundantcast.cxx index d1803aafbca7..47a155c64b37 100644 --- a/compilerplugins/clang/test/redundantcast.cxx +++ b/compilerplugins/clang/test/redundantcast.cxx @@ -329,14 +329,26 @@ void testArithmeticTypedefs() { (void) static_cast<T1>(c); // expected-error {{redundant}} } +void testReinterpretCast() { + int * p; + (void) reinterpret_cast<int *>(p); // expected-error {{redundant reinterpret_cast from 'int *' to 'int *' [loplugin:redundantcast]}} +} + void testReinterpretConstCast() { int n = 0; (void) reinterpret_cast<std::size_t>((const_cast<int const *>(&n))); // expected-error-re {{redundant const_cast from 'int *' to 'const int *' within reinterpret_cast to fundamental type 'std::size_t' (aka 'unsigned {{.+}}') [loplugin:redundantcast]}} } +void testSuspiciousReinterpretCast() { + D * p; + // expected-error@+1 {{suspicious reinterpret_cast from derived 'D *' to base 'S *', maybe this was meant to be a static_cast [loplugin:redundantcast]}} + (void) reinterpret_cast<S *>(p); + (void) reinterpret_cast<sal_uIntPtr>(p); // expected no error +} + void testDynamicCast() { - struct S1 { virtual ~S1(); }; + struct S1 { virtual ~S1() {} }; struct S2 final: S1 {}; struct S3: S1 {}; @@ -344,12 +356,37 @@ void testDynamicCast() { S2 * s2 = nullptr; S3 * s3 = nullptr; + (void) dynamic_cast<void *>(s1); + (void) dynamic_cast<void const *>(s1); (void) dynamic_cast<S2 *>(s1); + (void) dynamic_cast<S2 &>(*s1); (void) dynamic_cast<S1 *>(s2); // expected-error {{redundant dynamic upcast from 'S2 *' to 'S1 *' [loplugin:redundantcast]}} + (void) dynamic_cast<S1 &>(*s2); // expected-error {{redundant dynamic upcast from 'S2' to 'S1 &' [loplugin:redundantcast]}} (void) dynamic_cast<S2 *>(s2); // expected-error {{redundant dynamic cast from 'S2 *' to 'S2 *' [loplugin:redundantcast]}} + (void) dynamic_cast<S2 &>(*s2); // expected-error {{redundant dynamic cast from 'S2' to 'S2 &' [loplugin:redundantcast]}} (void) dynamic_cast<S3 *>(s2); + (void) dynamic_cast<S3 &>(*s2); (void) dynamic_cast<const S2 *>(s2); // expected-error {{redundant dynamic cast from 'S2 *' to 'const S2 *' [loplugin:redundantcast]}} + (void) dynamic_cast<const S2 &>(*s2); // expected-error {{redundant dynamic cast from 'S2' to 'const S2 &' [loplugin:redundantcast]}} (void) dynamic_cast<S1 *>(s3); // expected-error {{redundant dynamic upcast from 'S3 *' to 'S1 *' [loplugin:redundantcast]}} + (void) dynamic_cast<S1&>(*s3); // expected-error {{redundant dynamic upcast from 'S3' to 'S1 &' [loplugin:redundantcast]}} + + S1 const * c1 = nullptr; + S2 const * c2 = nullptr; + S3 const * c3 = nullptr; + + (void) dynamic_cast<void const *>(c1); + (void) dynamic_cast<S2 const *>(c1); + (void) dynamic_cast<S2 const &>(*c1); + (void) dynamic_cast<S1 const *>(c2); // expected-error {{redundant dynamic upcast from 'const S2 *' to 'const S1 *' [loplugin:redundantcast]}} + (void) dynamic_cast<S1 const &>(*c2); // expected-error {{redundant dynamic upcast from 'const S2' to 'const S1 &' [loplugin:redundantcast]}} + + (void) dynamic_cast<S2 const *>(c2); // expected-error {{redundant dynamic cast from 'const S2 *' to 'const S2 *' [loplugin:redundantcast]}} + (void) dynamic_cast<S2 const &>(*c2); // expected-error {{redundant dynamic cast from 'const S2' to 'const S2 &' [loplugin:redundantcast]}} + (void) dynamic_cast<S3 const *>(c2); + (void) dynamic_cast<S3 const &>(*c2); + (void) dynamic_cast<S1 const *>(c3); // expected-error {{redundant dynamic upcast from 'const S3 *' to 'const S1 *' [loplugin:redundantcast]}} + (void) dynamic_cast<S1 const&>(*c3); // expected-error {{redundant dynamic upcast from 'const S3' to 'const S1 &' [loplugin:redundantcast]}} } void overload(int); @@ -436,12 +473,25 @@ void testSalIntTypes() { (void) static_cast<Other>(n); // doesn't warn either } +void testFunctionalCast2() { + struct S1 { S1(int, int, int, int) {} }; + + // expected-error@+1 {{redundant functional cast [loplugin:redundantcast]}} + S1 aTitleBarBox(S1(0, 0, 0, 0)); + (void)aTitleBarBox; + + // no warning expected +#define S1_COL S1(0,0,0,0) + S1 aTest2(S1_COL); +} + int main() { testConstCast(); testStaticCast(); testFunctionalCast(); testCStyleCast(); testCStyleCastOfTemplateMethodResult(nullptr); + testReinterpretCast(); testReinterpretConstCast(); testDynamicCast(); testIntermediaryStaticCast(); diff --git a/compilerplugins/clang/test/redundantfcast.cxx b/compilerplugins/clang/test/redundantfcast.cxx index 20c939cb2b42..1d13d8bea238 100644 --- a/compilerplugins/clang/test/redundantfcast.cxx +++ b/compilerplugins/clang/test/redundantfcast.cxx @@ -9,6 +9,7 @@ #include "sal/config.h" +#include "config_clang.h" #include "rtl/ustring.hxx" #include "tools/color.hxx" @@ -44,23 +45,23 @@ int main() { OUString s; (void)OUString( - s); // expected-error@-1 {{redundant functional cast from 'rtl::OUString' to 'rtl::OUString' [loplugin:redundantfcast]}} + s); // expected-error-re@-1 {{redundant functional cast from '{{(rtl::)?}}OUString' to '{{(rtl::)?}}OUString' [loplugin:redundantfcast]}} using T1 = OUString; (void)T1( - s); // expected-error@-1 {{redundant functional cast from 'rtl::OUString' to 'T1' (aka 'rtl::OUString') [loplugin:redundantfcast]}} + s); // expected-error-re@-1 {{redundant functional cast from '{{(rtl::)?}}OUString' to 'T1' (aka '{{(rtl::)?}}OUString') [loplugin:redundantfcast]}} using T2 = OUString const; (void)T2( - s); // expected-error@-1 {{redundant functional cast from 'rtl::OUString' to 'T2' (aka 'const rtl::OUString') [loplugin:redundantfcast]}} + s); // expected-error-re@-1 {{redundant functional cast from '{{(rtl::)?}}OUString' to 'T2' (aka 'const {{(rtl::?)}}OUString') [loplugin:redundantfcast]}} (void)std::unique_ptr<int>(std::unique_ptr<int>( new int{})); // expected-error@-1 {{redundant functional cast from 'std::unique_ptr<int>' to 'std::unique_ptr<int>' [loplugin:redundantfcast]}} OUString s1; method1(OUString( - s1)); // expected-error@-1 {{redundant functional cast from 'rtl::OUString' to 'rtl::OUString' [loplugin:redundantfcast]}} + s1)); // expected-error-re@-1 {{redundant functional cast from '{{(rtl::)?}}OUString' to '{{(rtl::)?}}OUString' [loplugin:redundantfcast]}} OUString s2; s2 = OUString( - s1); // expected-error@-1 {{redundant functional cast from 'rtl::OUString' to 'rtl::OUString' [loplugin:redundantfcast]}} + s1); // expected-error-re@-1 {{redundant functional cast from '{{(rtl::)?}}OUString' to '{{(rtl::)?}}OUString' [loplugin:redundantfcast]}} (void)s2; Color col1; @@ -221,4 +222,21 @@ void foo() (void)aGroup; } } + +namespace test9 +{ +struct S +{ + int n; +}; + +void f() +{ + (void)S{ 0 }; +#if CLANG_VERSION >= 160000 + (void)S(0); +#endif +} +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/refcounting.cxx b/compilerplugins/clang/test/refcounting.cxx index 7ab830fc913b..54d4dbe14b38 100644 --- a/compilerplugins/clang/test/refcounting.cxx +++ b/compilerplugins/clang/test/refcounting.cxx @@ -13,16 +13,8 @@ #include <rtl/ref.hxx> #include <boost/intrusive_ptr.hpp> #include <com/sun/star/uno/XInterface.hpp> - -namespace cppu -{ -class OWeakObject -{ -public: - void acquire(); - void release(); -}; -} +#include <cppuhelper/weak.hxx> +#include <unotools/weakref.hxx> struct UnoObject : public cppu::OWeakObject { @@ -117,4 +109,24 @@ void foo7() p3 = static_cast<UnoSubObject*>(getConstRef().get()); } +const unotools::WeakReference<UnoObject>& getWeakRef(); +void foo8() +{ + // expected-error@+1 {{weak object being converted to strong, and then the reference dropped, and managed via raw pointer, should be managed via rtl::Reference [loplugin:refcounting]}} + UnoSubObject* p1 = static_cast<UnoSubObject*>(getWeakRef().get().get()); + (void)p1; + + // expected-error@+1 {{weak object being converted to strong, and then the reference dropped, and managed via raw pointer, should be managed via rtl::Reference [loplugin:refcounting]}} + UnoObject* p2 = getWeakRef().get().get(); + (void)p2; + + unotools::WeakReference<UnoObject> weak1; + // expected-error@+1 {{weak object being converted to strong, and then the reference dropped, and managed via raw pointer, should be managed via rtl::Reference [loplugin:refcounting]}} + UnoSubObject* p3 = dynamic_cast<UnoSubObject*>(weak1.get().get()); + (void)p3; + + // expected-error@+1 {{weak object being converted to strong, and then the reference dropped, and managed via raw pointer, should be managed via rtl::Reference [loplugin:refcounting]}} + UnoObject* p4 = weak1.get().get(); + (void)p4; +} /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/referencecasting.cxx b/compilerplugins/clang/test/referencecasting.cxx index 1b1e75f90cea..beb69cc86616 100644 --- a/compilerplugins/clang/test/referencecasting.cxx +++ b/compilerplugins/clang/test/referencecasting.cxx @@ -8,7 +8,6 @@ */ #include "sal/config.h" -#include "config_clang.h" #include "com/sun/star/uno/Sequence.hxx" #include "com/sun/star/uno/XInterface.hpp" @@ -105,16 +104,12 @@ void test(rtl::Reference<FooStream> l) css::uno::Reference<css::io::XStreamListener> a2 = l; (void)a2; } -// not should about the exact version I should use here, -// clang 7.0.1 visits the CXXConstructorExpr inside the initializer, while clang 11 does not -#if CLANG_VERSION >= 80000 css::uno::Sequence<css::uno::Reference<css::io::XStreamListener>> getContinuations() { rtl::Reference<FooStream> noel1; // expected-error@+1 {{unnecessary get() call [loplugin:referencecasting]}} return { noel1.get() }; } -#endif } namespace test8 @@ -211,6 +206,11 @@ class Foo : public cppu::WeakImplHelper<css::lang::XComponent, css::io::XInputSt return css::uno::Reference<css::io::XInputStream>(static_cast<css::io::XInputStream*>(this), css::uno::UNO_QUERY); } + css::uno::Reference<css::io::XInputStream> bar3() + { + // expected-error@+1 {{the source reference is already a subtype of the destination reference, just use = [loplugin:referencecasting]}} + return css::uno::Reference<css::io::XInputStream>(*this, css::uno::UNO_QUERY); + } }; } diff --git a/compilerplugins/clang/test/sallogareas.cxx b/compilerplugins/clang/test/sallogareas.cxx index 1b172ebd00b6..8dd552b9faa6 100644 --- a/compilerplugins/clang/test/sallogareas.cxx +++ b/compilerplugins/clang/test/sallogareas.cxx @@ -7,7 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <sal/log.hxx> void func1(); diff --git a/compilerplugins/clang/test/staticmethods.cxx b/compilerplugins/clang/test/staticmethods.cxx new file mode 100644 index 000000000000..cd87c930dc23 --- /dev/null +++ b/compilerplugins/clang/test/staticmethods.cxx @@ -0,0 +1,16 @@ +/* -*- 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/. + */ + +class foo +{ + // expected-error@+1 {{this member function can be declared static [loplugin:staticmethods]}} + int method1() { return 5; } +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/stringadd.cxx b/compilerplugins/clang/test/stringadd.cxx index f76464b9a96d..7c1193643303 100644 --- a/compilerplugins/clang/test/stringadd.cxx +++ b/compilerplugins/clang/test/stringadd.cxx @@ -27,48 +27,48 @@ static const char XXX2[] = "xxx"; void f1(OUString s1, int i, OString o) { OUString s2 = s1; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += "xxx"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += "xxx"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += s1; s2 = s1 + "xxx"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += s1; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += OUString::number(i); - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += XXX1; - // expected-error-re@+2 {{rather use O[U]String::Concat than constructing 'rtl::OUStringLiteral<4>' from 'const char16_t{{ ?}}[4]' on LHS of + (where RHS is of type 'const char{{ ?}}[4]') [loplugin:stringadd]}} - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error-re@+2 {{rather use O[U]String::Concat than constructing '{{(rtl::)?}}OUStringLiteral<4>'{{( \(aka 'rtl::OUStringLiteral<4>'\))?}} from 'const char16_t{{ ?}}[4]' on LHS of + (where RHS is of type 'const char{{ ?}}[4]') [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += OUStringLiteral(XXX1u) + XXX2; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += OStringToOUString(o, RTL_TEXTENCODING_UTF8); } void f2(OString s1, int i, OUString u) { OString s2 = s1; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += "xxx"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += "xxx"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += s1; s2 = s1 + "xxx"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += s1; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += OString::number(i); - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += OUStringToOString(u, RTL_TEXTENCODING_ASCII_US); } void f3(OUString aStr, int nFirstContent) { OUString aFirstStr = aStr.copy(0, nFirstContent); - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} aFirstStr += "..."; } OUString side_effect(); @@ -76,15 +76,15 @@ void f4(int i) { OUString s1; OUString s2("xxx"); - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += "xxx"; ++i; // any other kind of statement breaks the chain (at least for now) s2 += "xxx"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s2 += side_effect(); s1 += "yyy"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s1 += "yyy"; } } @@ -94,13 +94,13 @@ namespace test2 void f(OUString s3) { s3 += "xxx"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s3 += "xxx"; } void g(OString s3) { s3 += "xxx"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s3 += "xxx"; } } @@ -114,28 +114,28 @@ struct Bar void f(Bar b1, Bar& b2, Bar* b3) { OUString s3 = "xxx"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s3 += b1.m_field; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s3 += b2.m_field; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s3 += b3->m_field; } OUString side_effect(); void f2(OUString s) { OUString sRet = "xxx"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} sRet += side_effect(); - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} sRet += "xxx"; sRet += side_effect(); - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} sRet += "xxx"; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} sRet += "xxx"; sRet += s; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} sRet += "xxx"; } } @@ -151,7 +151,7 @@ void f() sRet += ";"; #endif sRet += " "; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} sRet += side_effect(); } } @@ -172,9 +172,9 @@ namespace test6 void f(OUString sComma, OUString maExtension, int mnDocumentIconID) { OUString sValue; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} sValue += sComma + sComma + maExtension + sComma; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} sValue += OUString::number(mnDocumentIconID) + sComma; } struct Foo @@ -188,7 +188,7 @@ void g(int x, const Foo& aValidation) { case 1: sCondition += "cell-content-is-in-list("; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} sCondition += aValidation.sFormula1 + ")"; } } @@ -205,9 +205,9 @@ void f1(OUString s, OUString t, int i, const char* pChar) { // no warning expected t = t + "xxx"; - // expected-error-re@+1 {{rather use O[U]String::Concat than constructing 'rtl::OUString' from 'const char{{ ?}}[4]' on RHS of + (where LHS is of type 'rtl::OUString') [loplugin:stringadd]}} + // expected-error-re@+1 {{rather use O[U]String::Concat than constructing '{{(rtl::)?}}OUString' from 'const char{{ ?}}[4]' on RHS of + (where LHS is of type '{{(rtl::)?}}OUString') [loplugin:stringadd]}} s = s + OUString("xxx"); - // expected-error@+1 {{rather use O[U]String::Concat than constructing 'rtl::OUString' from 'const rtl::OUString' on RHS of + (where LHS is of type 'rtl::OUString') [loplugin:stringadd]}} + // expected-error-re@+1 {{rather use O[U]String::Concat than constructing '{{(rtl::)?}}OUString' from 'const {{(rtl::)?}}OUString' on RHS of + (where LHS is of type '{{(rtl::)?}}OUString') [loplugin:stringadd]}} s = s + OUString(getByRef()); // no warning expected @@ -229,9 +229,9 @@ void f1(OUString s, OUString t, int i, const char* pChar) void f2(char ch) { OString s; - // expected-error-re@+1 {{rather use O[U]String::Concat than constructing 'rtl::OString' from 'const char{{ ?}}[4]' on RHS of + (where LHS is of type 'rtl::OString') [loplugin:stringadd]}} + // expected-error-re@+1 {{rather use O[U]String::Concat than constructing '{{(rtl::)?}}OString' from 'const char{{ ?}}[4]' on RHS of + (where LHS is of type '{{(rtl::)?}}OString') [loplugin:stringadd]}} s = s + OString("xxx"); - // expected-error@+1 {{rather use O[U]String::Concat than constructing 'rtl::OString' from 'char' on RHS of + (where LHS is of type 'rtl::OString') [loplugin:stringadd]}} + // expected-error-re@+1 {{rather use O[U]String::Concat than constructing '{{(rtl::)?}}OString' from 'char' on RHS of + (where LHS is of type '{{(rtl::)?}}OString') [loplugin:stringadd]}} s = s + OString(ch); } } @@ -251,7 +251,7 @@ C getC(); void f1(C c) { OString s; - // expected-error@+1 {{simplify by merging with the preceding assignment [loplugin:stringadd]}} + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} s += c.constStringFunction(c.constIntFunction()); s += c.constStringFunction(c.nonConstIntFunction()); s += c.nonConstStringFunction(); @@ -259,4 +259,57 @@ void f1(C c) } } +namespace test11 +{ +void f1() +{ + OUStringBuffer aFirstStr1("aaa"); + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} + aFirstStr1.append("..."); + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} + aFirstStr1.append("..."); +} +} + +namespace test12 +{ +void f1(int j) +{ + OUStringBuffer aFirstStr1(12); + // no warning expected + aFirstStr1.append("..."); + // expected-error@+1 {{simplify by merging with the preceding assign/append [loplugin:stringadd]}} + aFirstStr1.append("..."); + // no warning expected + aFirstStr1.append(((j + 1) % 15) ? " " : "\n"); +} +} + +namespace test13 +{ +void f1() +{ + OUStringBuffer aFirstStr1(12); + // no warning expected + aFirstStr1.append("..."); + // because we have a comment between them + aFirstStr1.append("..."); +} +} + +namespace test14 +{ +void f1() +{ + OUStringBuffer b(16); + b.append("..."); +} + +void f2(long long n) +{ + OUStringBuffer b(n); + b.append("..."); +} +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/stringconcatauto.cxx b/compilerplugins/clang/test/stringconcatauto.cxx index dc450503d25e..dde4211eaee4 100644 --- a/compilerplugins/clang/test/stringconcatauto.cxx +++ b/compilerplugins/clang/test/stringconcatauto.cxx @@ -15,46 +15,42 @@ void foo() { auto str1 = "str1" + OUString::number(10); // expected-error-re@-1 {{creating a variable of type {{.+}} will make it reference temporaries}} - // expected-note@-2 {{use OUString instead}} + // expected-note@-2 {{use O(U)String instead}} OUString str2 = "str2" + OUString::number(20) + "ing"; const auto& str3 = "str3" + OUString::number(30); // expected-error-re@-1 {{creating a variable of type {{.+}} will make it reference temporaries}} - // expected-note@-2 {{use OUString instead}} + // expected-note@-2 {{use O(U)String instead}} const auto str4 = "str4" + OString::number(40); // expected-error-re@-1 {{creating a variable of type {{.+}} will make it reference temporaries}} - // expected-note@-2 {{use OString instead}} + // expected-note@-2 {{use O(U)String instead}} auto str5 = OUString::number(50); - // expected-error-re@-1 {{creating a variable of type '{{(rtl::)?}}OUStringNumber<{{.*}}>' will make it reference temporaries}} - // expected-note@-2 {{use OUString instead}} + auto str6 = OUString::number(50).toAsciiUpperCase(); (void)str1; (void)str2; (void)str3; (void)str4; (void)str5; + (void)str6; } struct A { auto bar() // expected-error-re@-1 {{returning a variable of type {{.+}} will make it reference temporaries}} - // expected-note@-2 {{use OString instead}} + // expected-note@-2 {{use O(U)String instead}} { return "bar" + OString::number(110); } - auto baz() - // expected-error-re@-1 {{returning a variable of type '{{(rtl::)?}}OStringNumber<{{.*}}>' will make it reference temporaries}} - // expected-note@-2 {{use OString instead}} - { - return OString::number(120); - } + auto baz() { return OString::number(120); } + auto baz2() { return OString::number(120).toAsciiUpperCase(); } }; template <typename T> void fun(const T& par) // parameters are without warnings { const T& var = par; - // expected-error-re@-1 {{creating a variable of type 'const rtl::OUStringConcat<{{.*}}> &' will make it reference temporaries}} - // expected-note@-2 {{use OUString instead}} + // expected-error-re@-1 {{creating a variable of type 'const rtl::StringConcat<{{.*}}> &' will make it reference temporaries}} + // expected-note@-2 {{use O(U)String instead}} (void)var; } diff --git a/compilerplugins/clang/test/stringconcatliterals.cxx b/compilerplugins/clang/test/stringconcatliterals.cxx index 8b390f28fbbb..0575eb252bc0 100644 --- a/compilerplugins/clang/test/stringconcatliterals.cxx +++ b/compilerplugins/clang/test/stringconcatliterals.cxx @@ -40,6 +40,7 @@ void f(std::ostream& s1) s1 << "foo" << OUString(FOO); // expected-error@-1 {{replace '<<' between string literals with juxtaposition}} s1 << "foo" << OUString(foo); + s1 << "foo" << __func__; OString s2; s2 = "foo" + OString("foo"); // expected-error@-1 {{replace '+' between string literals with juxtaposition}} diff --git a/compilerplugins/clang/test/stringconstant.cxx b/compilerplugins/clang/test/stringconstant.cxx index 02f83b531068..f5982e2a4977 100644 --- a/compilerplugins/clang/test/stringconstant.cxx +++ b/compilerplugins/clang/test/stringconstant.cxx @@ -102,10 +102,6 @@ int main() { (void) OUString("xxx", 2, RTL_TEXTENCODING_ASCII_US); // expected-error {{suspicious 'rtl::OUString' constructor with literal of length 3 and non-matching length argument 2 [loplugin:stringconstant]}} -#if !defined __cpp_char8_t - (void) OUString(u8"xxx", 3, RTL_TEXTENCODING_ASCII_US); // expected-error {{simplify construction of 'OUString' with string constant argument [loplugin:stringconstant]}} -#endif - (void) OUString("\x80", 1, RTL_TEXTENCODING_UTF8); // expected-error {{suspicious 'rtl::OUString' constructor with text encoding 'RTL_TEXTENCODING_UTF8' but non-UTF-8 content [loplugin:stringconstant]}} (void) OUString("\xC2\x80", 2, RTL_TEXTENCODING_UTF8); // expected-error {{simplify construction of 'OUString' with UTF-8 content as OUString(u"\u0080") [loplugin:stringconstant]}} @@ -128,6 +124,17 @@ int main() { ub.append(static_cast<char const *>(sc2)); // at runtime: append "foo" ub.append(static_cast<char const *>(sc3)); // at runtime: assert ub.append(static_cast<char const *>(sc4)); // at runtime: UB + + // expected-error-re@+1 {{in call of 'rtl::OString::getStr', replace default-constructed '{{(rtl::)?}}OString' directly with an empty ordinary string literal}} + OString().getStr(); + // expected-error-re@+1 {{in call of 'rtl::OString::getStr', replace '{{(rtl::)?}}OString' constructed from a string literal directly with the string literal}} + OString("foo").getStr(); + // expected-error-re@+1 {{in call of 'rtl::OString::getStr', replace '{{(rtl::)?}}OString' constructed from a string literal directly with the string literal}} + (OString(("foo"))).getStr(); + // expected-error-re@+1 {{in call of 'rtl::OUString::getStr', replace default-constructed '{{(rtl::)?}}OUString' directly with an empty UTF-16 string literal}} + OUString().getStr(); + // expected-error-re@+1 {{in call of 'rtl::OUString::getStr', replace '{{(rtl::)?}}OUString' constructed from a string literal directly with a UTF-16 string literal}} + OUString("foo").getStr(); } diff --git a/compilerplugins/clang/test/stringliteralvar.cxx b/compilerplugins/clang/test/stringliteralvar.cxx index 1389146b6222..6ea7c184c644 100644 --- a/compilerplugins/clang/test/stringliteralvar.cxx +++ b/compilerplugins/clang/test/stringliteralvar.cxx @@ -9,16 +9,16 @@ #include <sal/config.h> +#include <iterator> #include <vector> #include <rtl/ustring.hxx> -#include <sal/macros.h> // expected-error-re@+1 {{change type of variable 'literal1' from constant character array ('const char{{ ?}}[4]') to OStringLiteral [loplugin:stringliteralvar]}} char const literal1[] = "foo"; OString f1() { - // expected-note@+1 {{first passed into a 'rtl::OString' constructor here [loplugin:stringliteralvar]}} + // expected-note-re@+1 {{first passed into a '{{(rtl::)?}}OString' constructor here [loplugin:stringliteralvar]}} return literal1; } @@ -27,7 +27,7 @@ void f2() { // expected-error-re@+1 {{change type of variable 'literal' from constant character array ('const char{{ ?}}[4]') to OUStringLiteral, and make it static [loplugin:stringliteralvar]}} char const literal[] = "foo"; - // expected-note@+1 {{first passed into a 'rtl::OUString' constructor here [loplugin:stringliteralvar]}} + // expected-note-re@+1 {{first passed into a '{{(rtl::)?}}OUString' constructor here [loplugin:stringliteralvar]}} f(literal); } @@ -38,31 +38,31 @@ struct S3 }; void f3() { - // expected-note@+1 {{first passed into a 'rtl::OUString' constructor here [loplugin:stringliteralvar]}} - f(S3::literal); + // expected-note-re@+1 {{first passed into a '{{(rtl::)?}}OUString' constructor here [loplugin:stringliteralvar]}} + f(OUString(S3::literal, 3)); } std::vector<OUString> f4() { // expected-error-re@+1 {{change type of variable 'literal' from constant character array ('const char16_t{{ ?}}[4]') to OUStringLiteral [loplugin:stringliteralvar]}} static constexpr char16_t literal[] = u"foo"; - // expected-note@+1 {{first passed into a 'rtl::OUString' constructor here [loplugin:stringliteralvar]}} - return { literal }; + // expected-note-re@+1 {{first passed into a '{{(rtl::)?}}OUString' constructor here [loplugin:stringliteralvar]}} + return { OUString(literal, 3) }; } void f5() { - // expected-error@+1 {{variable 'literal' of type 'const rtl::OUStringLiteral<4>' with automatic storage duration most likely needs to be static [loplugin:stringliteralvar]}} + // expected-error-re@+1 {{variable 'literal' of type 'const {{(rtl::)?}}OUStringLiteral<4>'{{( \(aka 'const rtl::OUStringLiteral<4>'\))?}} with automatic storage duration most likely needs to be static [loplugin:stringliteralvar]}} OUStringLiteral const literal = u"foo"; - // expected-note@+1 {{first converted to 'rtl::OUString' here [loplugin:stringliteralvar]}} + // expected-note-re@+1 {{first converted to '{{(rtl::)?}}OUString' here [loplugin:stringliteralvar]}} f(literal); } void f6() { - // expected-error@+1 {{variable 'literal' of type 'const rtl::OUStringLiteral<4>' with automatic storage duration most likely needs to be static [loplugin:stringliteralvar]}} + // expected-error-re@+1 {{variable 'literal' of type 'const {{(rtl::)?}}OUStringLiteral<4>'{{( \(aka 'const rtl::OUStringLiteral<4>'\))?}} with automatic storage duration most likely needs to be static [loplugin:stringliteralvar]}} constexpr OUStringLiteral literal = u"foo"; - // expected-note@+1 {{first converted to 'rtl::OUString' here [loplugin:stringliteralvar]}} + // expected-note-re@+1 {{first converted to '{{(rtl::)?}}OUString' here [loplugin:stringliteralvar]}} f(literal); } @@ -75,23 +75,23 @@ void f7() void f8() { static constexpr OUStringLiteral const literal = u"foo"; - // expected-error@+1 {{variable 'literal' of type 'const rtl::OUStringLiteral<4>' suspiciously used in a sizeof expression [loplugin:stringliteralvar]}} + // expected-error-re@+1 {{variable 'literal' of type 'const {{(rtl::)?}}OUStringLiteral<4>'{{( \(aka 'const rtl::OUStringLiteral<4>'\))?}} suspiciously used in a sizeof expression [loplugin:stringliteralvar]}} (void)sizeof literal; } void f9() { - // expected-error-re@+1 {{change type of variable 'literal' from constant character array ('const sal_Unicode{{ ?}}[3]') to OUStringLiteral [loplugin:stringliteralvar]}} + // expected-error-re@+1 {{change type of variable 'literal' from constant character array ('const sal_Unicode{{ ?}}[3]'{{( \(aka 'const char16_t\[3\]'\))?}}) to OUStringLiteral [loplugin:stringliteralvar]}} static sal_Unicode const literal[] = { 'f', 'o', 'o' }; - // expected-note@+1 {{first passed into a 'rtl::OUString' constructor here [loplugin:stringliteralvar]}} - f(OUString(literal, SAL_N_ELEMENTS(literal))); + // expected-note-re@+1 {{first passed into a '{{(rtl::)?}}OUString' constructor here [loplugin:stringliteralvar]}} + f(OUString(literal, std::size(literal))); } void f10() { - // expected-error-re@+1 {{change type of variable 'literal' from constant character array ('const sal_Unicode{{ ?}}[3]') to OUStringLiteral [loplugin:stringliteralvar]}} + // expected-error-re@+1 {{change type of variable 'literal' from constant character array ('const sal_Unicode{{ ?}}[3]'{{( \(aka 'const char16_t\[3\]'\))?}}) to OUStringLiteral [loplugin:stringliteralvar]}} static sal_Unicode const literal[] = { 'f', 'o', 'o' }; - // expected-note@+1 {{first passed into a 'rtl::OUString' constructor here [loplugin:stringliteralvar]}} + // expected-note-re@+1 {{first passed into a '{{(rtl::)?}}OUString' constructor here [loplugin:stringliteralvar]}} f(OUString(literal, 3)); } @@ -110,4 +110,25 @@ void f11(int nStreamType) (void)sStreamType; } +extern sal_Unicode const extarr[1]; + +sal_Unicode init(); + +void f12() +{ + // Suppress warnings if the array contains a malformed sequence of UTF-16 code units...: + static sal_Unicode const arr1[] = { 0xD800 }; + f(OUString(arr1, 1)); + // ...Or potentially contains a malformed sequence of UTF-16 code units...: + f(OUString(extarr, 1)); + sal_Unicode const arr2[] = { init() }; + f(OUString(arr2, 1)); + // ...But generate a warning if the array contains a well-formed sequence of UTF-16 code units + // containing surrogates: + // expected-error-re@+1 {{change type of variable 'arr3' from constant character array ('const sal_Unicode{{ ?}}[2]'{{( \(aka 'const char16_t\[2\]'\))?}}) to OUStringLiteral [loplugin:stringliteralvar]}} + static sal_Unicode const arr3[] = { 0xD800, 0xDC00 }; + // expected-note-re@+1 {{first passed into a '{{(rtl::)?}}OUString' constructor here [loplugin:stringliteralvar]}} + f(OUString(arr3, 2)); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/stringstatic.cxx b/compilerplugins/clang/test/stringstatic.cxx index 3c26d961c6a8..7e2089a17da7 100644 --- a/compilerplugins/clang/test/stringstatic.cxx +++ b/compilerplugins/clang/test/stringstatic.cxx @@ -9,21 +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*); +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/cppunitassertequals.hxx b/compilerplugins/clang/test/stringview-c++03.cxx index 2448d64e93e7..1824ac9d02ce 100644 --- a/compilerplugins/clang/test/cppunitassertequals.hxx +++ b/compilerplugins/clang/test/stringview-c++03.cxx @@ -7,17 +7,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#pragma once +#include <sal/config.h> -#include "sal/config.h" +#include <rtl/ustrbuf.hxx> -#include <cstddef> +// expected-no-diagnostics -#include "rtl/ustring.hxx" - -struct T { bool operator ==(T); }; - -void test( - bool b1, bool b2, OUString const & s1, OUString const & s2, T t, void * p, std::nullptr_t n); +rtl::OUStringBuffer nowarn(rtl::OUStringBuffer const& s, sal_Int32 n) +{ + return s.copy(n, s.getLength() - n); +} /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/stringview.cxx b/compilerplugins/clang/test/stringview.cxx index c03fbb84cb32..a8df9dd6b179 100644 --- a/compilerplugins/clang/test/stringview.cxx +++ b/compilerplugins/clang/test/stringview.cxx @@ -10,6 +10,7 @@ #include <sal/config.h> #include <string_view> +#include <utility> #include <rtl/strbuf.hxx> #include <rtl/string.hxx> @@ -59,6 +60,54 @@ void f1(OString s1) // expected-error@+1 {{rather than copy, pass with a view using subView() [loplugin:stringview]}} ConstructWithView(s1.copy(1)); } +void f1(OUStringBuffer s1) +{ + // expected-error@+1 {{rather than copy, pass with a view using subView() [loplugin:stringview]}} + call_view(s1.copy(1, 2)); + // expected-error@+1 {{rather than copy, pass with a view using subView() [loplugin:stringview]}} + call_view(s1.copy(1)); + // expected-error@+1 {{rather than copy, pass with a view using subView() [loplugin:stringview]}} + ConstructWithView(s1.copy(1, 2)); + // expected-error@+1 {{rather than copy, pass with a view using subView() [loplugin:stringview]}} + ConstructWithView(s1.copy(1)); + // expected-error@+1 {{rather than call toString, pass with a view [loplugin:stringview]}} + call_view(s1.toString()); + // expected-error@+1 {{rather than call toString, pass with a view [loplugin:stringview]}} + ConstructWithView(s1.toString()); +} +void f1(OStringBuffer s1) +{ + // expected-error@+1 {{rather than call toString, pass with a view [loplugin:stringview]}} + call_view(s1.toString()); + // expected-error@+1 {{rather than call toString, pass with a view [loplugin:stringview]}} + ConstructWithView(s1.toString()); +} +void makeStringAndClear(OUStringBuffer s) +{ + call_view(s.makeStringAndClear()); + ConstructWithView(s.makeStringAndClear()); + call_view((&s)->makeStringAndClear()); + ConstructWithView((&s)->makeStringAndClear()); + // expected-error@+1 {{rather than call makeStringAndClear on an rvalue, pass with a view [loplugin:stringview]}} + call_view(std::move(s).makeStringAndClear()); + // expected-error@+1 {{rather than call makeStringAndClear on an rvalue, pass with a view [loplugin:stringview]}} + ConstructWithView(std::move(s).makeStringAndClear()); + // expected-error@+1 {{rather than call makeStringAndClear on an rvalue, pass with a view [loplugin:stringview]}} + call_view((s).copy(1).makeStringAndClear()); + // expected-error@+1 {{rather than call makeStringAndClear on an rvalue, pass with a view [loplugin:stringview]}} + ConstructWithView(s.copy(1).makeStringAndClear()); +} +void makeStringAndClear(OStringBuffer s) +{ + call_view(s.makeStringAndClear()); + ConstructWithView(s.makeStringAndClear()); + call_view((&s)->makeStringAndClear()); + ConstructWithView((&s)->makeStringAndClear()); + // expected-error@+1 {{rather than call makeStringAndClear on an rvalue, pass with a view [loplugin:stringview]}} + call_view(std::move(s).makeStringAndClear()); + // expected-error@+1 {{rather than call makeStringAndClear on an rvalue, pass with a view [loplugin:stringview]}} + ConstructWithView(std::move(s).makeStringAndClear()); +} } namespace test2 @@ -101,49 +150,47 @@ void f4(OUString s1, OUString s2) void f5(char const* s1, sal_Int32 n1, char16_t const* s2, sal_Int32 n2, OString s3, OUString s4) { - // expected-error@+1 {{instead of an 'rtl::OString', pass a 'std::string_view' [loplugin:stringview]}} + // expected-error-re@+1 {{instead of an '{{(rtl::)?}}OString', pass a 'std::string_view' [loplugin:stringview]}} call_view(OString()); - // expected-error-re@+1 {{instead of an 'rtl::OString' constructed from a 'const char{{ ?}}[4]', pass a 'std::string_view' [loplugin:stringview]}} + // expected-error-re@+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' constructed from a 'const char', pass a 'std::string_view' (or an 'rtl::OStringChar') [loplugin:stringview]}} + // expected-error-re@+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' constructed from a 'const char *', pass a 'std::string_view' [loplugin:stringview]}} + // expected-error-re@+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' constructed from a 'const char *', pass a 'std::string_view' [loplugin:stringview]}} + // expected-error-re@+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' 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' constructed from a 'std::string_view' (aka 'basic_string_view<char>'), pass a 'std::string_view' [loplugin:stringview]}} + // expected-error-re@+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' constructed from a 'OStringNumber<int>', pass a 'std::string_view' [loplugin:stringview]}} + // expected-error-re@+1 {{instead of an {{'(rtl::)?}}OString' constructed from a {{'(rtl::)?StringNumber<char, 33>'|'OStringNumber<33>' \(aka 'StringNumber<char, 33ULL?>'\)}}, pass a 'std::string_view' [loplugin:stringview]}} call_view(OString(OString::number(0))); - // expected-error-re@+1 {{instead of an 'rtl::OString' constructed from a 'typename std::enable_if_t<ToStringHelper<OString>::allowOStringConcat && ToStringHelper<OString>::allowOStringConcat, OStringConcat<OString, OString>{{ ?}}>' (aka 'rtl::OStringConcat<rtl::OString, rtl::OString>'), pass a 'std::string_view' via 'rtl::OStringConcatenation' [loplugin:stringview]}} + // expected-error-re@+1 {{instead of an '{{(rtl::)?}}OString' constructed from a 'OStringConcat<{{(rtl::)?}}OString, {{(rtl::)?}}OString>' (aka 'StringConcat<char, rtl::OString, rtl::OString>'), pass a 'std::string_view' via 'rtl::Concat2View' [loplugin:stringview]}} call_view(OString(s3 + s3)); - // expected-error@+1 {{instead of an 'rtl::OUString', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error-re@+1 {{instead of an '{{(rtl::)?}}OUString', pass a 'std::u16string_view' [loplugin:stringview]}} call_view(OUString()); - // expected-error-re@+1 {{instead of an 'rtl::OUString' constructed from a 'const char{{ ?}}[4]', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error-re@+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-re@+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' constructed from a 'const char', pass a 'std::u16string_view' (or an 'rtl::OUStringChar') [loplugin:stringview]}} + // expected-error-re@+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", 3)); + // expected-error-re@+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' constructed from a 'const char16_t', pass a 'std::u16string_view' (or an 'rtl::OUStringChar') [loplugin:stringview]}} + // expected-error-re@+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' constructed from a 'const char16_t *', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error-re@+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' constructed from a 'const char16_t *', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error-re@+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]}} + // expected-error-re@+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' 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' constructed from a 'std::u16string_view' (aka 'basic_string_view<char16_t>'), pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error-re@+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' constructed from a 'OUStringNumber<int>', pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error-re@+1 {{instead of an '{{(rtl::)?}}OUString' constructed from a {{'(rtl::)?StringNumber<char16_t, 33>'|'OUStringNumber<33>' \(aka 'StringNumber<char16_t, 33ULL?>'\)}}, pass a 'std::u16string_view' [loplugin:stringview]}} call_view(OUString(OUString::number(0))); - // expected-error-re@+1 {{instead of an 'rtl::OUString' constructed from a 'typename std::enable_if_t<ToStringHelper<OUString>::allowOUStringConcat && ToStringHelper<OUString>::allowOUStringConcat, OUStringConcat<OUString, OUString>{{ ?}}>' (aka 'rtl::OUStringConcat<rtl::OUString, rtl::OUString>'), pass a 'std::u16string_view' via 'rtl::OUStringConcatenation' [loplugin:stringview]}} + // expected-error-re@+1 {{instead of an '{{(rtl::)?}}OUString' constructed from a 'OUStringConcat<{{(rtl::)?}}OUString, {{(rtl::)?}}OUString>' (aka 'StringConcat<char16_t, rtl::OUString, rtl::OUString>'), pass a 'std::u16string_view' via 'rtl::Concat2View' [loplugin:stringview]}} call_view(OUString(s4 + s4)); (void)(s3 == l1); @@ -158,10 +205,15 @@ 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' constructed from a 'std::u16string_view' (aka 'basic_string_view<char16_t>'), pass a 'std::u16string_view' [loplugin:stringview]}} + // expected-error-re@+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"))); - // 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]}} + // expected-error-re@+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]}} s += OUString(std::u16string_view(u"foo")); } +void f6(OUString s) +{ + // expected-error@+1 {{rather than getToken, pass with a view using o3tl::getToken() [loplugin:stringview]}} + s.getToken(1, ' ').toInt32(); +} /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/stringviewdangle.cxx b/compilerplugins/clang/test/stringviewdangle.cxx new file mode 100644 index 000000000000..0a8d2aa54b44 --- /dev/null +++ b/compilerplugins/clang/test/stringviewdangle.cxx @@ -0,0 +1,37 @@ +/* -*- 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 <string_view> +#include <utility> + +#include <rtl/strbuf.hxx> +#include <rtl/string.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.hxx> +#include <sal/types.h> + +namespace test1 +{ +OUString foo1(); +OUString& foo2(); +void f1() +{ + // expected-error@+1 {{view pointing into temporary i.e. dangling [loplugin:stringviewdangle]}} + std::u16string_view v = foo1(); + // expected-error@+1 {{view pointing into temporary i.e. dangling [loplugin:stringviewdangle]}} + v = foo1(); + + // no warning expected + std::u16string_view v2 = foo2(); + v2 = foo2(); +} +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/stringviewparam.cxx b/compilerplugins/clang/test/stringviewparam.cxx index f5f165804490..abb98797b1dc 100644 --- a/compilerplugins/clang/test/stringviewparam.cxx +++ b/compilerplugins/clang/test/stringviewparam.cxx @@ -19,7 +19,7 @@ #include "sal/types.h" void f1a(std::string_view); -// expected-error@+1 {{replace function parameter of type 'const rtl::OString &' with 'std::string_view' [loplugin:stringviewparam]}} +// expected-error-re@+1 {{replace function parameter of type 'const {{(rtl::)?}}OString &' with 'std::string_view' [loplugin:stringviewparam]}} char f1b(OString const& s) { f1a(s); @@ -32,7 +32,7 @@ char f1b(OString const& s) } void f2a(std::u16string_view); -// expected-error@+1 {{replace function parameter of type 'const rtl::OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} +// expected-error-re@+1 {{replace function parameter of type 'const {{(rtl::)?}}OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} sal_Unicode f2b(OUString const& s) { f2a(s); @@ -56,19 +56,19 @@ template <> void f5<OUString>(OUString const&) {} void f6([[maybe_unused]] OUString const&) {} bool f7( - // expected-error@+1 {{replace function parameter of type 'const rtl::OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} + // expected-error-re@+1 {{replace function parameter of type 'const {{(rtl::)?}}OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} const OUString& p1, - // expected-error@+1 {{replace function parameter of type 'const rtl::OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} + // expected-error-re@+1 {{replace function parameter of type 'const {{(rtl::)?}}OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} const OUString& p2) { return p1 == p2; } -// expected-error@+1 {{replace function parameter of type 'const rtl::OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} +// expected-error-re@+1 {{replace function parameter of type 'const {{(rtl::)?}}OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} bool f8(const OUString& p1, std::u16string_view p2) { return p1 == p2; } struct Converter { - // expected-error@+1 {{replace function parameter of type 'const rtl::OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} + // expected-error-re@+1 {{replace function parameter of type 'const {{(rtl::)?}}OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} static bool convertBool(bool& rBool, const OUString& rString) { rBool = rString == "true"; @@ -88,11 +88,26 @@ struct S10 } }; -// expected-error@+1 {{replace function parameter of type 'const rtl::OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} +// expected-error-re@+1 {{replace function parameter of type 'const {{(rtl::)?}}OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} void f11(const OUString& f11rString) { OUStringBuffer buf; buf.append(f11rString); } +// expected-error-re@+1 {{replace function parameter of type 'const {{(rtl::)?}}OUString &' with 'std::u16string_view' [loplugin:stringviewparam]}} +sal_uInt32 decimalStringToNumber(OUString const& str, sal_Int32 nStart, sal_Int32 nLength) +{ + sal_uInt32 result = 0; + for (sal_Int32 i = nStart; i < nStart + nLength;) + { + sal_uInt32 c = str.iterateCodePoints(&i); + sal_uInt32 value = 0; + if (c <= 0x0039) + value = c - 0x0030; + result = result * 10 + value; + } + return result; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/stringviewvar.cxx b/compilerplugins/clang/test/stringviewvar.cxx new file mode 100644 index 000000000000..4f5a8fd3def7 --- /dev/null +++ b/compilerplugins/clang/test/stringviewvar.cxx @@ -0,0 +1,65 @@ +/* -*- 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/. + */ + +#undef NDEBUG + +#include "sal/config.h" +#include <string_view> +#include "rtl/string.hxx" +#include "rtl/ustring.hxx" +#include "rtl/ustrbuf.hxx" +#include "sal/types.h" + +void f1(std::string_view sv) +{ + // expected-error-re@+1 {{replace var of type '{{(rtl::)?}}OString' with 'std::string_view' [loplugin:stringviewvar]}} + OString s1(sv); + (void)s1; +} + +void f2(const OString s1) +{ + // no warning expected + OString s2(s1); + (void)s2; +} + +std::string_view f3a(); +void f3() +{ + // expected-error-re@+1 {{replace var of type '{{(rtl::)?}}OString' with 'std::string_view' [loplugin:stringviewvar]}} + OString s1 = OString(f3a()); + (void)s1; +} + +void f4a(const OString&); +void f4(std::string_view sv) +{ + // no warning expected + OString s1(sv); + f4a(s1); +} + +void f5(std::string_view sv) +{ + // expected-error-re@+1 {{replace var of type '{{(rtl::)?}}OString' with 'std::string_view' [loplugin:stringviewvar]}} + OString s1(sv); + if (s1 == "xxxx") + f5(sv); +} + +void f6(std::u16string_view sv) +{ + // expected-error-re@+1 {{replace var of type '{{(rtl::)?}}OUString' with 'std::u16string_view' [loplugin:stringviewvar]}} + OUString s6; + s6 = sv; + (void)s6; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/trivialconstructor.cxx b/compilerplugins/clang/test/trivialconstructor.cxx new file mode 100644 index 000000000000..eed26f8bf305 --- /dev/null +++ b/compilerplugins/clang/test/trivialconstructor.cxx @@ -0,0 +1,58 @@ +/* -*- 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/. + */ + +struct S1 +{ + // expected-error@+1 {{no need for explicit constructor decl [loplugin:trivialconstructor]}} + S1() {} +}; + +struct S2 +{ + S2() {} + S2(int) {} +}; + +struct S3 +{ + S3() {} + template <typename T> S3(T); +}; + +template <typename> struct S4 +{ +#if !defined _MSC_VER +// expected-error@+2 {{no need for explicit constructor decl [loplugin:trivialconstructor]}} +#endif + S4() {} +}; + +template <typename> struct S5 +{ + S5() {} + S5(int); +}; + +template <typename> struct S6 +{ + S6() {} + template <typename T> S6(T); +}; + +struct S7 +{ + S7(int = 0) {} +}; + +struct S8 +{ + template <typename T> S8(T = 0) {} +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/trivialdestructor.cxx b/compilerplugins/clang/test/trivialdestructor.cxx new file mode 100644 index 000000000000..b6ba4e968193 --- /dev/null +++ b/compilerplugins/clang/test/trivialdestructor.cxx @@ -0,0 +1,57 @@ +/* -*- 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/. + */ + +struct S1 +{ + // expected-note@+1 {{previous declaration is here [loplugin:trivialdestructor]}} + ~S1(); +}; + +// expected-error@+1 {{no need for explicit destructor decl [loplugin:trivialdestructor]}} +S1::~S1() {} + +struct S2 +{ + // expected-note@+1 {{previous declaration is here [loplugin:trivialdestructor]}} + ~S2(); +}; + +// expected-error@+1 {{no need for explicit destructor decl [loplugin:trivialdestructor]}} +S2::~S2() = default; + +struct S3 +{ + ~S3() = delete; +}; + +struct S4 +{ + union { + int i; + float f; + }; + // expected-error@+1 {{no need for explicit destructor decl [loplugin:trivialdestructor]}} + ~S4() {} +}; + +struct Nontrivial +{ + ~Nontrivial(); +}; + +struct S5 +{ + union { + int i; + Nontrivial n; + }; + ~S5() {} +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/typeidcomparison.cxx b/compilerplugins/clang/test/typeidcomparison.cxx new file mode 100644 index 000000000000..31ab749a2496 --- /dev/null +++ b/compilerplugins/clang/test/typeidcomparison.cxx @@ -0,0 +1,41 @@ +/* -*- 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 <typeinfo> + +struct Base +{ + virtual ~Base(); +}; + +struct Derived : Base +{ +}; + +void good(Base* p) +{ + (void)(typeid(*p) == typeid(Derived)); + (void)(typeid(Derived) == typeid(*p)); + (void)(typeid(*p) != typeid(Derived)); + (void)(typeid(Derived) != typeid(*p)); +} + +void bad(Base* p) +{ + // expected-error@+1 {{comparison of type info of mixed pointer and non-pointer types 'Base *' and 'Derived' can never succeed [loplugin:typeidcomparison]}} + (void)(typeid(p) == typeid(Derived)); + // expected-error@+1 {{comparison of type info of mixed pointer and non-pointer types 'Derived' and 'Base *' can never succeed [loplugin:typeidcomparison]}} + (void)(typeid(Derived) == typeid(p)); + // expected-error@+1 {{comparison of type info of mixed pointer and non-pointer types 'Base *' and 'Derived' can never succeed [loplugin:typeidcomparison]}} + (void)(typeid(p) != typeid(Derived)); + // expected-error@+1 {{comparison of type info of mixed pointer and non-pointer types 'Derived' and 'Base *' can never succeed [loplugin:typeidcomparison]}} + (void)(typeid(Derived) != typeid(p)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/unnecessarygetstr.cxx b/compilerplugins/clang/test/unnecessarygetstr.cxx new file mode 100644 index 000000000000..bdb58cde2ef7 --- /dev/null +++ b/compilerplugins/clang/test/unnecessarygetstr.cxx @@ -0,0 +1,138 @@ +/* -*- 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 <ostream> +#include <sstream> +#include <string_view> +#include <string> + +#include <rtl/strbuf.hxx> +#include <rtl/string.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.hxx> +#include <sal/log.hxx> + +namespace test1 +{ +void f1(bool, const OString& s); +struct Foo +{ + void f1(bool, const OString& s); +}; +void test1(Foo& foo) +{ + OString s; + // expected-error@+1 {{unnecessary call to 'getStr' when passing to OString constructor [loplugin:unnecessarygetstr]}} + f1(true, s.getStr()); + // expected-error@+1 {{unnecessary call to 'getStr' when passing to OString constructor [loplugin:unnecessarygetstr]}} + foo.f1(true, s.getStr()); + // expected-error@+1 {{unnecessary call to 'getStr' when passing to OString constructor [loplugin:unnecessarygetstr]}} + foo.f1(true, OString::boolean(true).getStr()); + // expected-error@+1 {{unnecessary call to 'getStr' when passing to OString constructor [loplugin:unnecessarygetstr]}} + foo.f1(true, OString::number(12).getStr()); + + // avoid false + + OString aVal = "xx"; + OUString aCompText + = "xx" + OUString(aVal.getStr(), aVal.getLength(), RTL_TEXTENCODING_ASCII_US); + (void)aCompText; +} +} + +namespace test2 +{ +// call to param that takes string_view +void f2(bool, std::string_view); +void f2(bool, std::u16string_view); +struct Foo2 +{ + void f2(bool, std::string_view); + void f2(bool, std::u16string_view); +}; +void testOString(Foo2& foo) +{ + OString s; + // expected-error@+1 {{unnecessary call to 'getStr' when passing to string_view constructor [loplugin:unnecessarygetstr]}} + f2(true, s.getStr()); + // expected-error@+1 {{unnecessary call to 'getStr' when passing to string_view constructor [loplugin:unnecessarygetstr]}} + foo.f2(true, s.getStr()); + // expected-error@+1 {{unnecessary call to 'getStr' when passing to string_view constructor [loplugin:unnecessarygetstr]}} + foo.f2(true, OString::boolean(true).getStr()); + // expected-error@+1 {{unnecessary call to 'getStr' when passing to string_view constructor [loplugin:unnecessarygetstr]}} + foo.f2(true, OString::number(12).getStr()); +} +void testOUString(Foo2& foo) +{ + OUString s; + // expected-error@+1 {{unnecessary call to 'getStr' when passing to string_view constructor [loplugin:unnecessarygetstr]}} + f2(true, s.getStr()); + // expected-error@+1 {{unnecessary call to 'getStr' when passing to string_view constructor [loplugin:unnecessarygetstr]}} + foo.f2(true, s.getStr()); + // expected-error@+1 {{unnecessary call to 'getStr' when passing to string_view constructor [loplugin:unnecessarygetstr]}} + foo.f2(true, OUString::boolean(true).getStr()); + // expected-error@+1 {{unnecessary call to 'getStr' when passing to string_view constructor [loplugin:unnecessarygetstr]}} + foo.f2(true, OUString::number(12).getStr()); +} +} + +namespace test3 +{ +// call to param that takes string_view +void f2(bool, std::string_view); +struct Foo2 +{ + void f2(bool, std::string_view); +}; +void test3(Foo2& foo) +{ + std::string s; + // expected-error@+1 {{unnecessary call to 'c_str' when passing to string_view constructor [loplugin:unnecessarygetstr]}} + f2(true, s.c_str()); + // expected-error@+1 {{unnecessary call to 'c_str' when passing to string_view constructor [loplugin:unnecessarygetstr]}} + foo.f2(true, s.c_str()); +} +} + +namespace test4 +{ +void test() +{ + std::string s; + // expected-error@+1 {{unnecessary call to 'c_str' when passing to OUString::createFromAscii [loplugin:unnecessarygetstr]}} + OUString::createFromAscii(s.c_str()); +} +} + +namespace test5 +{ +void test(std::string v, OString o) +{ + // expected-error@+1 {{unnecessary call to 'c_str' when passing to string_view constructor [loplugin:unnecessarygetstr]}} + std::string_view s1(v.c_str()); + // expected-error@+1 {{unnecessary call to 'getStr' when passing to string constructor [loplugin:unnecessarygetstr]}} + std::string s2(o.getStr()); +} +} + +// no warning expected +namespace test6 +{ +void foo(const OString&); +void test(std::string v) { foo(v.c_str()); } +} + +// no warning expected +namespace test7 +{ +void test(const OString& v) { std::stringstream aStream(v.getStr()); } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/unnecessarylocking.cxx b/compilerplugins/clang/test/unnecessarylocking.cxx new file mode 100644 index 000000000000..a2319623140a --- /dev/null +++ b/compilerplugins/clang/test/unnecessarylocking.cxx @@ -0,0 +1,114 @@ +/* -*- 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 <mutex> +#include <osl/mutex.hxx> + +static std::mutex gSolarMutex; + +class SolarMutexGuard +{ + std::unique_lock<std::mutex> lock; + +public: + SolarMutexGuard() + : lock(gSolarMutex) + { + } +}; + +namespace test1 +{ +struct Foo +{ + int m_foo; + int bar1() + // expected-error@+1 {{unnecessary locking [loplugin:unnecessarylocking]}} + { + SolarMutexGuard guard; + return 1; + } + // no warning expected + int bar2() + { + SolarMutexGuard guard; + return m_foo; + } +}; +} + +namespace test2 +{ +int free_function() { return 1; } + +struct Foo +{ + std::mutex m_aMutex; + osl::Mutex m_aOslMutex; + int m_foo; + + int bar1() + // expected-error@+1 {{unnecessary locking [loplugin:unnecessarylocking]}} + { + std::unique_lock guard(m_aMutex); + return 1; + } + int bar2() + // expected-error@+1 {{unnecessary locking [loplugin:unnecessarylocking]}} + { + std::scoped_lock guard(m_aMutex); + return 1; + } + // no warning expected + int bar3() + { + std::scoped_lock guard(m_aMutex); + return m_foo; + } + int bar4() + // expected-error@+1 {{unnecessary locking [loplugin:unnecessarylocking]}} + { + ::osl::Guard<::osl::Mutex> aGuard(m_aOslMutex); + return 1; + } + int bar5() + { + // expected-error@+1 {{unnecessary locking [loplugin:unnecessarylocking]}} + { + std::unique_lock guard(m_aMutex); + return free_function(); + } + } + osl::Mutex& getOslMutex() { return m_aOslMutex; } + int bar6() + // expected-error@+1 {{unnecessary locking [loplugin:unnecessarylocking]}} + { + ::osl::Guard<::osl::Mutex> aGuard(getOslMutex()); + return 1; + } +}; +} + +// Calling anything on VCLUnoHelper means we need the SolarMutex +class VCLUnoHelper +{ +public: + static int CreateToolkit(); +}; +namespace test4 +{ +// no warning expected +void bar1() +{ + SolarMutexGuard guard; + VCLUnoHelper::CreateToolkit(); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/unnecessaryparen.cxx b/compilerplugins/clang/test/unnecessaryparen.cxx index ccc2b4ce6556..89ca84da6ab2 100644 --- a/compilerplugins/clang/test/unnecessaryparen.cxx +++ b/compilerplugins/clang/test/unnecessaryparen.cxx @@ -7,6 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <cstddef> #include <memory> #include <string> #include <rtl/ustring.hxx> @@ -34,6 +35,13 @@ template <> struct typed_flags<BrowseMode> : is_typed_flags<BrowseMode, 0xf> }; } +void f(char const *); +char const * operator ""_s1(char const *, std::size_t); +#if __cplusplus >= 202002L +struct Str { constexpr Str(char const *) {} }; +template<Str> char const * operator ""_s2(); +#endif + int main() { int x = 1; @@ -115,6 +123,21 @@ int main() (void)nBits; OUString::number((v2+1)); // expected-error {{parentheses immediately inside single-arg call [loplugin:unnecessaryparen]}} + + (void) ("foo"); // expected-error {{unnecessary parentheses around single-token string literal [loplugin:unnecessaryparen]}} + (void) ("foo" "bar"); + f(("foo")); // expected-error {{parentheses immediately inside single-arg call [loplugin:unnecessaryparen]}} + f(("foo" "bar")); + (void) ("foo"_s1); // expected-error {{unnecessary parentheses around single-token string literal [loplugin:unnecessaryparen]}} + (void) ("foo" "bar"_s1); + f(("foo"_s1)); // expected-error {{parentheses immediately inside single-arg call [loplugin:unnecessaryparen]}} + f(("foo" "bar"_s1)); +#if __cplusplus >= 202002L + (void) ("foo"_s2); //TODO: expected error {{unnecessary parentheses around single-token string literal [loplugin:unnecessaryparen]}} + (void) ("foo" "bar"_s2); + f(("foo"_s2)); // TODO: expected error {{parentheses immediately inside single-arg call [loplugin:unnecessaryparen]}} + f(("foo" "bar"_s2)); +#endif }; struct B { operator bool() const; }; diff --git a/compilerplugins/clang/test/unoaggregation.cxx b/compilerplugins/clang/test/unoaggregation.cxx new file mode 100644 index 000000000000..01e0dd832e9d --- /dev/null +++ b/compilerplugins/clang/test/unoaggregation.cxx @@ -0,0 +1,42 @@ +/* -*- 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 <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XMain.hpp> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/implbase1.hxx> +#include <sal/types.h> + +class Base : public cppu::WeakAggImplHelper1<css::lang::XInitialization> +{ +public: + void SAL_CALL initialize(css::uno::Sequence<css::uno::Any> const& aArguments) override; +}; + +class Good : public Base, public css::lang::XMain +{ +public: + css::uno::Any SAL_CALL queryInterface(css::uno::Type const& aType) override + { + return Base::queryInterface(aType); + } +}; + +class Bad : public cppu::ImplInheritanceHelper<Base, css::lang::XMain> +{ +public: + sal_Int32 SAL_CALL run(css::uno::Sequence<OUString> const& aArguments) override; +}; + +// expected-error@cppuhelper/implbase.hxx:* {{'ImplInheritanceHelper<Base, com::sun::star::lang::XMain>' derives from XAggregation, but its implementation of queryInterface does not delegate to an appropriate base class queryInterface [loplugin:unoaggregation]}} +Bad bad; //make sure Bad's base cppu::ImplInheritanceHelper<Base, css::lang::XMain> is instantiated + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/unoany.cxx b/compilerplugins/clang/test/unoany.cxx index 15c4b3ae2436..b5d91007f80f 100644 --- a/compilerplugins/clang/test/unoany.cxx +++ b/compilerplugins/clang/test/unoany.cxx @@ -22,7 +22,6 @@ int main() css::uno::Any b; a = b; a = getAny(); - a = css::uno::makeAny(true); // expected-error {{unnecessary copy, rather use <<= operator directly with the 'makeAny' argument [loplugin:unoany]}} a = css::uno::Any(true); // expected-error {{unnecessary copy, rather use <<= operator directly with the 'Any' constructor argument [loplugin:unoany]}} } diff --git a/compilerplugins/clang/test/unreffun.cxx b/compilerplugins/clang/test/unreffun.cxx index b61171a87c84..315c699b7748 100644 --- a/compilerplugins/clang/test/unreffun.cxx +++ b/compilerplugins/clang/test/unreffun.cxx @@ -7,6 +7,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "config_clang.h" + #include "unreffun.hxx" template <typename> struct S @@ -36,4 +38,20 @@ void l() // expected-error {{Unreferenced externally visible function definition { } +void m() +{ +// The below produced a false "Unreferenced externally invisible function definition" for Local::f +// prior to <https://github.com/llvm/llvm-project/commit/d812488d3c54c07f24d4bef79e329f17e7f19c3b> +// "Call MarkVirtualMembersReferenced on an actual class definition" in Clang 17: +#if CLANG_VERSION >= 170000 + struct Local; +#endif + struct Local + { + virtual void f() {} + }; + Local x; + (void)x; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/unreffun.hxx b/compilerplugins/clang/test/unreffun.hxx index a209dd7b6437..7eea5233fde7 100644 --- a/compilerplugins/clang/test/unreffun.hxx +++ b/compilerplugins/clang/test/unreffun.hxx @@ -13,4 +13,6 @@ void f(); extern void i(); +void m(); + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/unusedfields.cxx b/compilerplugins/clang/test/unusedfields.cxx index 6ff9189eab27..c936460bbea5 100644 --- a/compilerplugins/clang/test/unusedfields.cxx +++ b/compilerplugins/clang/test/unusedfields.cxx @@ -6,14 +6,12 @@ * 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 "config_clang.h" -// CLANG_VERSION = older versions of clang need something different in getParentFunctionDecl -// WIN32 = TODO, see corresponding TODO in compilerplugins/clang/unusedfields.cxx -#if CLANG_VERSION < 110000 || defined _WIN32 +#if defined _WIN32 // TODO, see corresponding TODO in compilerplugins/clang/unusedfields.cxx // expected-no-diagnostics #else +#include <map> #include <memory> #include <vector> #include <ostream> @@ -380,6 +378,49 @@ namespace TouchFromOutsideAnalysis1 }; }; +namespace WriteOnlyAnalysis4 +{ + struct ImplTabCtrlData + // expected-error@-1 {{read maLayoutLineToPageId [loplugin:unusedfields]}} + // expected-error@-2 {{outside maLayoutLineToPageId [loplugin:unusedfields]}} + { + std::map< int, int > maLayoutLineToPageId; + }; + class TabControl + // expected-error@-1 {{read mpTabCtrlData [loplugin:unusedfields]}} + // expected-error@-2 {{outside-constructor mpTabCtrlData [loplugin:unusedfields]}} + { + std::unique_ptr<ImplTabCtrlData> mpTabCtrlData; + + void foo(int nLine, int& rPageId) + { + rPageId = mpTabCtrlData->maLayoutLineToPageId[ nLine ]; + } + }; +} + +namespace WriteOnlyAnalysis5 +{ + struct ImplTabCtrlData + // expected-error@-1 {{read maLayoutLineToPageId [loplugin:unusedfields]}} + // expected-error@-2 {{write maLayoutLineToPageId [loplugin:unusedfields]}} + // expected-error@-3 {{outside maLayoutLineToPageId [loplugin:unusedfields]}} + { + std::map< int, int > maLayoutLineToPageId; + }; + class TabControl + // expected-error@-1 {{read mpTabCtrlData [loplugin:unusedfields]}} + // expected-error@-2 {{outside-constructor mpTabCtrlData [loplugin:unusedfields]}} + { + std::unique_ptr<ImplTabCtrlData> mpTabCtrlData; + + void foo(int nLine, int nPageId) + { + mpTabCtrlData->maLayoutLineToPageId[ nLine ] = nPageId; + } + }; +} + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/unusedmember.cxx b/compilerplugins/clang/test/unusedmember.cxx index a495b786919e..90f3051b98ee 100644 --- a/compilerplugins/clang/test/unusedmember.cxx +++ b/compilerplugins/clang/test/unusedmember.cxx @@ -7,6 +7,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <cstddef> + namespace Enum { namespace @@ -223,6 +225,31 @@ void f() } } +namespace Offsetof +{ +namespace +{ +struct S +{ + int i; +}; +} +void f() { (void)offsetof(S, i); } +} + +namespace OffsetofTemplate +{ +namespace +{ +template <typename> struct S +{ + int i; +}; +template <typename T> void f1() { (void)offsetof(T, i); } +} +void f() { f1<S<void>>(); } +} + int main() { (void)&Enum::f; @@ -233,6 +260,8 @@ int main() (void)&Aligned::f; (void)&Bases::f; (void)&Unnamed::f; + (void)&Offsetof::f; + (void)&OffsetofTemplate::f; } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/unusedvariablecheck.cxx b/compilerplugins/clang/test/unusedvariablecheck.cxx index c5b2a04d89fe..b020fba3eb4e 100644 --- a/compilerplugins/clang/test/unusedvariablecheck.cxx +++ b/compilerplugins/clang/test/unusedvariablecheck.cxx @@ -12,17 +12,27 @@ #include <list> #include <string> #include <vector> +#include <memory> namespace { template <typename T> using Vec = std::vector<T>; } +struct S : std::unique_ptr<int> +{ + S(int* = nullptr); +}; + int main() { std::list<int> v1; // expected-error {{unused variable 'v1' [loplugin:unusedvariablecheck]}} std::string v2; // expected-error {{unused variable 'v2' [loplugin:unusedvariablecheck]}} Vec<int> v3; // expected-error {{unused variable 'v3' [loplugin:unusedvariablecheck]}} + std::unique_ptr<int> + v4; // expected-error {{unused variable 'v4' [loplugin:unusedvariablecheck]}} + S v5; // expected-error {{unused variable 'v5' [loplugin:unusedvariablecheck]}} + S v6(nullptr); } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/test/unusedvarsglobal.cxx b/compilerplugins/clang/test/unusedvarsglobal.cxx index 58c18d0de84c..e7a0316d497d 100644 --- a/compilerplugins/clang/test/unusedvarsglobal.cxx +++ b/compilerplugins/clang/test/unusedvarsglobal.cxx @@ -6,11 +6,8 @@ * 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 "config_clang.h" -// CLANG_VERSION = older versions of clang need something different in getParentFunctionDecl -// WIN32 = TODO, see corresponding TODO in compilerplugins/clang/unusedfields.cxx -#if CLANG_VERSION < 110000 || defined _WIN32 +#if defined _WIN32 // TODO, see corresponding TODO in compilerplugins/clang/unusedfields.cxx // expected-no-diagnostics #else diff --git a/compilerplugins/clang/test/weakbase.cxx b/compilerplugins/clang/test/weakbase.cxx index a59a5372891e..3d5284ef543c 100644 --- a/compilerplugins/clang/test/weakbase.cxx +++ b/compilerplugins/clang/test/weakbase.cxx @@ -25,10 +25,59 @@ struct Foo2 : public tools::WeakBase virtual ~Foo2(); }; -// expected-error@+1 {{multiple copies of WeakBase, through inheritance paths Bar->Foo1->WeakBase, Bar->Foo2->WeakBase [loplugin:weakbase]}} +// expected-error@+1 {{found multiple copies of tools::WeakBase, through inheritance paths Bar->Foo1->WeakBase, Bar->Foo2->WeakBase [loplugin:weakbase]}} struct Bar : public Foo1, public Foo2 { virtual ~Bar(); }; +namespace cppu +{ +class OWeakObject +{ +}; +} + +namespace test2 +{ +class Foo1 : public cppu::OWeakObject +{ +}; +class Foo2 : public cppu::OWeakObject +{ +}; +// expected-error@+1 {{found multiple copies of cppu::OWeakObject, through inheritance paths Foo3->Foo1->OWeakObject, Foo3->Foo2->OWeakObject [loplugin:weakbase]}} +class Foo3 : public Foo1, public Foo2 +{ +}; +} + +namespace test3 +{ +class Foo1 : public virtual cppu::OWeakObject +{ +}; +class Foo2 : public virtual cppu::OWeakObject +{ +}; +// no warning expected +class Foo3 : public Foo1, public Foo2 +{ +}; +} + +namespace test4 +{ +class Foo1 : public cppu::OWeakObject +{ +}; +class Foo2 : public virtual cppu::OWeakObject +{ +}; +// expected-error@+1 {{found one virtual base and one or more normal bases of cppu::OWeakObject, through inheritance paths Foo3->Foo1->OWeakObject, Foo3->Foo2->OWeakObject [loplugin:weakbase]}} +class Foo3 : public Foo1, public Foo2 +{ +}; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |