diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2011-08-05 08:07:29 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2011-08-05 08:07:29 +0000 |
commit | 126b15542958f627bb2cb74ae048221022a031dc (patch) | |
tree | 243287f26c5d58c7d44a31adf7d4f6ceb3b1527d /clang/lib/Sema/SemaChecking.cpp | |
parent | ff371acaa4dcd3611e7307aceabe5b0a94e5fd4f (diff) | |
download | bcm5719-llvm-126b15542958f627bb2cb74ae048221022a031dc.tar.gz bcm5719-llvm-126b15542958f627bb2cb74ae048221022a031dc.zip |
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.
llvm-svn: 136964
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index af6141e3aeb..3065a5f64b3 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3489,6 +3489,15 @@ static void CheckArrayAccess_Check(Sema &S, 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 @@ static void CheckArrayAccess_Check(Sema &S, 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 @@ static void CheckArrayAccess_Check(Sema &S, << 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) |