Skip to content

Commit 2cf9e9d

Browse files
committed
[CIR][CodeGen] Fix std::ofstream fail during CodeGen
1 parent 5a75305 commit 2cf9e9d

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

clang/lib/CIR/CodeGen/CIRGenFunction.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,10 @@ void CIRGenFunction::LexicalScope::cleanup() {
388388
}
389389

390390
if (localScope->Depth == 0) {
391+
mlir::Block *currBlock = builder.getInsertionBlock();
392+
if (currBlock->mightHaveTerminator())
393+
currBlock->getTerminator()->erase();
394+
391395
// TODO(cir): get rid of all this special cases once cleanups are properly
392396
// implemented.
393397
// TODO(cir): most of this code should move into emitBranchThroughCleanup

clang/test/CIR/CodeGen/ofstream.cpp

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -I%S/../Inputs -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -I%S/../Inputs -fclangir -emit-llvm %s -o %t.ll
4+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
5+
6+
#include "std-cxx.h"
7+
8+
namespace std {
9+
template <class CharT> class basic_ofstream {
10+
public:
11+
basic_ofstream();
12+
~basic_ofstream();
13+
explicit basic_ofstream(const char *);
14+
};
15+
16+
using ofstream = basic_ofstream<char>;
17+
18+
ofstream &operator<<(ofstream &, const string &);
19+
} // namespace std
20+
21+
void foo(const char *path) {
22+
std::ofstream fout1(path);
23+
fout1 << path;
24+
std::ofstream fout2(path);
25+
fout2 << path;
26+
}
27+
28+
// CIR: cir.func @_Z3fooPKc
29+
// CIR: %[[V1:.*]] = cir.alloca !ty_std3A3Abasic_ofstream3Cchar3E, !cir.ptr<!ty_std3A3Abasic_ofstream3Cchar3E>, ["fout1", init] {alignment = 1 : i64}
30+
// CIR: %[[V2:.*]] = cir.alloca !ty_std3A3Abasic_ofstream3Cchar3E, !cir.ptr<!ty_std3A3Abasic_ofstream3Cchar3E>, ["fout2", init] {alignment = 1 : i64}
31+
// CIR: cir.try synthetic cleanup {
32+
// CIR: cir.call exception @_ZNSbIcEC1EPKcRKNS_9AllocatorE({{.*}}, {{.*}}, {{.*}}) : (!cir.ptr<!ty_std3A3Abasic_string3Cchar3E>, !cir.ptr<!s8i>, !cir.ptr<!ty_std3A3Abasic_string3Cchar3E3A3AAllocator>) -> () cleanup {
33+
// CIR: cir.call @_ZNSt14basic_ofstreamIcED1Ev(%[[V2]]) : (!cir.ptr<!ty_std3A3Abasic_ofstream3Cchar3E>) -> ()
34+
// CIR: cir.call @_ZNSt14basic_ofstreamIcED1Ev(%[[V1]]) : (!cir.ptr<!ty_std3A3Abasic_ofstream3Cchar3E>) -> ()
35+
// CIR: cir.yield
36+
// CIR: }
37+
// CIR: cir.yield
38+
// CIR: } catch [#cir.unwind {
39+
// CIR: cir.resume
40+
// CIR: }]
41+
// CIR: cir.try synthetic cleanup {
42+
// CIR: %[[V10:.*]] = cir.call exception @_ZStlsRSt14basic_ofstreamIcERKSbIcE(%[[V2]], {{.*}}) : (!cir.ptr<!ty_std3A3Abasic_ofstream3Cchar3E>, !cir.ptr<!ty_std3A3Abasic_string3Cchar3E>) -> !cir.ptr<!ty_std3A3Abasic_ofstream3Cchar3E> cleanup {
43+
// CIR: cir.call @_ZNSbIcED1Ev({{.*}}) : (!cir.ptr<!ty_std3A3Abasic_string3Cchar3E>) -> ()
44+
// CIR: cir.call @_ZNSt14basic_ofstreamIcED1Ev(%[[V2]]) : (!cir.ptr<!ty_std3A3Abasic_ofstream3Cchar3E>) -> ()
45+
// CIR: cir.call @_ZNSt14basic_ofstreamIcED1Ev(%[[V1]]) : (!cir.ptr<!ty_std3A3Abasic_ofstream3Cchar3E>) -> ()
46+
// CIR: cir.yield
47+
// CIR: }
48+
// CIR: cir.store %[[V10]], {{.*}} : !cir.ptr<!ty_std3A3Abasic_ofstream3Cchar3E>, !cir.ptr<!cir.ptr<!ty_std3A3Abasic_ofstream3Cchar3E>>
49+
// CIR: cir.yield
50+
// CIR: } catch [#cir.unwind {
51+
// CIR: cir.resume
52+
// CIR: }]
53+
// CIR: cir.call @_ZNSt14basic_ofstreamIcED1Ev(%[[V2]]) : (!cir.ptr<!ty_std3A3Abasic_ofstream3Cchar3E>) -> ()
54+
// CIR: cir.call @_ZNSt14basic_ofstreamIcED1Ev(%[[V1]]) : (!cir.ptr<!ty_std3A3Abasic_ofstream3Cchar3E>) -> ()
55+
// CIR: cir.return
56+
57+
// LLVM: @_Z3fooPKc(ptr {{.*}})
58+
// LLVM: %[[V9:.*]] = alloca %"class.std::basic_ofstream<char>", i64 1, align 1
59+
// LLVM: %[[V10:.*]] = alloca %"class.std::basic_ofstream<char>", i64 1, align 1
60+
// LLVM: {{.*}}
61+
// LLVM: invoke void @_ZNSbIcEC1EPKcRKNS_9AllocatorE(ptr {{.*}}, ptr {{.*}}, ptr {{.*}})
62+
// LLVM: to label %[[B56:.*]] unwind label %[[B57:.*]]
63+
// LLVM: [[B56]]
64+
// LLVM: br label {{.*}}
65+
// LLVM: [[B57]]
66+
// LLVM: call void @_ZNSt14basic_ofstreamIcED1Ev(ptr %[[V10]])
67+
// LLVM: call void @_ZNSt14basic_ofstreamIcED1Ev(ptr %[[V9]])
68+
// LLVM: br label %[[B61:.*]]
69+
// LLVM: [[B61]]
70+
// LLVM: resume { ptr, i32 } {{.*}}
71+
// LLVM: {{.*}}
72+
// LLVM: {{.*}} = invoke ptr @_ZStlsRSt14basic_ofstreamIcERKSbIcE(ptr %[[V10]], ptr {{.*}})
73+
// LLVM: to label {{.*}} unwind label %[[B70:.*]]
74+
// LLVM: [[B70]]
75+
// LLVM: call void @_ZNSbIcED1Ev(ptr {{.*}})
76+
// LLVM: call void @_ZNSt14basic_ofstreamIcED1Ev(ptr %[[V10]])
77+
// LLVM: call void @_ZNSt14basic_ofstreamIcED1Ev(ptr %[[V9]])
78+
// LLVM: br label %[[B74:.*]]
79+
// LLVM: [[B74]]
80+
// LLVM: resume { ptr, i32 } {{.*}}
81+
// LLVM: {{.*}}
82+
// LLVM: call void @_ZNSbIcED1Ev(ptr {{.*}})
83+
// LLVM: br label %[[B80:.*]]
84+
// LLVM: [[B80]]
85+
// LLVM: call void @_ZNSt14basic_ofstreamIcED1Ev(ptr %[[V10]])
86+
// LLVM: call void @_ZNSt14basic_ofstreamIcED1Ev(ptr %[[V9]])
87+
// LLVM: ret void

0 commit comments

Comments
 (0)