Index: include/clang/Sema/ParsedAttr.h =================================================================== --- include/clang/Sema/ParsedAttr.h +++ include/clang/Sema/ParsedAttr.h @@ -659,6 +659,7 @@ class AttributePool { friend class AttributeFactory; + friend class ParsedAttributes; AttributeFactory &Factory; llvm::TinyPtrVector Attrs; @@ -892,6 +893,13 @@ pool.takeAllFrom(attrs.pool); } + void takeOneFrom(ParsedAttributes &Attrs, ParsedAttr *PA) { + Attrs.getPool().remove(PA); + Attrs.remove(PA); + getPool().add(PA); + addAtEnd(PA); + } + void clear() { clearListOnly(); pool.clear(); Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -534,8 +534,8 @@ // attribute from being applied multiple times and gives // the source-location-filler something to work with. state.saveDeclSpecAttrs(); - moveAttrFromListToList(attr, declarator.getAttributes(), - declarator.getMutableDeclSpec().getAttributes()); + declarator.getMutableDeclSpec().getAttributes().takeOneFrom( + declarator.getAttributes(), &attr); return; } } Index: test/SemaObjC/arc-property-decl-attrs.m =================================================================== --- test/SemaObjC/arc-property-decl-attrs.m +++ test/SemaObjC/arc-property-decl-attrs.m @@ -287,3 +287,7 @@ @synthesize collision = _collision; // expected-note {{property synthesized here}} @end + +// This used to crash because we'd temporarly store the weak attribute on the +// declaration specifier, then deallocate it when clearing the declarator. +id i1, __weak i2, i3;