mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-12 21:28:48 +00:00
[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
This commit is contained in:
parent
890a8e575f
commit
8bed74ba51
@ -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; }
|
||||
|
@ -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">;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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}}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user