improve handling of address of global when checking for

constants and initializers.  Patch by Sanghyeon Seo, thanks!

llvm-svn: 44049
This commit is contained in:
Chris Lattner 2007-11-13 18:05:45 +00:00
parent c891ae92dc
commit 2f72c427cf
3 changed files with 33 additions and 0 deletions

View File

@ -359,6 +359,22 @@ Expr::isModifiableLvalueResult Expr::isModifiableLvalue() const {
return MLV_Valid;
}
bool Expr::hasStaticStorage() const {
switch (getStmtClass()) {
default:
return false;
case DeclRefExprClass: {
const Decl *D = cast<DeclRefExpr>(this)->getDecl();
if (const VarDecl *VD = dyn_cast<VarDecl>(D))
return VD->hasStaticStorage();
return false;
}
case MemberExprClass:
const MemberExpr *M = cast<MemberExpr>(this);
return !M->isArrow() && M->getBase()->hasStaticStorage();
}
}
bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
switch (getStmtClass()) {
default:
@ -391,11 +407,17 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
if (isa<EnumConstantDecl>(D) || isa<FunctionDecl>(D))
return true;
if (Loc) *Loc = getLocStart();
if (isa<VarDecl>(D))
return TR->isArrayType();
return false;
}
case UnaryOperatorClass: {
const UnaryOperator *Exp = cast<UnaryOperator>(this);
// C99 6.6p9
if (Exp->getOpcode() == UnaryOperator::AddrOf)
return Exp->getSubExpr()->hasStaticStorage();
// Get the operand value. If this is sizeof/alignof, do not evalute the
// operand. This affects C99 6.6p3.
if (!Exp->isSizeOfAlignOfOp() &&

View File

@ -105,6 +105,10 @@ public:
/// isConstantExpr - Return true if this expression is a valid constant expr.
bool isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const;
/// hasStaticStorage - Return true if this expression has static storage
/// duration.
bool hasStaticStorage() const;
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstExprConstant &&
T->getStmtClass() <= lastExprConstant;

View File

@ -0,0 +1,7 @@
// RUN: clang -fsyntax-only -verify %s
int i;
int a[] = {0};
struct { int i; } s;
int *array[] = {&i, a, &s.i};