summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Pilkington <erik.pilkington@gmail.com>2019-04-02 19:48:11 +0000
committerErik Pilkington <erik.pilkington@gmail.com>2019-04-02 19:48:11 +0000
commitaf913156685a910c4930c40e72a4f641f268a83f (patch)
treed12ec96cb15a9c60d16b8eb22e595d5682f82f19
parent3299ead8e9ff3d65ff133518d4df84dc2a424c72 (diff)
downloadbcm5719-llvm-af913156685a910c4930c40e72a4f641f268a83f.tar.gz
bcm5719-llvm-af913156685a910c4930c40e72a4f641f268a83f.zip
[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
-rw-r--r--clang/include/clang/Sema/ParsedAttr.h8
-rw-r--r--clang/lib/Sema/SemaType.cpp4
-rw-r--r--clang/test/SemaObjC/arc-property-decl-attrs.m4
3 files changed, 14 insertions, 2 deletions
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index d125d3b8062..2e0efe452a8 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<ParsedAttr *> 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 ba028b07e3b..3d3b771125f 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 6638054bef8..833998d4250 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;
OpenPOWER on IntegriCloud