summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Expr.cpp11
-rw-r--r--clang/lib/Sema/SemaExpr.cpp4
2 files changed, 14 insertions, 1 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 9c3d623c163..456b87b64e0 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/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;
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 1a80283f826..e8b4d8cb4b3 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2181,6 +2181,10 @@ inline QualType Sema::CheckAssignmentOperands( // C99 6.5.16.1
Diag(loc, diag::err_typecheck_duplicate_vector_components_not_mlvalue,
lex->getSourceRange());
return QualType();
+ case Expr::MLV_NotBlockQualified:
+ Diag(loc, diag::err_block_decl_ref_not_modifiable_lvalue,
+ lex->getSourceRange());
+ return QualType();
}
AssignConvertType ConvTy;
OpenPOWER on IntegriCloud