From 7ea21937de6f849a7f44f10549c3d69c5a8cb3f3 Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 26 Mar 2011 01:39:56 +0000 Subject: [PATCH] Properly move attributes to the decl spec when applying them there. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128324 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaType.cpp | 25 +++++++++++++++++++++---- test/SemaObjC/weak-attr-ivar.m | 10 ++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 53242294ac..d0b3fe70a2 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -138,6 +138,9 @@ namespace { /// Whether there are non-trivial modifications to the decl spec. bool trivial; + /// Whether we saved the attributes in the decl spec. + bool hasSavedAttrs; + /// The original set of attributes on the DeclSpec. llvm::SmallVector savedAttrs; @@ -149,7 +152,7 @@ namespace { TypeProcessingState(Sema &sema, Declarator &declarator) : sema(sema), declarator(declarator), chunkIndex(declarator.getNumTypeObjects()), - trivial(true) {} + trivial(true), hasSavedAttrs(false) {} Sema &getSema() const { return sema; @@ -178,13 +181,14 @@ namespace { /// Save the current set of attributes on the DeclSpec. void saveDeclSpecAttrs() { // Don't try to save them multiple times. - if (!savedAttrs.empty()) return; + if (hasSavedAttrs) return; DeclSpec &spec = getMutableDeclSpec(); for (AttributeList *attr = spec.getAttributes().getList(); attr; attr = attr->getNext()) savedAttrs.push_back(attr); trivial &= savedAttrs.empty(); + hasSavedAttrs = true; } /// Record that we had nowhere to put the given type attribute. @@ -214,7 +218,13 @@ namespace { } void restoreDeclSpecAttrs() { - assert(!savedAttrs.empty()); + assert(hasSavedAttrs); + + if (savedAttrs.empty()) { + getMutableDeclSpec().getAttributes().set(0); + return; + } + getMutableDeclSpec().getAttributes().set(savedAttrs[0]); for (unsigned i = 0, e = savedAttrs.size() - 1; i != e; ++i) savedAttrs[i]->setNext(savedAttrs[i+1]); @@ -360,8 +370,15 @@ distributeObjCPointerTypeAttrFromDeclarator(TypeProcessingState &state, // That might actually be the decl spec if we weren't blocked by // anything in the declarator. if (considerDeclSpec) { - if (handleObjCPointerTypeAttr(state, attr, declSpecType)) + if (handleObjCPointerTypeAttr(state, attr, declSpecType)) { + // Splice the attribute into the decl spec. Prevents the + // attribute from being applied multiple times and gives + // the source-location-filler something to work with. + state.saveDeclSpecAttrs(); + moveAttrFromListToList(attr, declarator.getAttrListRef(), + declarator.getMutableDeclSpec().getAttributes().getListRef()); return; + } } // Otherwise, if we found an appropriate chunk, splice the attribute diff --git a/test/SemaObjC/weak-attr-ivar.m b/test/SemaObjC/weak-attr-ivar.m index d5bbb01902..e3d96da13b 100644 --- a/test/SemaObjC/weak-attr-ivar.m +++ b/test/SemaObjC/weak-attr-ivar.m @@ -72,3 +72,13 @@ typedef enum { Foo_HUH_NONE } FooHUHCode; } @end +// rdar://problem/9123040 +@interface Test1 { +@public + id ivar __attribute__((objc_gc(weak))); +} +@property (assign) id prop __attribute((objc_gc(weak))); +@end +void test1(Test1 *t) { + id *(__attribute__((objc_gc(strong))) x) = &t->ivar; // expected-warning {{initializing '__strong id *' with an expression of type '__weak id *' discards qualifiers}} +} -- 2.50.1