Skip to content

Commit

Permalink
Add utility to evaluate lvalues which are an offset relative to a stack
Browse files Browse the repository at this point in the history
location.  Patch by Enea Zaffanella.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81672 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
eefriedman committed Sep 13, 2009
1 parent 98303b9 commit b2f295c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
7 changes: 6 additions & 1 deletion include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,14 @@ class Expr : public Stmt {
/// must be called on an expression that constant folds to an integer.
llvm::APSInt EvaluateAsInt(ASTContext &Ctx) const;

/// EvaluateAsLValue - Evaluate an expression to see if it's a valid LValue.
/// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue
/// with link time known address.
bool EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const;

/// EvaluateAsAnyLValue - The same as EvaluateAsLValue, except that it
/// also succeeds on stack based, immutable address lvalues.
bool EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const;

/// isNullPointerConstant - C99 6.3.2.3p3 - Return true if this is either an
/// integer constant expression with the value zero, or if this is one that is
/// cast to void*.
Expand Down
22 changes: 16 additions & 6 deletions lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,12 @@ struct EvalInfo {
/// EvalResult - Contains information about the evaluation.
Expr::EvalResult &EvalResult;

EvalInfo(ASTContext &ctx, Expr::EvalResult& evalresult) : Ctx(ctx),
EvalResult(evalresult) {}
/// AnyLValue - Stack based LValue results are not discarded.
bool AnyLValue;

EvalInfo(ASTContext &ctx, Expr::EvalResult& evalresult,
bool anylvalue = false)
: Ctx(ctx), EvalResult(evalresult), AnyLValue(anylvalue) {}
};


Expand Down Expand Up @@ -189,7 +193,7 @@ APValue LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) {
if (isa<FunctionDecl>(E->getDecl())) {
return APValue(E, 0);
} else if (VarDecl* VD = dyn_cast<VarDecl>(E->getDecl())) {
if (!VD->hasGlobalStorage())
if (!Info.AnyLValue && !VD->hasGlobalStorage())
return APValue();
if (!VD->getType()->isReferenceType())
return APValue(E, 0);
Expand All @@ -209,9 +213,9 @@ APValue LValueExprEvaluator::VisitBlockExpr(BlockExpr *E) {
}

APValue LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
if (E->isFileScope())
return APValue(E, 0);
return APValue();
if (!Info.AnyLValue && !E->isFileScope())
return APValue();
return APValue(E, 0);
}

APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) {
Expand Down Expand Up @@ -1786,6 +1790,12 @@ bool Expr::EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const {
return EvaluateLValue(this, Result.Val, Info) && !Result.HasSideEffects;
}

bool Expr::EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const {
EvalInfo Info(Ctx, Result, true);

return EvaluateLValue(this, Result.Val, Info) && !Result.HasSideEffects;
}

/// isEvaluatable - Call Evaluate to see if this expression can be constant
/// folded, but discard the result.
bool Expr::isEvaluatable(ASTContext &Ctx) const {
Expand Down

0 comments on commit b2f295c

Please sign in to comment.