]> granicus.if.org Git - clang/commitdiff
In ARC mode, consider Objective-C lifetime types (object pointers and
authorDouglas Gregor <dgregor@apple.com>
Tue, 12 Jul 2011 17:28:52 +0000 (17:28 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 12 Jul 2011 17:28:52 +0000 (17:28 +0000)
block pointers) that don't have any qualification to be POD types. We
were previously considering them to be non-POD types, because this was
convenient in C++ for is_pod-like traits. However, we now end up
inferring lifetime in such cases (template arguments infer __strong),
so it is not necessary.

Moreover, we want rvalues of object type (which have their lifetime
stripped) to be PODs to allow, e.g., va_arg(arglist, id) to function
properly. Fixes <rdar://problem/9758798>.

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

lib/AST/Type.cpp
test/ARCMT/cxx-checking.mm
test/CodeGenObjC/arc.m
test/SemaObjC/arc.m
test/SemaObjCXX/arc-non-pod.mm

index 1f0a37efac0070e317c0fa8aaae5305111073a46..08971eb0342158cf1ee89fced02193292f02c3ac 100644 (file)
@@ -915,8 +915,6 @@ bool QualType::isPODType(ASTContext &Context) const {
       return false;
 
     case Qualifiers::OCL_None:
-      if ((*this)->isObjCLifetimeType())
-        return false;
       break;
     }        
   }
index c298b94b82bdb0be0eec8690601a51dc58697d70..27e0ea3869b8fbf483cb8f5b55746ff19aded6f7 100644 (file)
@@ -75,12 +75,12 @@ struct HasBlockPointerMemberAndNonPOD1 { // expected-warning{{'HasBlockPointerMe
   int (^bp[2][3])(int);
 };
 
-int check_non_pod_objc_pointer0[__is_pod(id)? -1 : 1];
+int check_non_pod_objc_pointer0[__is_pod(id)? 1 : -1];
 int check_non_pod_objc_pointer1[__is_pod(__strong id)? -1 : 1];
 int check_non_pod_objc_pointer2[__is_pod(__unsafe_unretained id)? 1 : -1];
-int check_non_pod_objc_pointer3[__is_pod(id[2][3])? -1 : 1];
+int check_non_pod_objc_pointer3[__is_pod(id[2][3])? 1 : -1];
 int check_non_pod_objc_pointer4[__is_pod(__unsafe_unretained id[2][3])? 1 : -1];
-int check_non_pod_block0[__is_pod(int (^)(int))? -1 : 1];
+int check_non_pod_block0[__is_pod(int (^)(int))? 1 : -1];
 int check_non_pod_block1[__is_pod(int (^ __unsafe_unretained)(int))? 1 : -1];
 
 struct FlexibleArrayMember0 {
index df3968722e7fa657be9094f06a57e232b2ede82d..55b7747aa6148fa4f824f7a612793b780fb3f5cc 100644 (file)
@@ -1526,3 +1526,17 @@ void test53(void) {
 // CHECK-NEXT: call void @objc_release(i8* [[T0]])
 // CHECK-NEXT: ret void
 }
+
+// <rdar://problem/9758798>
+// CHECK: define void @test54(i32 %first, ...)
+void test54(int first, ...) {
+  __builtin_va_list arglist;
+  // CHECK: call void @llvm.va_start
+  __builtin_va_start(arglist, first);
+  // CHECK: call i8* @objc_retain
+  id obj = __builtin_va_arg(arglist, id);
+  // CHECK: call void @llvm.va_end
+  __builtin_va_end(arglist);
+  // CHECK: call void @objc_release
+  // CHECK: ret void
+}
index 61dc0e052541edcd879e86763ef2c2dba7672cd0..3d190e5c53a011e6c169489dac2dba2a2e6571fd 100644 (file)
@@ -618,3 +618,11 @@ void test35(void) {
 
   __strong int non_objc_type; // expected-warning {{'__strong' only applies to objective-c object or block pointer types}} 
 }
+
+void test36(int first, ...) {
+  // <rdar://problem/9758798>
+  __builtin_va_list arglist;
+  __builtin_va_start(arglist, first);
+  id obj = __builtin_va_arg(arglist, id);
+  __builtin_va_end(arglist);
+}
index 6c809bb7b35b58149ae213507b8c29b795f3c18b..6a47b3d85664b1fc1f2925d18385ccc7c3d4a1b3 100644 (file)
@@ -75,13 +75,14 @@ struct HasBlockPointerMemberAndNonPOD1 { // expected-warning{{'HasBlockPointerMe
   int (^bp[2][3])(int);
 };
 
-int check_non_pod_objc_pointer0[__is_pod(id)? -1 : 1];
+int check_non_pod_objc_pointer0[__is_pod(id)? 1 : -1];
 int check_non_pod_objc_pointer1[__is_pod(__strong id)? -1 : 1];
 int check_non_pod_objc_pointer2[__is_pod(__unsafe_unretained id)? 1 : -1];
-int check_non_pod_objc_pointer3[__is_pod(id[2][3])? -1 : 1];
+int check_non_pod_objc_pointer3[__is_pod(id[2][3])? 1 : -1];
 int check_non_pod_objc_pointer4[__is_pod(__unsafe_unretained id[2][3])? 1 : -1];
-int check_non_pod_block0[__is_pod(int (^)(int))? -1 : 1];
+int check_non_pod_block0[__is_pod(int (^)(int))? 1 : -1];
 int check_non_pod_block1[__is_pod(int (^ __unsafe_unretained)(int))? 1 : -1];
+int check_non_pod_block2[__is_pod(int (^ __strong)(int))? -1 : 1];
 
 struct FlexibleArrayMember0 {
   int length;