fiesh created this revision. fiesh added a reviewer: aaron.ballman. fiesh added a project: clang-tools-extra. Herald added subscribers: cfe-commits, kbarton, nemanjai. Herald added a project: clang. fiesh requested review of this revision.
As system headers are in general out of reach, it makes no sense to warn on pointer decays happening in them. This is a reboot of https://reviews.llvm.org/D31130 It is essentially unchanged, only updated to the new repository as well as minor API changes. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D88833 Files: clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp clang-tools-extra/test/clang-tidy/checkers/Inputs/cppcoreguidelines-pro-bounds-array-to-pointer-decay/macro.h clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp +++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp @@ -1,4 +1,6 @@ -// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-array-to-pointer-decay %t +// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-array-to-pointer-decay %t -- -- -isystem%S/Inputs/cppcoreguidelines-pro-bounds-array-to-pointer-decay + +#include <macro.h> #include <stddef.h> namespace gsl { @@ -8,7 +10,7 @@ template <class U, size_t N> array_view(U (&arr)[N]); }; -} +} // namespace gsl void pointerfun(int *p); void arrayfun(int p[]); @@ -29,9 +31,9 @@ gsl::array_view<int> av(a); arrayviewfun(av); // OK - int i = a[0]; // OK - int j = a[(1 + 2)];// OK - pointerfun(&a[0]); // OK + int i = a[0]; // OK + int j = a[(1 + 2)]; // OK + pointerfun(&a[0]); // OK for (auto &e : a) // OK, iteration internally decays array to pointer e = 1; @@ -41,11 +43,53 @@ return "clang"; // OK, decay string literal to pointer } const char *g2() { - return ("clang"); // OK, ParenExpr hides the literal-pointer decay + return ("clang"); // OK, ParenExpr hides the literal-pointer decay } void f2(void *const *); void bug25362() { void *a[2]; - f2(static_cast<void *const*>(a)); // OK, explicit cast + f2(static_cast<void *const *>(a)); // OK, explicit cast +} + +void user_fn_decay_str(const char *); +void user_fn_decay_int_array(const int *); +void bug32239() { + sys_macro_with_pretty_function_string_decay; // Ok + sys_macro_with_sys_string_decay; // Ok + sys_macro_with_sys_int_array_decay; // Ok + + sys_fn_decay_str(__PRETTY_FUNCTION__); // Ok + + sys_fn_decay_str(SYS_STRING); // Not Ok - should it be ok? + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay] + + sys_fn_decay_int_array(SYS_INT_ARRAY); // Not Ok + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay] + + user_code_in_sys_macro(sys_fn_decay_str(__PRETTY_FUNCTION__)); // Ok + + user_code_in_sys_macro(sys_fn_decay_str(SYS_STRING)); // Not Ok - should it be ok? + // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay] + + user_code_in_sys_macro(sys_fn_decay_int_array(SYS_INT_ARRAY)); // Not Ok + // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay] + + const char UserString[1] = ""; + decay_to_char_pointer_in_macro(UserString); // Not Ok + // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay] + + decay_to_char_pointer_in_macro(__PRETTY_FUNCTION__); // Ok + + int a[5]; + decay_to_int_pointer_in_macro(a); // Not Ok + // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay] + + user_fn_decay_str(__PRETTY_FUNCTION__); // Ok + + user_fn_decay_str(SYS_STRING); // Not Ok - should it be ok? + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay] + + user_fn_decay_int_array(SYS_INT_ARRAY); // Not ok + // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay] } Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/cppcoreguidelines-pro-bounds-array-to-pointer-decay/macro.h =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/cppcoreguidelines-pro-bounds-array-to-pointer-decay/macro.h @@ -0,0 +1,14 @@ +const char SYS_STRING[2] = "s"; +const int SYS_INT_ARRAY[2] = {0, 0}; + +void sys_fn_decay_str(const char *); +void sys_fn_decay_int_array(const int *); + +#define sys_macro_with_pretty_function_string_decay sys_fn_decay_str(__PRETTY_FUNCTION__) +#define sys_macro_with_sys_string_decay sys_fn_decay_str(SYS_STRING) +#define sys_macro_with_sys_int_array_decay sys_fn_decay_int_array(SYS_INT_ARRAY) + +#define user_code_in_sys_macro(expr) expr; + +#define decay_to_char_pointer_in_macro(expr) sys_fn_decay_str(expr) +#define decay_to_int_pointer_in_macro(expr) sys_fn_decay_int_array(expr) Index: clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp +++ clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp @@ -46,29 +46,49 @@ return InnerMatcher.matches(*E, Finder, Builder); } + +AST_MATCHER(ImplicitCastExpr, isArrayToPointerDecay) { + return Node.getCastKind() == CK_ArrayToPointerDecay; +} + +AST_MATCHER(ImplicitCastExpr, sysSymbolDecayInSysHeader) { + auto &SM = Finder->getASTContext().getSourceManager(); + if (!SM.isInSystemMacro(Node.getBeginLoc())) { + return false; + } + + if (const auto *SymbolDeclRef = dyn_cast<DeclRefExpr>(Node.getSubExpr())) { + const ValueDecl *SymbolDecl = SymbolDeclRef->getDecl(); + if (SymbolDecl && SM.isInSystemHeader(SymbolDecl->getLocation())) + return true; + } + return false; +} } // namespace void ProBoundsArrayToPointerDecayCheck::registerMatchers(MatchFinder *Finder) { - // The only allowed array to pointer decay + // We only allowed array to pointer decays // 1) just before array subscription // 2) inside a range-for over an array // 3) if it converts a string literal to a pointer + // 4) if it is caused by a system macro Finder->addMatcher( - traverse(ast_type_traits::TK_AsIs, - implicitCastExpr( - unless(hasParent(arraySubscriptExpr())), - unless(hasParentIgnoringImpCasts(explicitCastExpr())), - unless(isInsideOfRangeBeginEndStmt()), - unless(hasSourceExpression(ignoringParens(stringLiteral())))) - .bind("cast")), + traverse( + ast_type_traits::TK_AsIs, + implicitCastExpr( + isArrayToPointerDecay(), unless(hasParent(arraySubscriptExpr())), + unless(hasParentIgnoringImpCasts(explicitCastExpr())), + unless(isInsideOfRangeBeginEndStmt()), + unless(hasSourceExpression(ignoringParens(stringLiteral()))), + unless(hasSourceExpression(ignoringParens(predefinedExpr()))), + unless(sysSymbolDecayInSysHeader())) + .bind("cast")), this); } void ProBoundsArrayToPointerDecayCheck::check( const MatchFinder::MatchResult &Result) { const auto *MatchedCast = Result.Nodes.getNodeAs<ImplicitCastExpr>("cast"); - if (MatchedCast->getCastKind() != CK_ArrayToPointerDecay) - return; diag(MatchedCast->getExprLoc(), "do not implicitly decay an array into a " "pointer; consider using gsl::array_view or "
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits