[clang] [clang][CoverageMapping] do not emit gap when either end is an `ImplicitValueInitExpr` (PR #89564)
Wentao Zhang via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 22 09:18:46 PDT 2024
https://github.com/whentojump updated https://github.com/llvm/llvm-project/pull/89564
>From abbdb318d62bb2e5ab6f07e7d0fe11f4a06b5a11 Mon Sep 17 00:00:00 2001
From: Wentao Zhang <zhangwt1997 at gmail.com>
Date: Sun, 21 Apr 2024 21:27:01 -0500
Subject: [PATCH 1/2] [clang][CoverageMapping] do not emit gap when either end
is an ImplicitValueInitExpr
---
clang/lib/CodeGen/CoverageMappingGen.cpp | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 64c39c5de351c7..dd8c0577d758ca 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -1368,9 +1368,12 @@ struct CounterCoverageMappingBuilder
for (const Stmt *Child : S->children())
if (Child) {
// If last statement contains terminate statements, add a gap area
- // between the two statements. Skipping attributed statements, because
- // they don't have valid start location.
- if (LastStmt && HasTerminateStmt && !isa<AttributedStmt>(Child)) {
+ // between the two statements. Skipping attributed statements and
+ // implicit initializations, because they don't have valid source
+ // location.
+ if (LastStmt && HasTerminateStmt && !isa<AttributedStmt>(Child) &&
+ !isa<ImplicitValueInitExpr>(Child) &&
+ !isa<ImplicitValueInitExpr>(LastStmt)) {
auto Gap = findGapAreaBetween(getEnd(LastStmt), getStart(Child));
if (Gap)
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(),
>From cc42595ea34f4f4b5b9dda968f323ec95ba712e9 Mon Sep 17 00:00:00 2001
From: Wentao Zhang <zhangwt1997 at gmail.com>
Date: Mon, 22 Apr 2024 11:17:49 -0500
Subject: [PATCH 2/2] add tests
---
.../CoverageMapping/statement-expression.c | 36 +++++++++++++++++++
1 file changed, 36 insertions(+)
create mode 100644 clang/test/CoverageMapping/statement-expression.c
diff --git a/clang/test/CoverageMapping/statement-expression.c b/clang/test/CoverageMapping/statement-expression.c
new file mode 100644
index 00000000000000..6006e3646ee943
--- /dev/null
+++ b/clang/test/CoverageMapping/statement-expression.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name statement-expression.c %s
+
+// No crash for the following examples, where GNU Statement Expression extension
+// could contain region terminators (break, goto etc) before implicit
+// initializers in a struct or an array.
+// See https://github.com/llvm/llvm-project/pull/89564
+
+struct Foo {
+ int field1;
+ int field2;
+};
+
+void test1(void) {
+ struct Foo foo = {
+ .field1 = ({
+ switch (0) {
+ case 0:
+ break; // A region terminator
+ }
+ 0;
+ }),
+ // ImplicitValueInitExpr introduced here for .field2
+ };
+}
+
+void test2(void) {
+ int arr[3] = {
+ [0] = ({
+ goto L0; // A region terminator
+L0:
+ 0;
+ }),
+ // ImplicitValueInitExpr introduced here for subscript [1]
+ [2] = 0,
+ };
+}
More information about the cfe-commits
mailing list