1 // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-linux-gnu -emit-llvm -std=c++11 %s -o - | FileCheck -allow-deprecated-dag-overlap -check-prefix=CHECK-LIN -check-prefix=CHECK-LIN64 %s 2 // RUN: %clang_cc1 -no-opaque-pointers -triple i386-linux-gnu -emit-llvm -std=c++11 %s -o - | FileCheck -allow-deprecated-dag-overlap -check-prefix=CHECK-LIN -check-prefix=CHECK-LIN32 %s 3 // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-windows-msvc -emit-llvm -std=c++11 %s -o - -DWIN_TEST | FileCheck -allow-deprecated-dag-overlap -check-prefix=CHECK-WIN64 %s 4 // RUN: %clang_cc1 -no-opaque-pointers -triple i386-windows-msvc -emit-llvm -std=c++11 %s -o - -DWIN_TEST | FileCheck -allow-deprecated-dag-overlap -check-prefix=CHECK-WIN32 %s 5 6 int __regcall foo(int i); 7 8 int main() 9 { 10 int p = 0, _data; 11 auto lambda = [&](int parameter) -> int { 12 _data = foo(parameter); 13 return _data; 14 }; 15 return lambda(p); 16 } 17 // CHECK-LIN: call x86_regcallcc {{.+}} @_Z15__regcall3__foo 18 // CHECK-WIN64: call x86_regcallcc {{.+}} @"?foo@@YwHH@Z" 19 // CHECK-WIN32: call x86_regcallcc {{.+}} @"?foo@@YwHH@Z" 20 21 int __regcall foo (int i){ 22 return i; 23 } 24 // CHECK-LIN: define{{.*}} x86_regcallcc noundef {{.+}}@_Z15__regcall3__foo 25 // CHECK-WIN64: define dso_local x86_regcallcc noundef {{.+}}@"?foo@@YwHH@Z" 26 // CHECK-WIN32: define dso_local x86_regcallcc noundef {{.+}}@"?foo@@YwHH@Z" 27 28 // used to give a body to test_class functions 29 static int x = 0; 30 class test_class { 31 int a; 32 public: 33 #ifndef WIN_TEST 34 __regcall 35 #endif 36 test_class(){++x;} 37 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classC1Ev 38 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classC2Ev 39 // Windows ignores calling convention on constructor/destructors. 40 // CHECK-WIN64-DAG: define linkonce_odr dso_local noundef %class.test_class* @"??0test_class@@QEAA@XZ" 41 // CHECK-WIN32-DAG: define linkonce_odr dso_local x86_thiscallcc noundef %class.test_class* @"??0test_class@@QAE@XZ" 42 43 #ifndef WIN_TEST 44 __regcall 45 #endif 46 ~test_class(){--x;} 47 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD2Ev 48 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD1Ev 49 // Windows ignores calling convention on constructor/destructors. 50 // CHECK-WIN64-DAG: define linkonce_odr dso_local void @"??1test_class@@QEAA@XZ" 51 // CHECK-WIN32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"??1test_class@@QAE@XZ" 52 53 test_class& __regcall operator+=(const test_class&){ 54 return *this; 55 } 56 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc noundef nonnull align 4 dereferenceable(4) %class.test_class* @_ZN10test_classpLERKS_ 57 // CHECK-WIN64-DAG: define linkonce_odr dso_local x86_regcallcc noundef nonnull align 4 dereferenceable(4) %class.test_class* @"??Ytest_class@@QEAwAEAV0@AEBV0@@Z" 58 // CHECK-WIN32-DAG: define linkonce_odr dso_local x86_regcallcc noundef nonnull align 4 dereferenceable(4) %class.test_class* @"??Ytest_class@@QAwAAV0@ABV0@@Z" 59 void __regcall do_thing(){} 60 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_class20__regcall3__do_thingEv 61 // CHECK-WIN64-DAG: define linkonce_odr dso_local x86_regcallcc void @"?do_thing@test_class@@QEAwXXZ" 62 // CHECK-WIN32-DAG: define linkonce_odr dso_local x86_regcallcc void @"?do_thing@test_class@@QAwXXZ" 63 64 template<typename T> 65 void __regcall tempFunc(T i){} 66 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_class20__regcall3__tempFuncIiEEvT_ 67 // CHECK-WIN64-DAG: define linkonce_odr dso_local x86_regcallcc void @"??$freeTempFunc@H@@YwXH@Z" 68 // CHECK-WIN32-DAG: define linkonce_odr dso_local x86_regcallcc void @"??$freeTempFunc@H@@YwXH@Z" 69 }; 70 71 bool __regcall operator ==(const test_class&, const test_class&){ --x; return false;} 72 // CHECK-LIN-DAG: define{{.*}} x86_regcallcc noundef zeroext i1 @_ZeqRK10test_classS1_ 73 // CHECK-WIN64-DAG: define dso_local x86_regcallcc noundef zeroext i1 @"??8@Yw_NAEBVtest_class@@0@Z" 74 // CHECK-WIN32-DAG: define dso_local x86_regcallcc noundef zeroext i1 @"??8@Yw_NABVtest_class@@0@Z" 75 76 test_class __regcall operator""_test_class (unsigned long long) { ++x; return test_class{};} 77 // CHECK-LIN64-DAG: define{{.*}} x86_regcallcc void @_Zli11_test_classy(%class.test_class* noalias sret(%class.test_class) align 4 %agg.result, i64 noundef %0) 78 // CHECK-LIN32-DAG: define{{.*}} x86_regcallcc void @_Zli11_test_classy(%class.test_class* inreg noalias sret(%class.test_class) align 4 %agg.result, i64 noundef %0) 79 // CHECK-WIN64-DAG: ??__K_test_class@@Yw?AVtest_class@@_K@Z" 80 // CHECK-WIN32-DAG: ??__K_test_class@@Yw?AVtest_class@@_K@Z" 81 82 template<typename T> 83 void __regcall freeTempFunc(T i){} 84 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_Z24__regcall3__freeTempFuncIiEvT_ 85 // CHECK-WIN64-DAG: define linkonce_odr dso_local x86_regcallcc void @"??$freeTempFunc@H@@YwXH@Z" 86 // CHECK-WIN32-DAG: define linkonce_odr dso_local x86_regcallcc void @"??$freeTempFunc@H@@YwXH@Z" 87 88 // class to force generation of functions 89 void force_gen() { 90 test_class t; 91 test_class t2 = 12_test_class; 92 t += t2; 93 auto t3 = 100_test_class; 94 t3.tempFunc(1); 95 freeTempFunc(1); 96 t3.do_thing(); 97 } 98 99 long double _Complex __regcall foo(long double _Complex f) { 100 return f; 101 } 102 // CHECK-LIN64-DAG: define{{.*}} x86_regcallcc void @_Z15__regcall3__fooCe({ x86_fp80, x86_fp80 }* noalias sret({ x86_fp80, x86_fp80 }) align 16 %agg.result, { x86_fp80, x86_fp80 }* noundef byval({ x86_fp80, x86_fp80 }) align 16 %f) 103 // CHECK-LIN32-DAG: define{{.*}} x86_regcallcc void @_Z15__regcall3__fooCe({ x86_fp80, x86_fp80 }* inreg noalias sret({ x86_fp80, x86_fp80 }) align 4 %agg.result, { x86_fp80, x86_fp80 }* noundef byval({ x86_fp80, x86_fp80 }) align 4 %f) 104 // CHECK-WIN64-DAG: define dso_local x86_regcallcc noundef { double, double } @"?foo@@YwU?$_Complex@O@__clang@@U12@@Z"(double noundef %f.0, double noundef %f.1) 105 // CHECK-WIN32-DAG: define dso_local x86_regcallcc noundef { double, double } @"?foo@@YwU?$_Complex@O@__clang@@U12@@Z"(double noundef %f.0, double noundef %f.1) 106 107 // The following caused us to dereference uninitialized memory. The long name 108 // seems necessary, as does the return types. 109 float _Complex __regcall callee(float _Complex f); 110 // CHECK-LIN64-DAG: declare x86_regcallcc noundef <2 x float> @_Z18__regcall3__calleeCf(<2 x float> noundef) 111 // CHECK-LIN32-DAG: declare x86_regcallcc noundef { float, float } @_Z18__regcall3__calleeCf(float noundef, float noundef) 112 // CHECK-WIN64-DAG: declare dso_local x86_regcallcc noundef { float, float } @"?callee@@YwU?$_Complex@M@__clang@@U12@@Z"(float noundef, float noundef) 113 // CHECK-WIN32-DAG: declare dso_local x86_regcallcc noundef { float, float } @"?callee@@YwU?$_Complex@M@__clang@@U12@@Z"(float noundef, float noundef) 114 115 __regcall int 116 some_really_long_name_that_manages_to_hit_the_right_spot_of_mem(int a) { 117 float _Complex x[2]; 118 x[0] = callee(x[0]); 119 return a; 120 } 121