[PATCH] D109940: Fixed bug with clang where a fallthrough switch statement wasn't getting proper debug information
Shubham Sandeep Rastogi via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 16 18:47:05 PDT 2021
rastogishubham created this revision.
rastogishubham added a reviewer: aprantl.
rastogishubham added a project: debug-info.
rastogishubham requested review of this revision.
When clang sees a switch with a fallthrough like this:
static void funcA(void) {}
static void funcB(void) {}
int main(int argc, char **argv) {
switch (argc) {
case 0:
funcA();
break;
case 10:
default:
funcB();
break;
}
}
It does not add a proper debug location for that switch case, such as case 10: above.
The IR output looks like this:
Function Attrs: noinline nounwind optnone ssp uwtable
define i32 @main(i32 %0, i8** %1) #0 !dbg !9 {
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i8**, align 8
store i32 0, i32* %3, align 4
store i32 %0, i32* %4, align 4
call void @llvm.dbg.declare(metadata i32* %4, metadata !16, metadata !DIExpression()), !dbg !17
store i8** %1, i8*** %5, align 8
call void @llvm.dbg.declare(metadata i8*** %5, metadata !18, metadata !DIExpression()), !dbg !19
%6 = load i32, i32* %4, align 4, !dbg !20
switch i32 %6, label %9 [
i32 0, label %7
i32 10, label %8
], !dbg !21
7: ; preds = %2
call void @funcA(), !dbg !22
br label %10, !dbg !24
8: ; preds = %2
br label %9, !dbg !24
9: ; preds = %2, %8
call void @funcB(), !dbg !25
br label %10, !dbg !26
10: ; preds = %9, %7
%11 = load i32, i32* %3, align 4, !dbg !27
ret i32 %11, !dbg !27
}
label 7 and label 8 both have branches but label 8's branch uses the same debug location as label 7's branch. This resolves to disassembly such as:
LBB0_5:
.loc 1 0 5 ## Documents/test.c:0:5
movl -20(%rbp), %eax ## 4-byte Reload
.loc 1 5 5 ## Documents/test.c:5:5
subl $10, %eax
je LBB0_2
jmp LBB0_3
LBB0_1:
Ltmp1:
.loc 1 7 13 is_stmt 1 ## Documents/test.c:7:13
callq _funcA
.loc 1 8 13 ## Documents/test.c:8:13
jmp LBB0_4
LBB0_2:
jmp LBB0_3
LBB0_3:
.loc 1 11 13 ## Documents/test.c:11:13
callq _funcB
LBB0_2 does not get a .loc in this case
https://reviews.llvm.org/D109940
Files:
clang/lib/CodeGen/CGStmt.cpp
clang/test/CodeGen/switch-fallthrough.c
Index: clang/test/CodeGen/switch-fallthrough.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/switch-fallthrough.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx11.0.0 -debug-info-kind=standalone -emit-llvm %s -o - | FileCheck %s -v
+// CHECK: ], !dbg !{{[0-9]+}}
+// CHECK-EMPTY:
+// CHECK-NEXT: {{.+}}
+// CHECK-NEXT: br {{.+}}, !dbg !{{[0-9+]}}
+// CHECK-EMPTY:
+// CHECK-NEXT: {{.+}}
+// CHECK-NEXT: br {{.+}}, !dbg ![[LOC:[0-9]+]]
+void test(int num) {
+ switch (num) {
+ case 0:
+ break;
+ case 10: // CHECK: ![[LOC]] = !DILocation(line: [[@LINE]], column:{{.+}}, scope: {{.+}})
+ default:
+ break;
+ }
+}
\ No newline at end of file
Index: clang/lib/CodeGen/CGStmt.cpp
===================================================================
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -1518,6 +1518,11 @@
NextCase = dyn_cast<CaseStmt>(CurCase->getSubStmt());
}
+ // Generate a stop point for debug info if the case statement is followed
+ // by a default statement.
+ if (CurCase->getSubStmt()->getStmtClass() == Stmt::DefaultStmtClass) {
+ EmitStopPoint(CurCase);
+ }
// Normal default recursion for non-cases.
EmitStmt(CurCase->getSubStmt());
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D109940.373120.patch
Type: text/x-patch
Size: 1287 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210917/8b91f1ed/attachment.bin>
More information about the llvm-commits
mailing list