diff options
author | David Bolvansky <david.bolvansky@gmail.com> | 2018-11-01 16:26:10 +0000 |
---|---|---|
committer | David Bolvansky <david.bolvansky@gmail.com> | 2018-11-01 16:26:10 +0000 |
commit | b8dc05260c7da2260c0f48a14f880b062785d09f (patch) | |
tree | 967290019519f1ff70549f0e31ec29b7c6e98fae /clang/lib | |
parent | d686dbbc7c24a81a46f61733d48df866f2874e24 (diff) | |
download | llvm-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.cpp | 32 |
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 |