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

Reply via email to