summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/Type.h5
-rw-r--r--clang/lib/Sema/SemaExpr.cpp6
-rw-r--r--clang/test/SemaObjC/attr-objc-gc.m11
3 files changed, 22 insertions, 0 deletions
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 963f4b55432..6e8fd4da0db 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -213,6 +213,11 @@ public:
assert(type);
setObjCGCAttr(type);
}
+ Qualifiers withoutObjCGCAttr() const {
+ Qualifiers qs = *this;
+ qs.removeObjCGCAttr();
+ return qs;
+ }
bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c2f3a434b81..dbddc384512 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5803,6 +5803,12 @@ checkPointerTypesForAssignment(Sema &S, QualType lhsType, QualType rhsType) {
if (lhq.getAddressSpace() != rhq.getAddressSpace())
ConvTy = Sema::IncompatiblePointerDiscardsQualifiers;
+ // It's okay to add or remove GC qualifiers when converting to
+ // and from void*.
+ else if (lhq.withoutObjCGCAttr().compatiblyIncludes(rhq.withoutObjCGCAttr())
+ && (lhptee->isVoidType() || rhptee->isVoidType()))
+ ; // keep old
+
// For GCC compatibility, other qualifier mismatches are treated
// as still compatible in C.
else ConvTy = Sema::CompatiblePointerDiscardsQualifiers;
diff --git a/clang/test/SemaObjC/attr-objc-gc.m b/clang/test/SemaObjC/attr-objc-gc.m
index a8263174153..9ca12c9315a 100644
--- a/clang/test/SemaObjC/attr-objc-gc.m
+++ b/clang/test/SemaObjC/attr-objc-gc.m
@@ -17,3 +17,14 @@ static WEAK int h; // expected-warning {{'objc_gc' only applies to pointer types
/* expected-warning {{'__weak' only applies to pointer types; type here is 'int'}}*/ static __we\
ak int i;
+
+// rdar://problem/9126213
+void test2(id __attribute((objc_gc(strong))) *strong,
+ id __attribute((objc_gc(weak))) *weak) {
+ void *opaque;
+ opaque = strong;
+ strong = opaque;
+
+ opaque = weak;
+ weak = opaque;
+}
OpenPOWER on IntegriCloud