brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.9 KiB · 0cdf230 Raw
291 lines · c
1// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -O1 -disable-llvm-passes -o - | FileCheck %s2// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -O1 -disable-llvm-passes -o - | FileCheck %s3// RUN: %clang_cc1 %s -triple aarch64-windows -fms-extensions -emit-llvm -O1 -disable-llvm-passes -o - | FileCheck %s4// NOTE: we're passing "-O1 -disable-llvm-passes" to avoid adding optnone and noinline everywhere.5 6void abort(void) __attribute__((noreturn));7void might_crash(void);8void cleanup(void);9int check_condition(void);10void basic_finally(void) {11  __try {12    might_crash();13  } __finally {14    cleanup();15  }16}17 18// CHECK-LABEL: define dso_local void @basic_finally()19// CHECK: invoke void @might_crash()20// CHECK:     to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]21//22// CHECK: [[invoke_cont]]23// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()24// CHECK: call void @"?fin$0@0@basic_finally@@"({{i8 noundef( zeroext)?}} 0, ptr noundef %[[fp]])25// CHECK-NEXT: ret void26//27// CHECK: [[lpad]]28// CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad29// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()30// CHECK: call void @"?fin$0@0@basic_finally@@"({{i8 noundef( zeroext)?}} 1, ptr noundef %[[fp]])31// CHECK-NEXT: cleanupret from %[[pad]] unwind to caller32 33// CHECK: define internal void @"?fin$0@0@basic_finally@@"({{.*}})34// CHECK-SAME: [[finally_attrs:#[0-9]+]]35// CHECK: call void @cleanup()36 37// Mostly check that we don't double emit 'r' which would crash.38void decl_in_finally(void) {39  __try {40    might_crash();41  } __finally {42    int r;43  }44}45 46// Ditto, don't crash double emitting 'l'.47void label_in_finally(void) {48  __try {49    might_crash();50  } __finally {51l:52    cleanup();53    if (check_condition())54      goto l;55  }56}57 58// CHECK-LABEL: define dso_local void @label_in_finally()59// CHECK: invoke void @might_crash()60// CHECK:     to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]61//62// CHECK: [[invoke_cont]]63// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()64// CHECK: call void @"?fin$0@0@label_in_finally@@"({{i8 noundef( zeroext)?}} 0, ptr noundef %[[fp]])65// CHECK: ret void66 67// CHECK: define internal void @"?fin$0@0@label_in_finally@@"({{.*}})68// CHECK-SAME: [[finally_attrs]]69// CHECK: br label %[[l:[^ ]*]]70//71// CHECK: [[l]]72// CHECK: call void @cleanup()73// CHECK: call i32 @check_condition()74// CHECK: br i1 {{.*}}, label75// CHECK: br label %[[l]]76 77int crashed;78void use_abnormal_termination(void) {79  __try {80    might_crash();81  } __finally {82    crashed = __abnormal_termination();83  }84}85 86// CHECK-LABEL: define dso_local void @use_abnormal_termination()87// CHECK: invoke void @might_crash()88// CHECK:     to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]89//90// CHECK: [[invoke_cont]]91// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()92// CHECK: call void @"?fin$0@0@use_abnormal_termination@@"({{i8 noundef( zeroext)?}} 0, ptr noundef %[[fp]])93// CHECK: ret void94//95// CHECK: [[lpad]]96// CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad97// CHECK: %[[fp:[^ ]*]] = call ptr @llvm.localaddress()98// CHECK: call void @"?fin$0@0@use_abnormal_termination@@"({{i8 noundef( zeroext)?}} 1, ptr noundef %[[fp]])99// CHECK-NEXT: cleanupret from %[[pad]] unwind to caller100 101// CHECK: define internal void @"?fin$0@0@use_abnormal_termination@@"({{i8 noundef( zeroext)?}} %[[abnormal:abnormal_termination]], ptr noundef %frame_pointer)102// CHECK-SAME: [[finally_attrs]]103// CHECK: %[[abnormal_zext:[^ ]*]] = zext i8 %[[abnormal]] to i32104// CHECK: store i32 %[[abnormal_zext]], ptr @crashed105// CHECK-NEXT: ret void106 107void noreturn_noop_finally(void) {108  __try {109    __noop();110  } __finally {111    abort();112  }113}114 115// CHECK-LABEL: define dso_local void @noreturn_noop_finally()116// CHECK: call void @"?fin$0@0@noreturn_noop_finally@@"({{.*}})117// CHECK: ret void118 119// CHECK: define internal void @"?fin$0@0@noreturn_noop_finally@@"({{.*}})120// CHECK-SAME: [[finally_attrs]]121// CHECK: call void @abort()122// CHECK: unreachable123 124void noreturn_finally(void) {125  __try {126    might_crash();127  } __finally {128    abort();129  }130}131 132// CHECK-LABEL: define dso_local void @noreturn_finally()133// CHECK: invoke void @might_crash()134// CHECK:     to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]135//136// CHECK: [[cont]]137// CHECK: call void @"?fin$0@0@noreturn_finally@@"({{.*}})138// CHECK: ret void139//140// CHECK: [[lpad]]141// CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad142// CHECK: call void @"?fin$0@0@noreturn_finally@@"({{.*}})143// CHECK-NEXT: cleanupret from %[[pad]] unwind to caller144 145// CHECK: define internal void @"?fin$0@0@noreturn_finally@@"({{.*}})146// CHECK-SAME: [[finally_attrs]]147// CHECK: call void @abort()148// CHECK: unreachable149 150int finally_with_return(void) {151  __try {152    return 42;153  } __finally {154  }155}156// CHECK-LABEL: define dso_local i32 @finally_with_return()157// CHECK: store i32 1, ptr %cleanup.dest.slot158// CHECK: %cleanup.dest = load i32, ptr %cleanup.dest.slot159// CHECK: icmp ne i32 %cleanup.dest160// CHECK: call void @"?fin$0@0@finally_with_return@@"({{.*}})161// CHECK: ret i32 42162 163// CHECK: define internal void @"?fin$0@0@finally_with_return@@"({{.*}})164// CHECK-SAME: [[finally_attrs]]165// CHECK-NOT: br i1166// CHECK-NOT: br label167// CHECK: ret void168 169int nested___finally___finally(void) {170  __try {171    __try {172    } __finally {173      return 1;174    }175  } __finally {176    // Intentionally no return here.177  }178  return 0;179}180 181// CHECK-LABEL: define dso_local i32 @nested___finally___finally182// CHECK: invoke void @"?fin$1@0@nested___finally___finally@@"({{.*}})183// CHECK:          to label %[[outercont:[^ ]*]] unwind label %[[lpad:[^ ]*]]184//185// CHECK: [[outercont]]186// CHECK: call void @"?fin$0@0@nested___finally___finally@@"({{.*}})187// CHECK-NEXT: ret i32 0188//189// CHECK: [[lpad]]190// CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad191// CHECK: call void @"?fin$0@0@nested___finally___finally@@"({{.*}})192// CHECK-NEXT: cleanupret from %[[pad]] unwind to caller193 194// CHECK-LABEL: define internal void @"?fin$0@0@nested___finally___finally@@"({{.*}})195// CHECK-SAME: [[finally_attrs]]196// CHECK: ret void197 198// CHECK-LABEL: define internal void @"?fin$1@0@nested___finally___finally@@"({{.*}})199// CHECK-SAME: [[finally_attrs]]200// CHECK: unreachable201 202// FIXME: Our behavior seems suspiciously different.203 204int nested___finally___finally_with_eh_edge(void) {205  __try {206    __try {207      might_crash();208    } __finally {209      return 899;210    }211  } __finally {212    // Intentionally no return here.213  }214  return 912;215}216// CHECK-LABEL: define dso_local i32 @nested___finally___finally_with_eh_edge217// CHECK: invoke void @might_crash()218// CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad1:[^ ]*]]219//220// [[invokecont]]221// CHECK: invoke void @"?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})222// CHECK-NEXT:       to label %[[outercont:[^ ]*]] unwind label %[[lpad2:[^ ]*]]223//224// CHECK: [[outercont]]225// CHECK: call void @"?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})226// CHECK-NEXT: ret i32 912227//228// CHECK: [[lpad1]]229// CHECK-NEXT: %[[innerpad:[^ ]*]] = cleanuppad230// CHECK: invoke void @"?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})231// CHECK-NEXT:    label %[[innercleanupretbb:[^ ]*]] unwind label %[[lpad2:[^ ]*]]232//233// CHECK: [[innercleanupretbb]]234// CHECK-NEXT: cleanupret from %[[innerpad]] unwind label %[[lpad2]]235//236// CHECK: [[lpad2]]237// CHECK-NEXT: %[[outerpad:[^ ]*]] = cleanuppad238// CHECK: call void @"?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})239// CHECK-NEXT: cleanupret from %[[outerpad]] unwind to caller240 241// CHECK-LABEL: define internal void @"?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})242// CHECK-SAME: [[finally_attrs]]243// CHECK: ret void244 245// CHECK-LABEL: define internal void @"?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})246// CHECK-SAME: [[finally_attrs]]247// CHECK: unreachable248 249void finally_within_finally(void) {250  __try {251    might_crash();252  } __finally {253    __try {254      might_crash();255    } __finally {256    }257  }258}259 260// CHECK-LABEL: define dso_local void @finally_within_finally(261// CHECK: invoke void @might_crash(262 263// CHECK: call void @"?fin$0@0@finally_within_finally@@"(264// CHECK: call void @"?fin$0@0@finally_within_finally@@"({{.*}}) [ "funclet"(265 266// CHECK-LABEL: define internal void @"?fin$0@0@finally_within_finally@@"({{[^)]*}})267// CHECK-SAME: [[finally_attrs]]268// CHECK: invoke void @might_crash(269 270// CHECK: call void @"?fin$1@0@finally_within_finally@@"(271// CHECK: call void @"?fin$1@0@finally_within_finally@@"({{.*}}) [ "funclet"(272 273// CHECK-LABEL: define internal void @"?fin$1@0@finally_within_finally@@"({{[^)]*}})274// CHECK-SAME: [[finally_attrs]]275 276void cleanup_with_func(const char *);277void finally_with_func(void) {278  __try {279    might_crash();280  } __finally {281    cleanup_with_func(__func__);282  }283}284 285// CHECK-LABEL: define internal void @"?fin$0@0@finally_with_func@@"({{[^)]*}})286// CHECK: call void @cleanup_with_func(ptr noundef @"??_C@_0BC@COAGBPGM@finally_with_func?$AA@")287 288// Look for the absence of noinline.  nounwind is expected; any further289// attributes should be string attributes.290// CHECK: attributes [[finally_attrs]] = { nounwind "{{.*}}" }291