diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -981,7 +981,8 @@ // precise source location of the checked return statement. if (requiresReturnValueCheck()) { ReturnLocation = CreateDefaultAlignTempAlloca(Int8PtrTy, "return.sloc.ptr"); - InitTempAlloca(ReturnLocation, llvm::ConstantPointerNull::get(Int8PtrTy)); + Builder.CreateStore(llvm::ConstantPointerNull::get(Int8PtrTy), + ReturnLocation); } // Emit subprogram debug descriptor. diff --git a/clang/test/CodeGenObjC/static-alloc-init.m b/clang/test/CodeGenObjC/static-alloc-init.m new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenObjC/static-alloc-init.m @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s + +typedef struct { + int x[12]; +} Big; + +@protocol P +- (Big) foo; +@end + +// CHECK-LABEL: define{{.*}} void @test( +// CHECK: %p.addr = alloca i8*, align 8 +// CHECK-NEXT: %big = alloca %struct.Big, align 4 +// CHECK-NEXT: %tmp = alloca i8*, align 8 +// CHECK-NEXT: store i8* %p, i8** %p.addr, align 8 +// CHECK-NEXT: br label %for.cond +// +// CHECK-LABEL: for.cond: +// CHECK: %0 = load i8*, i8** %p.addr, align 8 +// CHECK-NEXT: %1 = icmp eq i8* %0, null +// CHECK-NEXT: br i1 %1, label %nilReceiverCleanup, label %msgSend +// +// CHECK-LABEL: msgSend: +// CHECK: store i8* %0, i8** %tmp, align 8 +// CHECK-NEXT: %2 = call { i8*, i8*, i8*, i32, i8* (i8*, i8*, ...)* }* @objc_msg_lookup_sender(i8** %tmp, i8* bitcast ({ i8*, i8* }* @".objc_selector_foo_{?=[12i]}16\010:8" to i8*), i8* null) +// CHECK-NEXT: %3 = getelementptr inbounds { i8*, i8*, i8*, i32, i8* (i8*, i8*, ...)* }, { i8*, i8*, i8*, i32, i8* (i8*, i8*, ...)* }* %2, i32 0, i32 4 +// CHECK-NEXT: %4 = load i8* (i8*, i8*, ...)*, i8* (i8*, i8*, ...)** %3, align 8 +// CHECK-NEXT: %5 = load volatile i8*, i8** %tmp, align 8 +// CHECK-NEXT: %6 = bitcast i8* (i8*, i8*, ...)* %4 to void (%struct.Big*, i8*, i8*)* +// CHECK-NEXT: call void %6(%struct.Big* sret(%struct.Big) align 4 %big, i8* %5, i8* bitcast ({ i8*, i8* }* @".objc_selector_foo_{?=[12i]}16\010:8" to i8*)) +// CHECK-NEXT: br label %continue +// +// CHECK-LABEL: nilReceiverCleanup: +// CHECK: %7 = bitcast %struct.Big* %big to i8* +// CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 %7, i8 0, i64 48, i1 false) +// CHECK-NEXT: br label %continue +// +// CHECK-LABEL: continue: +// CHECK: br label %for.cond + +void test(id
p) { + for (;;) { + Big big = [p foo]; + } +}