diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp index a1494a095f5b6..4c48fc923fa87 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp @@ -15,16 +15,13 @@ using namespace clang::ast_matchers; namespace clang::tidy::cppcoreguidelines { void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - const auto AllPointerTypes = - anyOf(hasType(pointerType()), + anyOf(hasType(hasUnqualifiedDesugaredType(pointerType())), hasType(autoType( hasDeducedType(hasUnqualifiedDesugaredType(pointerType())))), hasType(decltypeType(hasUnderlyingType(pointerType())))); - // Flag all operators +, -, +=, -=, ++, -- that result in a pointer + // Flag all operators +, -, +=, -= that result in a pointer Finder->addMatcher( binaryOperator( hasAnyOperatorName("+", "-", "+=", "-="), AllPointerTypes, @@ -32,8 +29,12 @@ void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) { .bind("expr"), this); + // Flag all operators ++, -- that result in a pointer Finder->addMatcher( - unaryOperator(hasAnyOperatorName("++", "--"), hasType(pointerType())) + unaryOperator(hasAnyOperatorName("++", "--"), + hasType(hasUnqualifiedDesugaredType(pointerType())), + unless(hasUnaryOperand( + ignoringImpCasts(declRefExpr(to(isImplicit())))))) .bind("expr"), this); diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h index 67f7d1bf9dd69..3466c72a769e9 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h @@ -23,6 +23,9 @@ class ProBoundsPointerArithmeticCheck : public ClangTidyCheck { public: ProBoundsPointerArithmeticCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 579fca54924d5..a19bf190d85f2 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -166,6 +166,10 @@ Changes in existing checks ` check by fixing false positives when a function name is just prefixed with a targeted function name. +- Improved :doc:`cppcoreguidelines-pro-bounds-pointer-arithmetic + ` check by + fixing false negatives when pointer arithmetic was used through type aliases. + - Improved :doc:`misc-const-correctness ` check by adding the option `AllowedTypes`, that excludes specified types from const-correctness diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-pr36489.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-pr36489.cpp index faab2a1ccf0e1..b3d3fab9c5409 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-pr36489.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-pr36489.cpp @@ -1,11 +1,14 @@ // RUN: %check_clang_tidy -std=c++14-or-later %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t // Fix PR36489 and detect auto-deduced value correctly. +typedef char* charPtr; + char *getPtr(); auto getPtrAuto() { return getPtr(); } decltype(getPtr()) getPtrDeclType(); decltype(auto) getPtrDeclTypeAuto() { return getPtr(); } auto getPtrWithTrailingReturnType() -> char *; +charPtr getCharPtr() { return getPtr(); } void auto_deduction_binary() { auto p1 = getPtr() + 1; @@ -28,6 +31,10 @@ void auto_deduction_binary() { // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: do not use pointer arithmetic auto *p9 = getPtrDeclTypeAuto() + 1; // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: do not use pointer arithmetic + auto p10 = getCharPtr() + 1; + // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not use pointer + auto* p11 = getCharPtr() + 1; + // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not use pointer arithmetic } void auto_deduction_subscript() { @@ -50,4 +57,6 @@ void auto_deduction_subscript() { // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic auto p8 = getPtrDeclTypeAuto()[9]; // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic + auto p9 = getCharPtr()[10]; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic } diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic.cpp index 7cbc6ddf96ab6..b1534eeb36827 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic.cpp @@ -4,10 +4,13 @@ enum E { ENUM_LITERAL = 1 }; +typedef int* IntPtr; + int i = 4; int j = 1; int *p = 0; int *q = 0; +IntPtr ip = 0; void fail() { q = p + 4; @@ -50,6 +53,32 @@ void fail() { i = p[1]; // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic + + p = ip + 1; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: do not use pointer arithmetic + ip++; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic + i = ip[1]; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic +} + +template +void template_fail() { + T* p; + T* q; + + p = q + 1; + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic + q = p - 1; + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic + p++; + // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic + i = p[1]; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic +} + +void instantiate() { + template_fail(); } struct S {