[cfe-commits] r136964 - /cfe/trunk/lib/Sema/SemaChecking.cpp
Chandler Carruth
chandlerc at gmail.com
Fri Aug 5 01:07:29 PDT 2011
Author: chandlerc
Date: Fri Aug 5 03:07:29 2011
New Revision: 136964
URL: http://llvm.org/viewvc/llvm-project?rev=136964&view=rev
Log:
Finally getting around to re-working this to more accurately white-list
1-element character arrays which are serving as flexible arrays. This is
the initial step, which is to restrict the 1-element array whitelist to
arrays that are member declarations. I'll refine it from here based on
the proposed patch.
Modified:
cfe/trunk/lib/Sema/SemaChecking.cpp
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=136964&r1=136963&r2=136964&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Aug 5 03:07:29 2011
@@ -3489,6 +3489,15 @@
if (!IndexExpr->isIntegerConstantExpr(index, S.Context))
return;
+ const NamedDecl *ND = NULL;
+ bool IsMemberDecl = false;
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
+ ND = dyn_cast<NamedDecl>(DRE->getDecl());
+ if (const MemberExpr *ME = dyn_cast<MemberExpr>(BaseExpr)) {
+ ND = dyn_cast<NamedDecl>(ME->getMemberDecl());
+ IsMemberDecl = true;
+ }
+
if (index.isUnsigned() || !index.isNegative()) {
llvm::APInt size = ArrayTy->getSize();
if (!size.isStrictlyPositive())
@@ -3498,9 +3507,19 @@
else if (size.getBitWidth() < index.getBitWidth())
size = size.sext(index.getBitWidth());
- // Don't warn for valid indexes, or arrays of size 1 (which are often
- // tail-allocated arrays that are emulating flexible arrays in C89 code).
- if (index.slt(size) || size == 1)
+ // Don't warn for valid indexes
+ if (index.slt(size))
+ return;
+
+ // Also don't warn for arrays of size 1 which are members of some
+ // structure. These are often used to approximate flexible arrays in C89
+ // code.
+ // FIXME: We should also check whether there are any members after this
+ // member within the struct as that precludes the usage as a flexible
+ // array. We should also potentially check for an explicit '1' as opposed
+ // to a macro or template argument which might accidentally and erroneously
+ // expand to '1'.
+ if (IsMemberDecl && size == 1)
return;
S.DiagRuntimeBehavior(E->getBase()->getLocStart(), BaseExpr,
@@ -3515,11 +3534,6 @@
<< IndexExpr->getSourceRange());
}
- const NamedDecl *ND = NULL;
- if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
- ND = dyn_cast<NamedDecl>(DRE->getDecl());
- if (const MemberExpr *ME = dyn_cast<MemberExpr>(BaseExpr))
- ND = dyn_cast<NamedDecl>(ME->getMemberDecl());
if (ND)
S.DiagRuntimeBehavior(ND->getLocStart(), BaseExpr,
S.PDiag(diag::note_array_index_out_of_bounds)
More information about the cfe-commits
mailing list