From: Eli Friedman Date: Sun, 22 Mar 2009 23:26:56 +0000 (+0000) Subject: Adjust isModifiableLvalue to give a slightly more useful diagnostic for X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=04831aa3271edc5f00a651bf7152c2902981d7c3;p=clang Adjust isModifiableLvalue to give a slightly more useful diagnostic for attempting to illegally modify a BlockDeclRefExpr. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67491 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index f2553c3390..789fbc5ce1 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -781,7 +781,17 @@ Expr::isModifiableLvalueResult Expr::isModifiableLvalue(ASTContext &Ctx) const { return MLV_InvalidExpression; case LV_MemberFunction: return MLV_MemberFunction; } - + + // The following is illegal: + // void takeclosure(void (^C)(void)); + // void func() { int x = 1; takeclosure(^{ x = 7; }); } + // + if (getStmtClass() == BlockDeclRefExprClass) { + const BlockDeclRefExpr *BDR = cast(this); + if (!BDR->isByRef() && isa(BDR->getDecl())) + return MLV_NotBlockQualified; + } + QualType CT = Ctx.getCanonicalType(getType()); if (CT.isConstQualified()) @@ -795,15 +805,6 @@ 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(this); - if (!BDR->isByRef() && isa(BDR->getDecl())) - return MLV_NotBlockQualified; - } // Assigning to an 'implicit' property? else if (getStmtClass() == ObjCKVCRefExprClass) { diff --git a/test/Sema/block-literal.c b/test/Sema/block-literal.c index 290cef1fed..4890839b97 100644 --- a/test/Sema/block-literal.c +++ b/test/Sema/block-literal.c @@ -39,7 +39,7 @@ void test2() { } foo: - takeclosure(^{ x = 4; }); // expected-error {{read-only variable is not assignable}} + takeclosure(^{ x = 4; }); // expected-error {{variable is not assignable (missing __block type specifier)}} __block y = 7; // expected-warning {{type specifier missing, defaults to 'int'}} takeclosure(^{ y = 8; }); }