Skip to content

Commit c79b544

Browse files
authored
[SEH] Fix assertin when return scalar value from __try block. (#71488)
Current compler assert with `!SI->isAtomic() && !SI->isVolatile()' failed This due to following rule: First, no exception can move in or out of _try region., i.e., no "potential faulty instruction can be moved across _try boundary. Second, the order of exceptions for instructions 'directly' under a _try must be preserved (not applied to those in callees). Finally, global states (local/global/heap variables) that can be read outside of _try region must be updated in memory (not just in register) before the subsequent exception occurs. All memory instructions inside a _try are considered as 'volatile' to assure 2nd and 3rd rules for C-code above. This is a little sub-optimized. But it's acceptable as the amount of code directly under _try is very small. However during findDominatingStoreToReturnValue: those are not allowed. To fix just skip the assertion when current function has seh try.
1 parent 64ed4ed commit c79b544

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

clang/lib/CodeGen/CGCall.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3507,7 +3507,9 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
35073507
return nullptr;
35083508
// These aren't actually possible for non-coerced returns, and we
35093509
// only care about non-coerced returns on this code path.
3510-
assert(!SI->isAtomic() && !SI->isVolatile());
3510+
// All memory instructions inside __try block are volatile.
3511+
assert(!SI->isAtomic() &&
3512+
(!SI->isVolatile() || CGF.currentFunctionUsesSEHTry()));
35113513
return SI;
35123514
};
35133515
// If there are multiple uses of the return-value slot, just check

clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,26 @@ void foo()
6767
}
6868
}
6969
}
70+
71+
// CHECK-LABEL:@"?bar@@YAHXZ"()
72+
// CHECK: invoke.cont:
73+
// CHECK: invoke void @llvm.seh.try.begin()
74+
// CHECK: invoke.cont1:
75+
// CHECK: store volatile i32 1, ptr %cleanup.dest.slot
76+
// CHECK: invoke void @llvm.seh.try.end()
77+
// CHECK: invoke.cont2:
78+
// CHECK: call void @"?fin$0@0@bar@@"
79+
// CHECK: %cleanup.dest3 = load i32, ptr %cleanup.dest.slot
80+
// CHECK: return:
81+
// CHECK: ret i32 11
82+
int bar()
83+
{
84+
int x;
85+
__try {
86+
return 11;
87+
} __finally {
88+
if (_abnormal_termination()) {
89+
x = 9;
90+
}
91+
}
92+
}

0 commit comments

Comments
 (0)