From 421048698b6b6bf86754190bcfe98a0ed82ee5b5 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 17 Apr 2011 23:21:26 +0000 Subject: [PATCH] Fix a miscompilation I introduced in r129652, thanks for Eli for tracking it down. we effectively were compile the testcase into: void test14(int x) { switch (x) { case 11: break; case 42: test14(97); // fallthrough default: test14(42); break; which is not the same thing at all. This fixes a miscompilation of MallocBench/gs seen on the clang-x86_64-linux-fnt buildbot. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129679 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGStmt.cpp | 10 +++++++++- test/CodeGen/switch-dce.c | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index b8b2cd9f3e..8bb45343db 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -873,7 +873,8 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { return; } - // If the body of the case is just a 'break', try to not emit an empty block. + // If the body of the case is just a 'break', and if there was no fallthrough, + // try to not emit an empty block. if (isa(S.getSubStmt())) { JumpDest Block = BreakContinueStack.back().BreakBlock; @@ -882,6 +883,13 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { llvm::APSInt CaseVal = S.getLHS()->EvaluateAsInt(getContext()); SwitchInsn->addCase(llvm::ConstantInt::get(getLLVMContext(), CaseVal), Block.getBlock()); + + // If there was a fallthrough into this case, make sure to redirect it to + // the end of the switch as well. + if (Builder.GetInsertBlock()) { + Builder.CreateBr(Block.getBlock()); + Builder.ClearInsertionPoint(); + } return; } } diff --git a/test/CodeGen/switch-dce.c b/test/CodeGen/switch-dce.c index 4013809cbf..bbb5f7e5aa 100644 --- a/test/CodeGen/switch-dce.c +++ b/test/CodeGen/switch-dce.c @@ -229,3 +229,19 @@ void test13(int x) { default: test13(42); break; } } + + +// Verify that case 42 only calls test14 once. +// CHECK: @test14 +// CHECK: call void @test14(i32 97) +// CHECK-NEXT: br label [[EPILOG2:%[0-9.a-z]+]] +// CHECK: call void @test14(i32 42) +// CHECK-NEXT: br label [[EPILOG2]] +void test14(int x) { + switch (x) { + case 42: test14(97); // fallthrough + case 11: break; + default: test14(42); break; + } +} + -- 2.40.0