]> granicus.if.org Git - clang/commitdiff
Allow GC qualifiers to be added/removed by conversions from/to void*
authorJohn McCall <rjmccall@apple.com>
Sat, 26 Mar 2011 02:56:45 +0000 (02:56 +0000)
committerJohn McCall <rjmccall@apple.com>
Sat, 26 Mar 2011 02:56:45 +0000 (02:56 +0000)
without a warning.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128328 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Type.h
lib/Sema/SemaExpr.cpp
test/SemaObjC/attr-objc-gc.m

index 963f4b55432b3d92b77719969867e8dc9fb4f6c8..6e8fd4da0dbd526aeab233ec93bbd17056788f12 100644 (file)
@@ -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; }
index c2f3a434b81226a83613fe82958e11ca5773dd42..dbddc384512536076463b54166467c44a0837770 100644 (file)
@@ -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;
index a82631741534caea15b54c7730f6cbad2435d805..9ca12c9315a19673ad67b6c94f164a177749d505 100644 (file)
@@ -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;
+}