r345847 - [Diagnostics] Implement -Wsizeof-pointer-div

David Bolvansky via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 1 09:26:10 PDT 2018


Author: xbolva00
Date: Thu Nov  1 09:26:10 2018
New Revision: 345847

URL: http://llvm.org/viewvc/llvm-project?rev=345847&view=rev
Log:
[Diagnostics] Implement -Wsizeof-pointer-div 

Summary:
void test(int *arr) {
    int arr_len = sizeof(arr) / sizeof(*arr);  // warn, incorrect way to compute number of array elements
}

Enabled under -Wall (same behaviour as GCC)

Reviewers: rsmith, MTC, aaron.ballman

Reviewed By: aaron.ballman

Subscribers: MTC, thakis, jfb, cfe-commits

Differential Revision: https://reviews.llvm.org/D52949

Added:
    cfe/trunk/test/Sema/div-sizeof-ptr.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=345847&r1=345846&r2=345847&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Nov  1 09:26:10 2018
@@ -3294,6 +3294,10 @@ def warn_address_of_reference_null_compa
   InGroup<TautologicalUndefinedCompare>;
 def note_reference_is_return_value : Note<"%0 returns a reference">;
 
+def warn_division_sizeof_ptr : Warning<
+  "'%0' will return the size of the pointer, not the array itself">,
+  InGroup<DiagGroup<"sizeof-pointer-div">>;
+
 def note_function_warning_silence : Note<
     "prefix with the address-of operator to silence this warning">;
 def note_function_to_function_call : Note<

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=345847&r1=345846&r2=345847&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Nov  1 09:26:10 2018
@@ -8726,6 +8726,32 @@ static void checkArithmeticNull(Sema &S,
       << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
 }
 
+static void DiagnoseDivisionSizeofPointer(Sema &S, Expr *LHS, Expr *RHS,
+                                          SourceLocation Loc) {
+  const auto *LUE = dyn_cast<UnaryExprOrTypeTraitExpr>(LHS);
+  const auto *RUE = dyn_cast<UnaryExprOrTypeTraitExpr>(RHS);
+  if (!LUE || !RUE)
+    return;
+  if (LUE->getKind() != UETT_SizeOf || LUE->isArgumentType() ||
+      RUE->getKind() != UETT_SizeOf)
+    return;
+
+  QualType LHSTy = LUE->getArgumentExpr()->IgnoreParens()->getType();
+  QualType RHSTy;
+
+  if (RUE->isArgumentType())
+    RHSTy = RUE->getArgumentType();
+  else
+    RHSTy = RUE->getArgumentExpr()->IgnoreParens()->getType();
+
+  if (!LHSTy->isPointerType() || RHSTy->isPointerType())
+    return;
+  if (LHSTy->getPointeeType() != RHSTy)
+    return;
+
+  S.Diag(Loc, diag::warn_division_sizeof_ptr) << LHS << LHS->getSourceRange();
+}
+
 static void DiagnoseBadDivideOrRemainderValues(Sema& S, ExprResult &LHS,
                                                ExprResult &RHS,
                                                SourceLocation Loc, bool IsDiv) {
@@ -8756,8 +8782,10 @@ QualType Sema::CheckMultiplyDivideOperan
 
   if (compType.isNull() || !compType->isArithmeticType())
     return InvalidOperands(Loc, LHS, RHS);
-  if (IsDiv)
+  if (IsDiv) {
     DiagnoseBadDivideOrRemainderValues(*this, LHS, RHS, Loc, IsDiv);
+    DiagnoseDivisionSizeofPointer(*this, LHS.get(), RHS.get(), Loc);
+  }
   return compType;
 }
 
@@ -16603,4 +16631,4 @@ ExprResult Sema::ActOnObjCAvailabilityCh
 
   return new (Context)
       ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy);
-}
+}
\ No newline at end of file

Added: cfe/trunk/test/Sema/div-sizeof-ptr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/div-sizeof-ptr.cpp?rev=345847&view=auto
==============================================================================
--- cfe/trunk/test/Sema/div-sizeof-ptr.cpp (added)
+++ cfe/trunk/test/Sema/div-sizeof-ptr.cpp Thu Nov  1 09:26:10 2018
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 %s -verify -Wsizeof-pointer-div -fsyntax-only
+
+template <typename Ty, int N>
+int f(Ty (&Array)[N]) {
+  return sizeof(Array) / sizeof(Ty); // Should not warn
+}
+
+void test(int *p, int **q) {
+  int a1 = sizeof(p) / sizeof(*p);   // expected-warning {{'sizeof (p)' will return the size of the pointer, not the array itself}}
+  int a2 = sizeof p / sizeof *p;     // expected-warning {{'sizeof p' will return the size of the pointer, not the array itself}}
+  int a3 = sizeof(*q) / sizeof(**q); // expected-warning {{'sizeof (*q)' will return the size of the pointer, not the array itself}}
+  int a4 = sizeof(p) / sizeof(int);  // expected-warning {{'sizeof (p)' will return the size of the pointer, not the array itself}}
+  int a5 = sizeof(p) / sizeof(p[0]); // expected-warning {{'sizeof (p)' will return the size of the pointer, not the array itself}}
+
+  // Should not warn
+  int b1 = sizeof(int *) / sizeof(int);
+  int b2 = sizeof(p) / sizeof(p);
+  int b3 = sizeof(*q) / sizeof(q);
+  int b4 = sizeof(p) / sizeof(char);
+
+  int arr[10];
+  int b5 = sizeof(arr) / sizeof(*arr);
+  int b6 = sizeof(arr) / sizeof(arr[0]);
+  int b7 = sizeof(arr) / sizeof(int);
+
+  int arr2[10][12];
+  int b8 = sizeof(arr2) / sizeof(*arr2);
+}




More information about the cfe-commits mailing list