summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/AST/Expr.cpp2
-rw-r--r--clang/lib/AST/ExprConstant.cpp10
-rw-r--r--clang/test/Sema/block-literal.c6
3 files changed, 18 insertions, 0 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 9e8958c0733..083bf3b8087 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -854,6 +854,8 @@ bool Expr::hasGlobalStorage() const {
switch (getStmtClass()) {
default:
return false;
+ case BlockExprClass:
+ return true;
case ParenExprClass:
return cast<ParenExpr>(this)->getSubExpr()->hasGlobalStorage();
case ImplicitCastExprClass:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 327fff0c0b1..8fd75f1808e 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -156,6 +156,7 @@ public:
APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
APValue VisitDeclRefExpr(DeclRefExpr *E);
+ APValue VisitBlockExpr(BlockExpr *E);
APValue VisitPredefinedExpr(PredefinedExpr *E) { return APValue(E, 0); }
APValue VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
APValue VisitMemberExpr(MemberExpr *E);
@@ -184,6 +185,14 @@ APValue LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E)
return APValue(E, 0);
}
+APValue LValueExprEvaluator::VisitBlockExpr(BlockExpr *E)
+{
+ if (E->hasBlockDeclRefExprs())
+ return APValue();
+
+ return APValue(E, 0);
+}
+
APValue LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
if (E->isFileScope())
return APValue(E, 0);
@@ -373,6 +382,7 @@ APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
}
if (SubExpr->getType()->isFunctionType() ||
+ SubExpr->getType()->isBlockPointerType() ||
SubExpr->getType()->isArrayType()) {
APValue Result;
if (EvaluateLValue(SubExpr, Result, Info))
diff --git a/clang/test/Sema/block-literal.c b/clang/test/Sema/block-literal.c
index 2dc45812431..040c383033b 100644
--- a/clang/test/Sema/block-literal.c
+++ b/clang/test/Sema/block-literal.c
@@ -81,6 +81,12 @@ void test_arguments() {
static int global_x = 10;
void (^global_block)(void) = ^{ printf("global x is %d\n", global_x); };
+typedef void (^void_block_t)(void);
+
+static const void_block_t myBlock = ^{ };
+
+static const void_block_t myBlock2 = ^ void(void) { };
+
#if 0
// Old syntax. FIXME: convert/test.
void test_byref() {
OpenPOWER on IntegriCloud