https://llvm.org/bugs/show_bug.cgi?id=25997
Bug ID: 25997 Summary: [WinEH] no-return function in cleanup code not called with -O Product: clang Version: trunk Hardware: PC OS: Windows XP Status: NEW Severity: normal Priority: P Component: LLVM Codegen Assignee: unassignedclangb...@nondot.org Reporter: r.sagita...@gmx.de CC: llvm-bugs@lists.llvm.org Classification: Unclassified This code: #include <stdlib.h> #include <stdio.h> struct Cleanup { ~Cleanup() { puts("abort"); exit(42); } }; void test() { try { Cleanup a; throw int(3); } catch(int) { } } int main(int argc, char** argv) { test(); } compiles and runs correctly (prints "abort" and has exit code 42) when built with "clang -fexceptions -m32". Adding "-O" to the command line causes the program to crash. The C++ code itself seems questionable, but other languages support arbitrary code in "finally" blocks, e.g. throwing another exception. The IR for the test function: define void @"\01?test@@YAXXZ"() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { entry: %a = alloca %struct.Cleanup, align 1 %tmp = alloca i32, align 4 store i32 3, i32* %tmp, align 4 %0 = bitcast i32* %tmp to i8* invoke void @_CxxThrowException(i8* %0, %eh.ThrowInfo* @_TI1H) #4 to label %unreachable unwind label %ehcleanup ehcleanup: ; preds = %entry %1 = cleanuppad within none [] call x86_thiscallcc void @"\01??1Cleanup@@QAE@XZ"(%struct.Cleanup* %a) #5 [ "funclet"(token %1) ] cleanupret from %1 unwind label %catch.dispatch catch.dispatch: ; preds = %ehcleanup %2 = catchswitch within none [label %catch] unwind to caller catch: ; preds = %catch.dispatch %3 = catchpad within %2 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] catchret from %3 to label %catchret.dest catchret.dest: ; preds = %catch br label %try.cont try.cont: ; preds = %catchret.dest ret void unreachable: ; preds = %entry unreachable } The problem here is that the optimizer infers "noreturn" from the cleanup call and replaces "cleanupret" with "unreachable": define void @"\01?test@@YAXXZ"() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { entry: %a = alloca %struct.Cleanup, align 1 %tmp = alloca i32, align 4 %0 = getelementptr inbounds %struct.Cleanup, %struct.Cleanup* %a, i32 0, i32 0 call void @llvm.lifetime.start(i64 1, i8* %0) #6 store i32 3, i32* %tmp, align 4, !tbaa !4 %1 = bitcast i32* %tmp to i8* invoke void @_CxxThrowException(i8* %1, %eh.ThrowInfo* nonnull @_TI1H) #7 to label %unreachable unwind label %ehcleanup ehcleanup: ; preds = %entry %2 = cleanuppad within none [] call x86_thiscallcc void @"\01??1Cleanup@@QAE@XZ"(%struct.Cleanup* nonnull %a) #6 [ "funclet"(token %2) ] unreachable unreachable: ; preds = %entry unreachable } This seems to break the funclet extraction mechanism for the Windows exception handling. -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs