In ARC mode, consider Objective-C lifetime types (object pointers and
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>. llvm-svn: 134993
This commit is contained in:
parent
7f4427fc60
commit
7e6bfb4a0d
|
@ -915,8 +915,6 @@ bool QualType::isPODType(ASTContext &Context) const {
|
|||
return false;
|
||||
|
||||
case Qualifiers::OCL_None:
|
||||
if ((*this)->isObjCLifetimeType())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue