Instantiation of byref variable in

block literal expression.

llvm-svn: 108019
This commit is contained in:
Fariborz Jahanian 2010-07-09 21:27:28 +00:00
parent 3e39272fed
commit 2f8bd36bcf
3 changed files with 28 additions and 1 deletions

View File

@ -6279,6 +6279,10 @@ TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
if (!ND)
return SemaRef.ExprError();
// Is this instantiation of a __block variable?
if (E->getDecl()->getAttr<BlocksAttr>())
ND->addAttr(::new (SemaRef.Context) BlocksAttr(BlocksAttr::ByRef));
if (!getDerived().AlwaysRebuild() &&
ND == E->getDecl()) {
// Mark it referenced in the new context regardless.

View File

@ -18,7 +18,11 @@ int test1(void)
template <typename T, typename T1> void foo(T t, T1 r)
{
T block_arg;
T1 (^block)(char, T, T1, double) = ^ T1 (char ch, T arg, T1 arg2, double d1) { return block_arg+arg; };
__block T1 byref_block_arg;
T1 (^block)(char, T, T1, double) =
^ T1 (char ch, T arg, T1 arg2, double d1) { byref_block_arg = arg2;
return byref_block_arg + arg; };
void (^block2)() = ^{};
}

View File

@ -0,0 +1,19 @@
// RUN: %clang_cc1 -fblocks -fsyntax-only -verify %s
// rdar: // 6182276
template <typename T, typename T1> void foo(T t, T1 r)
{
T block_arg;
__block T1 byref_block_arg;
T1 (^block)(T) = ^ T1 (T arg) {
byref_block_arg = arg;
block_arg = arg; // expected-error {{variable is not assignable (missing __block type specifier)}}
return block_arg+arg; };
}
int main(void)
{
foo(100, 'a'); // expected-note {{in instantiation of function template specialization 'foo<int, char>' requested here}}
}