Skip to content

Commit 8bed74b

Browse files
committed
[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
1 parent 890a8e5 commit 8bed74b

File tree

4 files changed

+41
-8
lines changed

4 files changed

+41
-8
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,6 +2088,16 @@ class ASTContext : public RefCountedBase<ASTContext> {
20882088
CharUnits getTypeSizeInChars(QualType T) const;
20892089
CharUnits getTypeSizeInChars(const Type *T) const;
20902090

2091+
Optional<CharUnits> getTypeSizeInCharsIfKnown(QualType Ty) const {
2092+
if (Ty->isIncompleteType() || Ty->isDependentType())
2093+
return None;
2094+
return getTypeSizeInChars(Ty);
2095+
}
2096+
2097+
Optional<CharUnits> getTypeSizeInCharsIfKnown(const Type *Ty) const {
2098+
return getTypeSizeInCharsIfKnown(QualType(Ty, 0));
2099+
}
2100+
20912101
/// Return the ABI-specified alignment of a (complete) type \p T, in
20922102
/// bits.
20932103
unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; }

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7841,7 +7841,8 @@ def warn_format_mix_positional_nonpositional_args : Warning<
78417841
"cannot mix positional and non-positional arguments in format string">,
78427842
InGroup<Format>;
78437843
def warn_static_array_too_small : Warning<
7844-
"array argument is too small; contains %0 elements, callee requires at least %1">,
7844+
"array argument is too small; %select{contains %0 elements|is of size %0}2,"
7845+
" callee requires at least %1">,
78457846
InGroup<ArrayBounds>;
78467847
def note_callee_static_array : Note<
78477848
"callee declares array parameter as static here">;

clang/lib/Sema/SemaExpr.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5228,15 +5228,29 @@ Sema::CheckStaticArrayArgument(SourceLocation CallLoc,
52285228
return;
52295229

52305230
const ConstantArrayType *ArgCAT =
5231-
Context.getAsConstantArrayType(ArgExpr->IgnoreParenImpCasts()->getType());
5231+
Context.getAsConstantArrayType(ArgExpr->IgnoreParenCasts()->getType());
52325232
if (!ArgCAT)
52335233
return;
52345234

5235-
if (ArgCAT->getSize().ult(CAT->getSize())) {
5235+
if (getASTContext().hasSameUnqualifiedType(CAT->getElementType(),
5236+
ArgCAT->getElementType())) {
5237+
if (ArgCAT->getSize().ult(CAT->getSize())) {
5238+
Diag(CallLoc, diag::warn_static_array_too_small)
5239+
<< ArgExpr->getSourceRange()
5240+
<< (unsigned)ArgCAT->getSize().getZExtValue()
5241+
<< (unsigned)CAT->getSize().getZExtValue() << 0;
5242+
DiagnoseCalleeStaticArrayParam(*this, Param);
5243+
}
5244+
return;
5245+
}
5246+
5247+
Optional<CharUnits> ArgSize =
5248+
getASTContext().getTypeSizeInCharsIfKnown(ArgCAT);
5249+
Optional<CharUnits> ParmSize = getASTContext().getTypeSizeInCharsIfKnown(CAT);
5250+
if (ArgSize && ParmSize && *ArgSize < *ParmSize) {
52365251
Diag(CallLoc, diag::warn_static_array_too_small)
5237-
<< ArgExpr->getSourceRange()
5238-
<< (unsigned) ArgCAT->getSize().getZExtValue()
5239-
<< (unsigned) CAT->getSize().getZExtValue();
5252+
<< ArgExpr->getSourceRange() << (unsigned)ArgSize->getQuantity()
5253+
<< (unsigned)ParmSize->getQuantity() << 1;
52405254
DiagnoseCalleeStaticArrayParam(*this, Param);
52415255
}
52425256
}

clang/test/Sema/static-array.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
1+
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -fsyntax-only -fblocks -verify %s
22

33
void cat0(int a[static 0]) {} // expected-warning {{'static' has no effect on zero-length arrays}}
44

5-
void cat(int a[static 3]) {} // expected-note 2 {{callee declares array parameter as static here}}
5+
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}}
66

77
void vat(int i, int a[static i]) {} // expected-note {{callee declares array parameter as static here}}
88

@@ -19,6 +19,14 @@ void f(int *p) {
1919

2020
vat(1, 0); // expected-warning {{null passed to a callee that requires a non-null argument}}
2121
vat(3, b);
22+
23+
char d[4];
24+
cat((int *)d); // expected-warning {{array argument is too small; is of size 4, callee requires at least 12}}
25+
cat(d); // expected-warning {{array argument is too small; is of size 4, callee requires at least 12}} expected-warning {{incompatible pointer types}}
26+
27+
char e[12];
28+
cat((int *)e);
29+
cat(e); // expected-warning {{incompatible pointer types}}
2230
}
2331

2432

0 commit comments

Comments
 (0)