ahatanak created this revision.
ahatanak added reviewers: rjmccall, ldionne.
ahatanak added a project: clang.
ahatanak requested review of this revision.

clang was just being conservative and trying to prevent users from messing up 
the qualifier on the inner pointer type. Lifting this restriction enables using 
some of the libc++ templates with ObjC pointer arguments, which clang currently 
rejects.

rdar://79018677


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D107021

Files:
  clang/lib/Sema/SemaExprObjC.cpp
  clang/test/SemaObjC/arc-type-conversion.m


Index: clang/test/SemaObjC/arc-type-conversion.m
===================================================================
--- clang/test/SemaObjC/arc-type-conversion.m
+++ clang/test/SemaObjC/arc-type-conversion.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify 
-fblocks %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify 
-fblocks -Wno-incompatible-pointer-types %s
 
 typedef const void * CFTypeRef;
 CFTypeRef CFBridgingRetain(id X);
@@ -96,3 +96,14 @@
   id c = 1 ? a : b; // expected-error {{operands to conditional of types 'id' 
and 'void *' are incompatible in ARC mode}}
   id d = 1 ? b : a; // expected-error {{operands to conditional of types 'void 
*' and 'id' are incompatible in ARC mode}}
 }
+
+void conversion_pointer_to_id(__strong id *x) {
+  struct S {
+    int a[2];
+  } s, *p;
+
+  x = (__strong id *)&s;
+  x = &s; // expected-error {{implicit conversion of a non-Objective-C pointer 
type 'struct S *' to '__strong id *' is disallowed with ARC}}
+  p = (struct S *)x;
+  p = x; // expected-error {{implicit conversion of an indirect pointer to an 
Objective-C pointer to 'struct S *' is disallowed with ARC}}
+}
Index: clang/lib/Sema/SemaExprObjC.cpp
===================================================================
--- clang/lib/Sema/SemaExprObjC.cpp
+++ clang/lib/Sema/SemaExprObjC.cpp
@@ -4453,9 +4453,14 @@
   // Allow casts between pointers to lifetime types (e.g., __strong id*)
   // and pointers to void (e.g., cv void *). Casting from void* to lifetime*
   // must be explicit.
-  if (exprACTC == ACTC_indirectRetainable && castACTC == ACTC_voidPtr)
+  // Allow conversions between pointers to lifetime types and coreFoundation
+  // pointers too, but only when the conversions are explicit.
+  if (exprACTC == ACTC_indirectRetainable &&
+      (castACTC == ACTC_voidPtr ||
+       (castACTC == ACTC_coreFoundation && isCast(CCK))))
     return ACR_okay;
-  if (castACTC == ACTC_indirectRetainable && exprACTC == ACTC_voidPtr &&
+  if (castACTC == ACTC_indirectRetainable &&
+      (exprACTC == ACTC_voidPtr || exprACTC == ACTC_coreFoundation) &&
       isCast(CCK))
     return ACR_okay;
 


Index: clang/test/SemaObjC/arc-type-conversion.m
===================================================================
--- clang/test/SemaObjC/arc-type-conversion.m
+++ clang/test/SemaObjC/arc-type-conversion.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -fblocks %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -fblocks -Wno-incompatible-pointer-types %s
 
 typedef const void * CFTypeRef;
 CFTypeRef CFBridgingRetain(id X);
@@ -96,3 +96,14 @@
   id c = 1 ? a : b; // expected-error {{operands to conditional of types 'id' and 'void *' are incompatible in ARC mode}}
   id d = 1 ? b : a; // expected-error {{operands to conditional of types 'void *' and 'id' are incompatible in ARC mode}}
 }
+
+void conversion_pointer_to_id(__strong id *x) {
+  struct S {
+    int a[2];
+  } s, *p;
+
+  x = (__strong id *)&s;
+  x = &s; // expected-error {{implicit conversion of a non-Objective-C pointer type 'struct S *' to '__strong id *' is disallowed with ARC}}
+  p = (struct S *)x;
+  p = x; // expected-error {{implicit conversion of an indirect pointer to an Objective-C pointer to 'struct S *' is disallowed with ARC}}
+}
Index: clang/lib/Sema/SemaExprObjC.cpp
===================================================================
--- clang/lib/Sema/SemaExprObjC.cpp
+++ clang/lib/Sema/SemaExprObjC.cpp
@@ -4453,9 +4453,14 @@
   // Allow casts between pointers to lifetime types (e.g., __strong id*)
   // and pointers to void (e.g., cv void *). Casting from void* to lifetime*
   // must be explicit.
-  if (exprACTC == ACTC_indirectRetainable && castACTC == ACTC_voidPtr)
+  // Allow conversions between pointers to lifetime types and coreFoundation
+  // pointers too, but only when the conversions are explicit.
+  if (exprACTC == ACTC_indirectRetainable &&
+      (castACTC == ACTC_voidPtr ||
+       (castACTC == ACTC_coreFoundation && isCast(CCK))))
     return ACR_okay;
-  if (castACTC == ACTC_indirectRetainable && exprACTC == ACTC_voidPtr &&
+  if (castACTC == ACTC_indirectRetainable &&
+      (exprACTC == ACTC_voidPtr || exprACTC == ACTC_coreFoundation) &&
       isCast(CCK))
     return ACR_okay;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D107021: [Sema][Obj... Akira Hatanaka via Phabricator via cfe-commits

Reply via email to