19b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -cxx-abi microsoft -fexceptions | FileCheck -check-prefix WIN32 %s 29b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner 39b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Klecknerstruct A { 49b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner A(); 59b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner ~A(); 69b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner int a; 79b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner}; 89b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner 99b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid KlecknerA getA(); 109b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner 119b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Klecknerint TakesTwo(A a, A b); 129b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Klecknervoid HasEHCleanup() { 139b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner TakesTwo(getA(), getA()); 149b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner} 159b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner 169b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// With exceptions, we need to clean up at least one of these temporaries. 179b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: define void @"\01?HasEHCleanup@@YAXXZ"() {{.*}} { 189b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// First one doesn't have any cleanups, no need for invoke. 199b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: call void @"\01?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}}) 209b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// If this call throws, we have to cleanup the first temporary. 219b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke void @"\01?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}}) 229b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// If this call throws, we already popped our cleanups 239b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: call i32 @"\01?TakesTwo@@YAHUA@@0@Z" 249b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: ret void 259b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// 269b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// There should be one dtor call for unwinding from the second getA. 279b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" 289b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: } 299b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner 309b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Klecknervoid TakeRef(const A &a); 319b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Klecknerint HasDeactivatedCleanups() { 329b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner return TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A())); 339b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner} 349b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner 359b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: define i32 @"\01?HasDeactivatedCleanups@@YAHXZ"() {{.*}} { 369b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: %[[isactive:.*]] = alloca i1 379b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 389b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 399b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1:.*]]) 409b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 true, i1* %[[isactive]] 419b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 429b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 439b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 449b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 false, i1* %[[isactive]] 459b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z" 469b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// Destroy the two const ref temporaries. 479b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" 489b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ" 499b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: ret i32 509b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// 519b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// Conditionally destroy arg1. 529b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: %[[cond:.*]] = load i1* %[[isactive]] 539b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: br i1 %[[cond]] 549b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg1]]) 559b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: } 569b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner 579b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// Test putting the cleanups inside a conditional. 589b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Klecknerint CouldThrow(); 599b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Klecknerint HasConditionalCleanup(bool cond) { 609b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner return (cond ? TakesTwo(A(), A()) : CouldThrow()); 619b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner} 629b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner 639b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: define i32 @"\01?HasConditionalCleanup@@YAH_N@Z"(i1 zeroext %{{.*}}) {{.*}} { 649b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 false 659b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: br i1 669b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// No cleanups, so we call and then activate a cleanup if it succeeds. 679b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1:.*]]) 689b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 true 699b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// Now we have a cleanup for the first aggregate, so we invoke. 709b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %{{.*}}) 719b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// Now we have no cleanups because TakeTwo will destruct both args. 729b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: call i32 @"\01?TakesTwo@@YAHUA@@0@Z" 739b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// Still no cleanups, so call. 749b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: call i32 @"\01?CouldThrow@@YAHXZ"() 759b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// Somewhere in the landing pad for our single invoke, call the dtor. 769b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg1]]) 779b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: } 789b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner 799b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// Now test both. 809b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Klecknerint HasConditionalDeactivatedCleanups(bool cond) { 819b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner return (cond ? TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A())) : CouldThrow()); 829b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner} 839b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner 849b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: define i32 @"\01?HasConditionalDeactivatedCleanups@@YAH_N@Z"{{.*}} { 859b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: %[[arg1:.*]] = alloca %struct.A, align 4 869b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: alloca i1 879b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: %[[arg1_cond:.*]] = alloca i1 889b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// Start all four cleanups as deactivated. 899b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 false 909b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 false 919b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 false 929b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 false 939b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: br i1 949b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// True condition. 959b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 969b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 true 979b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 989b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1]]) 999b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 true, i1* %[[arg1_cond]] 1009b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 1019b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 true 1029b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" 1039b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" 1049b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 true 1059b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: store i1 false, i1* %[[arg1_cond]] 1069b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z" 1079b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// False condition. 1089b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke i32 @"\01?CouldThrow@@YAHXZ"() 1099b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// Two normal cleanups for TakeRef args. 1109b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" 1119b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ" 1129b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: ret i32 1139b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// 1149b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// Somewhere in the landing pad soup, we conditionally destroy arg1. 1159b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: %[[isactive:.*]] = load i1* %[[arg1_cond]] 1169b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: br i1 %[[isactive]] 1179b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg1]]) 1189b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner// WIN32: } 119