From 1ee711633dfdd1fe4e94926723c92ec25ebab9f5 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Wed, 8 Nov 2017 22:44:34 +0000 Subject: [PATCH] [ObjC] Fix function signature handling for blocks literals with attributes Block literals can have a type with attributes in its signature, e.g. ns_returns_retained. The code that inspected the type loc of the block when declaring its parameters didn't account for this fact, and only looked through paren type loc. This commit ensures that getAsAdjusted is used instead of IgnoreParens to find the block's FunctionProtoTypeLoc. This ensures that block parameters are declared correctly in the block and avoids the 'undeclared identifier' error. rdar://35416160 llvm-svn: 317736 --- clang/lib/Sema/SemaExpr.cpp | 4 ++-- .../test/SemaObjC/block-literal-with-attribute.m | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaObjC/block-literal-with-attribute.m diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index d80237d248d2..d5a7bc31a81d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -12859,8 +12859,8 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, // Look for an explicit signature in that function type. FunctionProtoTypeLoc ExplicitSignature; - TypeLoc tmp = Sig->getTypeLoc().IgnoreParens(); - if ((ExplicitSignature = tmp.getAs())) { + if ((ExplicitSignature = + Sig->getTypeLoc().getAsAdjusted())) { // Check whether that explicit signature was synthesized by // GetTypeForDeclarator. If so, don't save that as part of the diff --git a/clang/test/SemaObjC/block-literal-with-attribute.m b/clang/test/SemaObjC/block-literal-with-attribute.m new file mode 100644 index 000000000000..24ef2aafa87c --- /dev/null +++ b/clang/test/SemaObjC/block-literal-with-attribute.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks -fobjc-arc +// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks +// FIXME: should compile + +__auto_type block = ^ id __attribute__((ns_returns_retained)) (id filter) { + return filter; // ok +}; +__auto_type block2 = ^ __attribute__((ns_returns_retained)) id (id filter) { + return filter; // ok +}; +__auto_type block3 = ^ id (id filter) __attribute__((ns_returns_retained)) { + return filter; // ok +}; + +// expected-no-diagnostics