Suppress -Warray-bounds in certain cases involving macros from system headers.

The motivation here is a "clever" implementation of strncmp(), which peels the first few comparisons via chained conditional expressions which ensure that the input arrays are known at compile time to be sufficiently large.

llvm-svn: 146430
This commit is contained in:
Matt Beaumont-Gay 2011-12-12 22:35:02 +00:00
parent 055d0c961b
commit 9d570c438c
3 changed files with 31 additions and 1 deletions

View File

@ -4275,7 +4275,7 @@ static bool IsTailPaddedMemberArray(Sema &S, llvm::APInt Size,
void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
bool isSubscript, bool AllowOnePastEnd) {
const Type* EffectiveType = getElementType(BaseExpr);
const Type *EffectiveType = getElementType(BaseExpr);
BaseExpr = BaseExpr->IgnoreParenCasts();
IndexExpr = IndexExpr->IgnoreParenCasts();
@ -4381,6 +4381,16 @@ void Sema::CheckArrayAccess(const Expr *expr) {
switch (expr->getStmtClass()) {
case Stmt::ArraySubscriptExprClass: {
const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(expr);
// Suppress the warning if the subscript expression (as identified by
// the ']' location) and the index expression are both from macro
// expansions within a system header.
SourceLocation RBracketLoc = SourceMgr.getSpellingLoc(
ASE->getRBracketLoc());
SourceLocation IndexLoc = SourceMgr.getSpellingLoc(
ASE->getIdx()->IgnoreParens()->getLocStart());
if (SourceMgr.isFromSameFile(RBracketLoc, IndexLoc) &&
SourceMgr.isInSystemHeader(RBracketLoc))
return;
CheckArrayAccess(ASE->getBase(), ASE->getIdx(), true,
AllowOnePastEnd > 0);
return;

View File

@ -0,0 +1,11 @@
// "System header" for testing that -Warray-bounds is properly suppressed in
// certain cases.
#define BAD_MACRO_1 \
int i[3]; \
i[3] = 5
#define BAD_MACRO_2(_b, _i) \
(_b)[(_i)] = 5
#define QUESTIONABLE_MACRO(_a) \
sizeof(_a) > 3 ? (_a)[3] = 5 : 5
#define NOP(x) (x)

View File

@ -0,0 +1,9 @@
// RUN: %clang_cc1 -isystem %S/Inputs -verify %s
#include <array-bounds-system-header.h>
void test_system_header_macro() {
BAD_MACRO_1; // no-warning
char a[3]; // expected-note 2 {{declared here}}
BAD_MACRO_2(a, 3); // expected-warning {{array index 3}}
QUESTIONABLE_MACRO(a);
NOP(a[3] = 5); // expected-warning {{array index 3}}
}