File: windows-seh-EHa-CppCondiTemps.cpp

package info (click to toggle)
llvm-toolchain-13 1%3A13.0.1-11
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,418,840 kB
  • sloc: cpp: 5,290,826; ansic: 996,570; asm: 544,593; python: 188,212; objc: 72,027; lisp: 30,291; f90: 25,395; sh: 24,898; javascript: 9,780; pascal: 9,398; perl: 7,484; ml: 5,432; awk: 3,523; makefile: 2,913; xml: 953; cs: 573; fortran: 539
file content (129 lines) | stat: -rw-r--r-- 4,070 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// RUN: %clang_cc1 -triple x86_64-windows -fasync-exceptions -fcxx-exceptions -fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s

// CHECK: define dso_local i32 @"?bar@@YAHHVB1@@VB2@@@Z"
// CHECK: %coerce.dive1 = getelementptr inbounds %class.B2
// CHECK: %coerce.dive2 = getelementptr inbounds %class.B1
// -----   scope begin of two passed-by-value temps  
// CHECK: invoke void @llvm.seh.scope.begin()
// CHECK: invoke void @llvm.seh.scope.begin()
// CHECK: invoke void @llvm.seh.scope.end()
// CHECK: call void @"??1B1@@QEAA@XZ"
// CHECK: invoke void @llvm.seh.scope.end()
// CHECK: call void @"??1B2@@QEAA@XZ"

// CHECK: define linkonce_odr dso_local void @"??1B2@@QEAA@XZ"
// CHECK: %this.addr = alloca %class.B2*
// -----  B1 scope begin without base ctor
// CHECK: invoke void @llvm.seh.scope.begin()
// CHECK: invoke void @llvm.seh.scope.end()
// CHECK: call void @"??1B1@@QEAA@XZ"

// CHECK: define dso_local void @"?goo@@YA?AVB1@@H@Z"
// CHECK: call %class.B2* @"??0B2@@QEAA@XZ"(%class.B2*
// CHECK: invoke void @llvm.seh.scope.begin()
// check: call void @llvm.memcpy
// CHECK: invoke void @llvm.seh.scope.end()
// CHECK: call void @"??1B2@@QEAA@XZ"(%class.B2*

// CHECK: define linkonce_odr dso_local %class.B2* @"??0B2@@QEAA@XZ"
// CHECK: call %class.B1* @"??0B1@@QEAA@XZ"(%class.B1*
// -----  scope begin of base ctor 
// CHECK: invoke void @llvm.seh.scope.begin()
// CHECK: invoke void @llvm.seh.scope.end()
// -----  B1 scope end without base dtor

// ****************************************************************************
// Abstract:     Test CPP Conditional-Expr & ABI Temps under SEH -EHa option

void printf(...);

int xxxx = 0;
int* ptr; 

int foo(int a)
{
  return xxxx + a;
}

class B1      {
public:
   int data = 90;
   B1() { foo(data + 111); }
    ~B1() { printf("in B1 Dtor \n"); }
};
class B2 : public B1 {
public:
  B2() { foo(data + 222); }
  ~B2() { printf("in B2 Dtor \n");; }
};
class B3 : public B2 {
public:
  B3() { foo(data + 333); }
  ~B3() { printf("in B3 Dtor \n");; }
};

int bar(int j, class B1 b1Bar, class B2 b2Bar)
{
  int ww;
  if ( j > 0)
    ww = b1Bar.data;
  else
    ww = b2Bar.data;
  return  ww + *ptr;
}

class B1 goo(int w)
{
  class B2 b2ingoo;
  b2ingoo.data += w;
  return b2ingoo;
}

// CHECK: define dso_local i32 @main()
// CHECK: invoke void @llvm.seh.scope.begin()
// ---   beginning of conditional temp test
// CHECK: invoke %class.B2* @"??0B2@@QEAA@XZ"
// CHECK: invoke void @llvm.seh.scope.begin()
// CHECK: invoke %class.B3* @"??0B3@@QEAA@XZ"
// CHECK: invoke void @llvm.seh.scope.begin()
// CHECK: invoke void @llvm.seh.scope.end()
// CHECK: call void @"??1B3@@QEAA@XZ"
// CHECK: invoke void @llvm.seh.scope.end()
// CHECK: call void @"??1B2@@QEAA@XZ"
// -----  end of conditional temp test

// -----  testing caller's passed-by-value temps
//        setting scope in case exception occurs before the call
// check: invoke %class.B2* @"??0B2@@QEAA@XZ"
// CHECK: invoke void @llvm.seh.scope.begin()
// CHECK: invoke %class.B1* @"??0B1@@QEAA@XZ"
// CHECK: invoke void @llvm.seh.scope.begin()
// -----   end of temps' scope right before callee
// CHECK: invoke void @llvm.seh.scope.end()
// CHECK: invoke void @llvm.seh.scope.end()
// CHECK: invoke i32 @"?bar@@YAHHVB1@@VB2@@@Z"

// -----  testing caller's return-by-value temp
//        scope begins right after callee which is the ctor of return temp
// CHECK: void @"?goo@@YA?AVB1@@H@Z"
// CHECK: invoke void @llvm.seh.scope.begin()
// CHECK: invoke void @llvm.seh.scope.end()

int main() {
  class B3 b3inmain;

  // Test conditional ctor and dtor
  int m = (xxxx > 1) ? B2().data + foo(99) : 
      B3().data + foo(88);

  // Test: passed-in by value
  // Per Windows ABI, ctored by caller, dtored by callee
  int i = bar(foo(0), B1(), B2());

  // Test: returned by value
  // Per Windows ABI, caller allocate a temp in stack, then ctored by callee, 
  //          finally dtored in caller after consumed
  class B1 b1fromgoo = goo(i);

  return m + b1fromgoo.data + b3inmain.data;
}