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.
pr25102()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();
seqAbort()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 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