1 // RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-msvc -o - | FileCheck %s 2 3 // Statement allow the user to exit the evaluation scope of a CallExpr without 4 // executing the call. Check that clang generates reasonable IR for that case. 5 6 // Not trivially copyable, subject to inalloca. 7 struct Foo { 8 int x; 9 Foo(); 10 ~Foo(); 11 }; 12 13 void inalloca(Foo x, Foo y); 14 15 // PR25102: In this case, clang attempts to clean up unreachable blocks *during* 16 // IR generation. inalloca defers some RAUW operations to the end of codegen, 17 // and those references would become stale when the unreachable call to 18 // 'inalloca' got deleted. 19 extern "C" void pr25102() { 20 inalloca(Foo(), ({ 21 goto out; 22 Foo(); 23 })); 24 out:; 25 } 26 27 // CHECK-LABEL: define dso_local void @pr25102() 28 // CHECK: br label %out 29 // CHECK: out: 30 // CHECK: ret void 31 32 bool cond(); 33 extern "C" void seqAbort() { 34 inalloca(Foo(), ({ 35 if (cond()) 36 goto out; 37 Foo(); 38 })); 39 out:; 40 } 41 42 // FIXME: This can cause a stack leak. We should really have a "normal" cleanup 43 // that goto branches through. 44 // CHECK-LABEL: define dso_local void @seqAbort() 45 // CHECK: alloca inalloca <{ %struct.Foo, %struct.Foo }> 46 // CHECK: call noundef zeroext i1 @"?cond@@YA_NXZ"() 47 // CHECK: br i1 48 // CHECK: br label %out 49 // CHECK: call void @"?inalloca@@YAXUFoo@@0@Z"(<{ %struct.Foo, %struct.Foo }>* inalloca(<{ %struct.Foo, %struct.Foo }>) %{{.*}}) 50 // CHECK: call void @llvm.stackrestore(i8* %inalloca.save) 51 // CHECK: out: 52