mirror of https://github.com/microsoft/clang.git
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
This commit is contained in:
parent
b4c82b4a2c
commit
7ea21937de
|
@ -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<AttributeList*, 2> 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
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue