[clang] [Coverage] Add a new flag to split region after every call. (PR #90031)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 25 01:05:25 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: None (c01db33f)
<details>
<summary>Changes</summary>
This helps with displaying more precise coverage when a function causes the program to exit, crashes, or similar. For example, using this flag should address the case listed in the documentation under "Drawbacks and limitations":
```
int f() {
may_throw();
return 0;
}
```
If the call to `may_throw` propagates an exception into `f`, the `return` statement should not be marked as executed.
This change adds a significant number of basic blocks, so likely has a performance and size overhead, so I've not made it the default behaviour.
---
Full diff: https://github.com/llvm/llvm-project/pull/90031.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/CoverageMappingGen.cpp (+6-1)
- (added) clang/test/CoverageMapping/branch-return.cpp (+31)
``````````diff
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 733686d4946b3c..32fdfb0d35063b 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -45,6 +45,11 @@ static llvm::cl::opt<bool> EmptyLineCommentCoverage(
"disable it on test)"),
llvm::cl::init(true), llvm::cl::Hidden);
+static llvm::cl::opt<bool> CallsEndCoverageRegion(
+ "calls-end-coverage-region",
+ llvm::cl::desc("Force a coverage region end after every call expression"),
+ llvm::cl::init(false), llvm::cl::Hidden);
+
llvm::cl::opt<bool> SystemHeadersCoverage(
"system-headers-coverage",
llvm::cl::desc("Enable collecting coverage from system headers"),
@@ -1484,7 +1489,7 @@ struct CounterCoverageMappingBuilder
// Terminate the region when we hit a noreturn function.
// (This is helpful dealing with switch statements.)
QualType CalleeType = E->getCallee()->getType();
- if (getFunctionExtInfo(*CalleeType).getNoReturn())
+ if (CallsEndCoverageRegion || getFunctionExtInfo(*CalleeType).getNoReturn())
terminateRegion(E);
}
diff --git a/clang/test/CoverageMapping/branch-return.cpp b/clang/test/CoverageMapping/branch-return.cpp
new file mode 100644
index 00000000000000..16c1b88607d590
--- /dev/null
+++ b/clang/test/CoverageMapping/branch-return.cpp
@@ -0,0 +1,31 @@
+// Test that branch regions are generated for return paths when calls-end-coverage-region is set.
+
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name branch-return.cpp %s | FileCheck %s -check-prefix=WITHOUT
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -mllvm -calls-end-coverage-region -dump-coverage-mapping -emit-llvm-only -main-file-name branch-return.cpp %s | FileCheck %s -check-prefix=WITH
+
+// CHECK-LABEL: _Z5func1ii:
+// WITHOUT: File 0, [[@LINE+2]]:26 -> [[@LINE+4]]:2 = #0
+// WITH: File 0, [[@LINE+1]]:26 -> [[@LINE+3]]:2 = #0
+bool func1(int a, int b) {
+ return (a | b) < 100;
+}
+
+// CHECK-LABEL: _Z5func2ii:
+// WITHOUT: File 0, [[@LINE+2]]:26 -> [[@LINE+4]]:2 = #0
+// WITH: File 0, [[@LINE+1]]:26 -> [[@LINE+3]]:2 = #0
+bool func2(int a, int b) {
+ return (a ^ b) > 10;
+}
+
+// CHECK-LABEL: _Z5func3ii:
+// WITHOUT: File 0, [[@LINE+6]]:26 -> [[@LINE+10]]:2 = #0
+// WITH: File 0, [[@LINE+5]]:26 -> [[@LINE+9]]:2 = #0
+// WITH: Gap,File 0, [[@LINE+5]]:27 -> [[@LINE+6]]:3 = 0
+// WITH: File 0, [[@LINE+5]]:3 -> [[@LINE+5]]:26 = 0
+// WITH: Gap,File 0, [[@LINE+4]]:27 -> [[@LINE+5]]:3 = 0
+// WITH: File 0, [[@LINE+4]]:3 -> [[@LINE+4]]:22 = 0
+bool func3(int a, int b) {
+ bool val1 = func1(a, b);
+ bool val2 = func2(a, b);
+ return val1 || val2;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/90031
More information about the cfe-commits
mailing list