1// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -cxx-abi microsoft -fexceptions | FileCheck -check-prefix WIN32 %s 2 3struct A { 4 A(); 5 ~A(); 6 int a; 7}; 8 9A getA(); 10 11int TakesTwo(A a, A b); 12void HasEHCleanup() { 13 TakesTwo(getA(), getA()); 14} 15 16// With exceptions, we need to clean up at least one of these temporaries. 17// WIN32: define void @"\01?HasEHCleanup@@YAXXZ"() {{.*}} { 18// First one doesn't have any cleanups, no need for invoke. 19// WIN32: call void @"\01?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}}) 20// If this call throws, we have to cleanup the first temporary. 21// WIN32: invoke void @"\01?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}}) 22// If this call throws, we already popped our cleanups 23// WIN32: call i32 @"\01?TakesTwo@@YAHUA@@0@Z" 24// WIN32: ret void 25// 26// There should be one dtor call for unwinding from the second getA. 27// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" 28// WIN32: } 29 30void TakeRef(const A &a); 31int HasDeactivatedCleanups() { 32 return TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A())); 33} 34 35// WIN32: define i32 @"\01?HasDeactivatedCleanups@@YAHXZ"() {{.*}} { 36// WIN32: %[[isactive:.*]] = alloca i1 37// WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 38// WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 39// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1:.*]]) 40// WIN32: store i1 true, i1* %[[isactive]] 41// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 42// WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 43// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 44// WIN32: store i1 false, i1* %[[isactive]] 45// WIN32: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z" 46// Destroy the two const ref temporaries. 47// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" 48// WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ" 49// WIN32: ret i32 50// 51// Conditionally destroy arg1. 52// WIN32: %[[cond:.*]] = load i1* %[[isactive]] 53// WIN32: br i1 %[[cond]] 54// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg1]]) 55// WIN32: } 56 57// Test putting the cleanups inside a conditional. 58int CouldThrow(); 59int HasConditionalCleanup(bool cond) { 60 return (cond ? TakesTwo(A(), A()) : CouldThrow()); 61} 62 63// WIN32: define i32 @"\01?HasConditionalCleanup@@YAH_N@Z"(i1 zeroext %{{.*}}) {{.*}} { 64// WIN32: store i1 false 65// WIN32: br i1 66// No cleanups, so we call and then activate a cleanup if it succeeds. 67// WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1:.*]]) 68// WIN32: store i1 true 69// Now we have a cleanup for the first aggregate, so we invoke. 70// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %{{.*}}) 71// Now we have no cleanups because TakeTwo will destruct both args. 72// WIN32: call i32 @"\01?TakesTwo@@YAHUA@@0@Z" 73// Still no cleanups, so call. 74// WIN32: call i32 @"\01?CouldThrow@@YAHXZ"() 75// Somewhere in the landing pad for our single invoke, call the dtor. 76// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg1]]) 77// WIN32: } 78 79// Now test both. 80int HasConditionalDeactivatedCleanups(bool cond) { 81 return (cond ? TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A())) : CouldThrow()); 82} 83 84// WIN32: define i32 @"\01?HasConditionalDeactivatedCleanups@@YAH_N@Z"{{.*}} { 85// WIN32: %[[arg1:.*]] = alloca %struct.A, align 4 86// WIN32: alloca i1 87// WIN32: %[[arg1_cond:.*]] = alloca i1 88// Start all four cleanups as deactivated. 89// WIN32: store i1 false 90// WIN32: store i1 false 91// WIN32: store i1 false 92// WIN32: store i1 false 93// WIN32: br i1 94// True condition. 95// WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 96// WIN32: store i1 true 97// WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 98// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1]]) 99// WIN32: store i1 true, i1* %[[arg1_cond]] 100// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 101// WIN32: store i1 true 102// WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 103// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 104// WIN32: store i1 true 105// WIN32: store i1 false, i1* %[[arg1_cond]] 106// WIN32: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z" 107// False condition. 108// WIN32: invoke i32 @"\01?CouldThrow@@YAHXZ"() 109// Two normal cleanups for TakeRef args. 110// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" 111// WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ" 112// WIN32: ret i32 113// 114// Somewhere in the landing pad soup, we conditionally destroy arg1. 115// WIN32: %[[isactive:.*]] = load i1* %[[arg1_cond]] 116// WIN32: br i1 %[[isactive]] 117// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg1]]) 118// WIN32: } 119