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 <zhangwt1...@gmail.com> Date: Sun, 21 Apr 2024 21:27:01 -0500 Subject: [PATCH 1/4] [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 f2931efcc97ce418ab724e2cb052b47ec5c87986 Mon Sep 17 00:00:00 2001 From: Wentao Zhang <zhangwt1...@gmail.com> Date: Mon, 22 Apr 2024 11:17:49 -0500 Subject: [PATCH 2/4] 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..5f9ab5838af342 --- /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 introduce 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 f1(void) { + struct Foo foo = { + .field1 = ({ + switch (0) { + case 0: + break; // A region terminator + } + 0; + }), + // ImplicitValueInitExpr introduced here for .field2 + }; +} + +void f2(void) { + int arr[3] = { + [0] = ({ + goto L0; // A region terminator +L0: + 0; + }), + // ImplicitValueInitExpr introduced here for subscript [1] + [2] = 0, + }; +} >From 6a00626a44b23815b99ad217b0ab9ed8567c19a2 Mon Sep 17 00:00:00 2001 From: Wentao Zhang <zhangwt1...@gmail.com> Date: Mon, 22 Apr 2024 11:20:08 -0500 Subject: [PATCH 3/4] Revert "[clang][CoverageMapping] do not emit gap when either end is an ImplicitValueInitExpr" This reverts commit abbdb318d62bb2e5ab6f07e7d0fe11f4a06b5a11. --- clang/lib/CodeGen/CoverageMappingGen.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index dd8c0577d758ca..64c39c5de351c7 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -1368,12 +1368,9 @@ 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 and - // implicit initializations, because they don't have valid source - // location. - if (LastStmt && HasTerminateStmt && !isa<AttributedStmt>(Child) && - !isa<ImplicitValueInitExpr>(Child) && - !isa<ImplicitValueInitExpr>(LastStmt)) { + // between the two statements. Skipping attributed statements, because + // they don't have valid start location. + if (LastStmt && HasTerminateStmt && !isa<AttributedStmt>(Child)) { auto Gap = findGapAreaBetween(getEnd(LastStmt), getStart(Child)); if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), >From c7359ddf8ee689f12fa75ccc3ccff1bfecb2027a Mon Sep 17 00:00:00 2001 From: Wentao Zhang <zhangwt1...@gmail.com> Date: Mon, 22 Apr 2024 11:33:41 -0500 Subject: [PATCH 4/4] move into findGapAreaBetween --- clang/lib/CodeGen/CoverageMappingGen.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 64c39c5de351c7..733686d4946b3c 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -1208,6 +1208,12 @@ struct CounterCoverageMappingBuilder /// Find a valid gap range between \p AfterLoc and \p BeforeLoc. std::optional<SourceRange> findGapAreaBetween(SourceLocation AfterLoc, SourceLocation BeforeLoc) { + // Some statements (like AttributedStmt and ImplicitValueInitExpr) don't + // have valid source locations. Do not emit a gap region if this is the case + // in either AfterLoc end or BeforeLoc end. + if (AfterLoc.isInvalid() || BeforeLoc.isInvalid()) + return std::nullopt; + // If AfterLoc is in function-like macro, use the right parenthesis // location. if (AfterLoc.isMacroID()) { @@ -1368,9 +1374,8 @@ 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. + if (LastStmt && HasTerminateStmt) { auto Gap = findGapAreaBetween(getEnd(LastStmt), getStart(Child)); if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits