aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Expr.cpp
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2008-09-26 14:41:28 +0000
committerSteve Naroff <snaroff@apple.com>2008-09-26 14:41:28 +0000
commit4f6a7d7ead09b439216c32f2de806a998aeb222a (patch)
tree82492ffdc09cbb70eec125514fe8ae227052d83b /lib/AST/Expr.cpp
parent84fa6b90abf73e8cc539c9947ed5a6286f588569 (diff)
Tweak Expr::isModifiableLvalue() and Expr::isLvalue() to better deal with BlockDeclRef exprs.
This fixes <rdar://problem/6248392> clang: Error when using address of stack variable inside block. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56652 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r--lib/AST/Expr.cpp11
1 files changed, 10 insertions, 1 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 9c3d623c16..456b87b64e 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -425,7 +425,7 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
}
case BlockDeclRefExprClass: {
const BlockDeclRefExpr *BDR = cast<BlockDeclRefExpr>(this);
- if (BDR->isByRef() && isa<VarDecl>(BDR->getDecl()))
+ if (isa<VarDecl>(BDR->getDecl()))
return LV_Valid;
break;
}
@@ -497,6 +497,15 @@ Expr::isModifiableLvalueResult Expr::isModifiableLvalue(ASTContext &Ctx) const {
if (r->hasConstFields())
return MLV_ConstQualified;
}
+ // The following is illegal:
+ // void takeclosure(void (^C)(void));
+ // void func() { int x = 1; takeclosure(^{ x = 7 }); }
+ //
+ if (getStmtClass() == BlockDeclRefExprClass) {
+ const BlockDeclRefExpr *BDR = cast<BlockDeclRefExpr>(this);
+ if (!BDR->isByRef() && isa<VarDecl>(BDR->getDecl()))
+ return MLV_NotBlockQualified;
+ }
return MLV_Valid;
}