From: Chris Lattner Date: Tue, 13 Nov 2007 18:05:45 +0000 (+0000) Subject: improve handling of address of global when checking for X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1d09ecca892185ba067e47ba879f424de59950ef;p=clang improve handling of address of global when checking for constants and initializers. Patch by Sanghyeon Seo, thanks! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44049 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/Expr.cpp b/AST/Expr.cpp index 4505feca77..10f0895695 100644 --- a/AST/Expr.cpp +++ b/AST/Expr.cpp @@ -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(this)->getDecl(); + if (const VarDecl *VD = dyn_cast(D)) + return VD->hasStaticStorage(); + return false; + } + case MemberExprClass: + const MemberExpr *M = cast(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(D) || isa(D)) return true; if (Loc) *Loc = getLocStart(); + if (isa(D)) + return TR->isArrayType(); return false; } case UnaryOperatorClass: { const UnaryOperator *Exp = cast(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() && diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 7f47a299b3..e69344690d 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -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; diff --git a/test/Sema/address-constant.c b/test/Sema/address-constant.c new file mode 100644 index 0000000000..0b451cc39c --- /dev/null +++ b/test/Sema/address-constant.c @@ -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};