diff options
| author | Erik Pilkington <erik.pilkington@gmail.com> | 2019-01-25 20:52:45 +0000 |
|---|---|---|
| committer | Erik Pilkington <erik.pilkington@gmail.com> | 2019-01-25 20:52:45 +0000 |
| commit | 8bed74ba517465e2d7f90f8df6aaff418d771006 (patch) | |
| tree | 2367ab0c3008a145d9048e77e2addc722f8c6e03 | |
| parent | 890a8e575f5b0d73711338357f204d95055a1023 (diff) | |
| download | bcm5719-llvm-8bed74ba517465e2d7f90f8df6aaff418d771006.tar.gz bcm5719-llvm-8bed74ba517465e2d7f90f8df6aaff418d771006.zip | |
[Sema] Improve a -Warray-bounds diagnostic
Fix a bug where we would compare array sizes with incompatible
element types, and look through explicit casts.
rdar://44800168
Differential revision: https://reviews.llvm.org/D57064
llvm-svn: 352239
| -rw-r--r-- | clang/include/clang/AST/ASTContext.h | 10 | ||||
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 24 | ||||
| -rw-r--r-- | clang/test/Sema/static-array.c | 12 |
4 files changed, 41 insertions, 8 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index c838018c9f2..fe52f818ea4 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2088,6 +2088,16 @@ public: CharUnits getTypeSizeInChars(QualType T) const; CharUnits getTypeSizeInChars(const Type *T) const; + Optional<CharUnits> getTypeSizeInCharsIfKnown(QualType Ty) const { + if (Ty->isIncompleteType() || Ty->isDependentType()) + return None; + return getTypeSizeInChars(Ty); + } + + Optional<CharUnits> getTypeSizeInCharsIfKnown(const Type *Ty) const { + return getTypeSizeInCharsIfKnown(QualType(Ty, 0)); + } + /// Return the ABI-specified alignment of a (complete) type \p T, in /// bits. unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; } diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index b1cd8f7046b..d1d99876c31 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7841,7 +7841,8 @@ def warn_format_mix_positional_nonpositional_args : Warning< "cannot mix positional and non-positional arguments in format string">, InGroup<Format>; def warn_static_array_too_small : Warning< - "array argument is too small; contains %0 elements, callee requires at least %1">, + "array argument is too small; %select{contains %0 elements|is of size %0}2," + " callee requires at least %1">, InGroup<ArrayBounds>; def note_callee_static_array : Note< "callee declares array parameter as static here">; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 3c6a7779560..8f3fd162740 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5228,15 +5228,29 @@ Sema::CheckStaticArrayArgument(SourceLocation CallLoc, return; const ConstantArrayType *ArgCAT = - Context.getAsConstantArrayType(ArgExpr->IgnoreParenImpCasts()->getType()); + Context.getAsConstantArrayType(ArgExpr->IgnoreParenCasts()->getType()); if (!ArgCAT) return; - if (ArgCAT->getSize().ult(CAT->getSize())) { + if (getASTContext().hasSameUnqualifiedType(CAT->getElementType(), + ArgCAT->getElementType())) { + if (ArgCAT->getSize().ult(CAT->getSize())) { + Diag(CallLoc, diag::warn_static_array_too_small) + << ArgExpr->getSourceRange() + << (unsigned)ArgCAT->getSize().getZExtValue() + << (unsigned)CAT->getSize().getZExtValue() << 0; + DiagnoseCalleeStaticArrayParam(*this, Param); + } + return; + } + + Optional<CharUnits> ArgSize = + getASTContext().getTypeSizeInCharsIfKnown(ArgCAT); + Optional<CharUnits> ParmSize = getASTContext().getTypeSizeInCharsIfKnown(CAT); + if (ArgSize && ParmSize && *ArgSize < *ParmSize) { Diag(CallLoc, diag::warn_static_array_too_small) - << ArgExpr->getSourceRange() - << (unsigned) ArgCAT->getSize().getZExtValue() - << (unsigned) CAT->getSize().getZExtValue(); + << ArgExpr->getSourceRange() << (unsigned)ArgSize->getQuantity() + << (unsigned)ParmSize->getQuantity() << 1; DiagnoseCalleeStaticArrayParam(*this, Param); } } diff --git a/clang/test/Sema/static-array.c b/clang/test/Sema/static-array.c index 304485d5af9..cc1043fe9c4 100644 --- a/clang/test/Sema/static-array.c +++ b/clang/test/Sema/static-array.c @@ -1,8 +1,8 @@ -// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -fsyntax-only -fblocks -verify %s void cat0(int a[static 0]) {} // expected-warning {{'static' has no effect on zero-length arrays}} -void cat(int a[static 3]) {} // expected-note 2 {{callee declares array parameter as static here}} +void cat(int a[static 3]) {} // expected-note 4 {{callee declares array parameter as static here}} expected-note 2 {{passing argument to parameter 'a' here}} void vat(int i, int a[static i]) {} // expected-note {{callee declares array parameter as static here}} @@ -19,6 +19,14 @@ void f(int *p) { vat(1, 0); // expected-warning {{null passed to a callee that requires a non-null argument}} vat(3, b); + + char d[4]; + cat((int *)d); // expected-warning {{array argument is too small; is of size 4, callee requires at least 12}} + cat(d); // expected-warning {{array argument is too small; is of size 4, callee requires at least 12}} expected-warning {{incompatible pointer types}} + + char e[12]; + cat((int *)e); + cat(e); // expected-warning {{incompatible pointer types}} } |

