From: Erik Pilkington Date: Tue, 2 Apr 2019 19:48:11 +0000 (+0000) Subject: [Sema] Fix a use-after-deallocate of a ParsedAttr X-Git-Tag: llvmorg-10-init~8650 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=af913156685a910c4930c40e72a4f641f268a83f;p=platform%2Fupstream%2Fllvm.git [Sema] Fix a use-after-deallocate of a ParsedAttr moveAttrFromListToList only makes sense when moving an attribute to a list with a pool that's either equivalent, or has a shorter lifetime. Therefore, using it to move a ParsedAttr from a declarator to a declaration specifier doesn't make sense, since the declaration specifier's pool outlives the declarator's. The patch adds a new function, ParsedAttributes::takeOneFrom, which transfers the attribute from one pool to another, fixing the use-after-deallocate. rdar://49175426 Differential revision: https://reviews.llvm.org/D60101 llvm-svn: 357516 --- diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h index d125d3b..2e0efe4 100644 --- a/clang/include/clang/Sema/ParsedAttr.h +++ b/clang/include/clang/Sema/ParsedAttr.h @@ -659,6 +659,7 @@ public: class AttributePool { friend class AttributeFactory; + friend class ParsedAttributes; AttributeFactory &Factory; llvm::TinyPtrVector Attrs; @@ -892,6 +893,13 @@ public: 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(); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index ba028b0..3d3b771 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -534,8 +534,8 @@ static void distributeObjCPointerTypeAttrFromDeclarator( // 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; } } diff --git a/clang/test/SemaObjC/arc-property-decl-attrs.m b/clang/test/SemaObjC/arc-property-decl-attrs.m index 6638054..833998d 100644 --- a/clang/test/SemaObjC/arc-property-decl-attrs.m +++ b/clang/test/SemaObjC/arc-property-decl-attrs.m @@ -287,3 +287,7 @@ __attribute__((objc_root_class)) @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;