diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-16 19:31:14 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-16 19:31:14 +0000 |
| commit | 13f6718b428fc5c4b966b6d47bc52aa3d6d36191 (patch) | |
| tree | af787fc1c45a64df9b6af1cc1a27361dae7aa3dd /clang | |
| parent | 6bb2f1d5b542a0fef88c841a12ff46e8a4877ca2 (diff) | |
| download | bcm5719-llvm-13f6718b428fc5c4b966b6d47bc52aa3d6d36191.tar.gz bcm5719-llvm-13f6718b428fc5c4b966b6d47bc52aa3d6d36191.zip | |
PR11594: Don't blindly build a UnaryOperator UO_Minus on an expression which
might not be an rvalue when checking array accesses. Instead, pass through a
flag indicating the array index is negated.
llvm-svn: 146753
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 6 | ||||
| -rw-r--r-- | clang/test/Sema/array-bounds-ptr-arith.c | 7 |
4 files changed, 13 insertions, 6 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 0b08526d98e..bd542da6a60 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -6200,7 +6200,7 @@ public: private: void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, const ArraySubscriptExpr *ASE=0, - bool AllowOnePastEnd=true); + bool AllowOnePastEnd=true, bool IndexNegated=false); void CheckArrayAccess(const Expr *E); bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall); bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index c8f2d05e0d4..9bb532b5329 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -4277,7 +4277,7 @@ static bool IsTailPaddedMemberArray(Sema &S, llvm::APInt Size, void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, const ArraySubscriptExpr *ASE, - bool AllowOnePastEnd) { + bool AllowOnePastEnd, bool IndexNegated) { IndexExpr = IndexExpr->IgnoreParenCasts(); if (IndexExpr->isValueDependent()) return; @@ -4292,6 +4292,8 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, llvm::APSInt index; if (!IndexExpr->EvaluateAsInt(index, Context)) return; + if (IndexNegated) + index = -index; const NamedDecl *ND = NULL; if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BaseExpr)) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c18d37df5f3..552d0e7f21b 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6203,11 +6203,9 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, if (!checkArithmeticOpPointerOperand(*this, Loc, LHS.get())) return QualType(); - Expr *IExpr = RHS.get()->IgnoreParenCasts(); - UnaryOperator negRex(IExpr, UO_Minus, IExpr->getType(), VK_RValue, - OK_Ordinary, IExpr->getExprLoc()); // Check array bounds for pointer arithemtic - CheckArrayAccess(LHS.get()->IgnoreParenCasts(), &negRex); + CheckArrayAccess(LHS.get(), RHS.get(), /*ArraySubscriptExpr*/0, + /*AllowOnePastEnd*/true, /*IndexNegated*/true); if (CompLHSTy) *CompLHSTy = LHS.get()->getType(); return LHS.get()->getType(); diff --git a/clang/test/Sema/array-bounds-ptr-arith.c b/clang/test/Sema/array-bounds-ptr-arith.c index c0e0d0ea785..022335bd37a 100644 --- a/clang/test/Sema/array-bounds-ptr-arith.c +++ b/clang/test/Sema/array-bounds-ptr-arith.c @@ -12,3 +12,10 @@ void* broken (struct ext2_super_block *es,int a) { return (void *)es->s_uuid + 80; // expected-warning {{refers past the end of the array}} } + +// Test case reduced from PR11594 +struct S { int n; }; +void pr11594(struct S *s) { + int a[10]; + int *p = a - s->n; +} |

