From: Mike Stump Date: Thu, 19 Feb 2009 22:01:56 +0000 (+0000) Subject: Add enough checking to ensure that non-constant block literals don't X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b83d287bc7f47d36fb0751a481e2ef9308b37252;p=clang Add enough checking to ensure that non-constant block literals don't appear to be constant. I'll probably redo this and throw it all away later once we have codegen for BlockDeclRefExprs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65070 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index d75d3667d5..3745866f75 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -2051,9 +2051,11 @@ public: class BlockExpr : public Expr { protected: BlockDecl *TheBlock; + bool HasBlockDeclRefExprs; public: - BlockExpr(BlockDecl *BD, QualType ty) : Expr(BlockExprClass, ty), - TheBlock(BD) {} + BlockExpr(BlockDecl *BD, QualType ty, bool hasBlockDeclRefExprs) + : Expr(BlockExprClass, ty), + TheBlock(BD), HasBlockDeclRefExprs(hasBlockDeclRefExprs) {} const BlockDecl *getBlockDecl() const { return TheBlock; } BlockDecl *getBlockDecl() { return TheBlock; } @@ -2070,6 +2072,10 @@ public: /// getFunctionType - Return the underlying function type for this block. const FunctionType *getFunctionType() const; + /// hasBlockDeclRefExprs - Return true iff the block has BlockDeclRefExpr + /// contained inside. + bool hasBlockDeclRefExprs() const { return HasBlockDeclRefExprs; } + static bool classof(const Stmt *T) { return T->getStmtClass() == BlockExprClass; } diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 540a6377f2..51c581a708 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -260,7 +260,11 @@ public: APValue VisitAddrLabelExpr(AddrLabelExpr *E) { return APValue(E, 0); } APValue VisitCallExpr(CallExpr *E); - APValue VisitBlockExpr(BlockExpr *E) { return APValue(E, 0); } + APValue VisitBlockExpr(BlockExpr *E) { + if (!E->hasBlockDeclRefExprs()) + return APValue(E, 0); + return APValue(); + } APValue VisitConditionalOperator(ConditionalOperator *E); }; } // end anonymous namespace diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp index a6cf01fe2b..009a2dd17a 100644 --- a/lib/AST/StmtSerialization.cpp +++ b/lib/AST/StmtSerialization.cpp @@ -1290,11 +1290,14 @@ ExtVectorElementExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C) { void BlockExpr::EmitImpl(Serializer& S) const { S.Emit(getType()); S.EmitOwnedPtr(TheBlock); + S.EmitBool(HasBlockDeclRefExprs); } BlockExpr* BlockExpr::CreateImpl(Deserializer& D, ASTContext& C) { QualType T = QualType::ReadVal(D); - return new BlockExpr(cast(D.ReadOwnedPtr(C)),T); + BlockDecl *B = cast(D.ReadOwnedPtr(C)); + bool H = D.ReadBool(); + return new BlockExpr(B,T,H); } void BlockDeclRefExpr::EmitImpl(Serializer& S) const { diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 523014f1fb..8cfd60ce5c 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -382,6 +382,8 @@ public: } llvm::Constant *VisitBlockExpr(const BlockExpr *E) { + assert (!E->hasBlockDeclRefExprs() && "global block with BlockDeclRefs"); + const char *Name = ""; if (const NamedDecl *ND = dyn_cast(CGF->CurFuncDecl)) Name = ND->getNameAsString().c_str(); @@ -615,7 +617,9 @@ public: return CGM.GetAddrOfConstantCFString(S); } case Expr::BlockExprClass: { - return CGF->BuildBlockLiteralTmp(cast(E)); + BlockExpr *B = cast(E); + if (!B->hasBlockDeclRefExprs()) + return CGF->BuildBlockLiteralTmp(B); } } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 3eb68b5059..2a4b4657be 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -2004,7 +2004,8 @@ struct BlockSemaInfo { llvm::SmallVector Params; bool hasPrototype; bool isVariadic; - + bool hasBlockDeclRefExprs; + BlockDecl *TheDecl; /// TheScope - This is the scope for the block itself, which contains diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5d1d935386..c95b5ee52d 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -865,6 +865,9 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // as they do not get snapshotted. // if (CurBlock && ShouldSnapshotBlockValueReference(CurBlock, VD)) { + // Blocks that have these can't be constant. + CurBlock->hasBlockDeclRefExprs = true; + // The BlocksAttr indicates the variable is bound by-reference. if (VD->getAttr()) return Owned(new (Context) BlockDeclRefExpr(VD, @@ -4331,6 +4334,7 @@ void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *BlockScope) { BSI->ReturnType = 0; BSI->TheScope = BlockScope; + BSI->hasBlockDeclRefExprs = false; BSI->TheDecl = BlockDecl::Create(Context, CurContext, CaretLoc); PushDeclContext(BlockScope, BSI->TheDecl); @@ -4442,7 +4446,7 @@ Sema::ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *body, BlockTy = Context.getBlockPointerType(BlockTy); BSI->TheDecl->setBody(Body.take()); - return new (Context) BlockExpr(BSI->TheDecl, BlockTy); + return new (Context) BlockExpr(BSI->TheDecl, BlockTy, BSI->hasBlockDeclRefExprs); } Sema::ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,