aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorDavid Bolvansky <david.bolvansky@gmail.com>2018-11-01 16:26:10 +0000
committerDavid Bolvansky <david.bolvansky@gmail.com>2018-11-01 16:26:10 +0000
commitb8dc05260c7da2260c0f48a14f880b062785d09f (patch)
tree967290019519f1ff70549f0e31ec29b7c6e98fae /clang/lib
parentd686dbbc7c24a81a46f61733d48df866f2874e24 (diff)
downloadllvm-b8dc05260c7da2260c0f48a14f880b062785d09f.zip
llvm-b8dc05260c7da2260c0f48a14f880b062785d09f.tar.gz
llvm-b8dc05260c7da2260c0f48a14f880b062785d09f.tar.bz2
[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 llvm-svn: 345847
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp32
1 files changed, 30 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ecda5be..d7fc1aa 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -8726,6 +8726,32 @@ static void checkArithmeticNull(Sema &S, ExprResult &LHS, ExprResult &RHS,
<< 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::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS,
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::ActOnObjCAvailabilityCheckExpr(
return new (Context)
ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy);
-}
+} \ No newline at end of file