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); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits