[clang] [coverage] fix crash in code coverage and `if constexpr` with `ExprWithCleanups` (PR #80292)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 1 05:36:54 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-clang
Author: Hana Dusíková (hanickadot)
<details>
<summary>Changes</summary>
Fixes https://github.com/llvm/llvm-project/issues/80285
---
Full diff: https://github.com/llvm/llvm-project/pull/80292.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/CoverageMappingGen.cpp (+14-2)
- (modified) clang/test/CoverageMapping/if.cpp (+29)
``````````diff
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 8b5e6c4ad8272..6640fe6f41fd1 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -1808,12 +1808,24 @@ struct CounterCoverageMappingBuilder
}
}
+private:
+ static bool evaluateConstantCondition(const Expr *Condition) {
+ if (const auto *Expr = dyn_cast<ConstantExpr>(Condition))
+ return Expr->getResultAsAPSInt().getExtValue();
+
+ if (const auto *Expr = dyn_cast<ExprWithCleanups>(Condition))
+ return evaluateConstantCondition(Expr->getSubExpr()); // recursion
+
+ assert(false && "Unexpected node in 'if constexpr' condition");
+ return false;
+ }
+
+public:
void coverIfConstexpr(const IfStmt *S) {
assert(S->isConstexpr());
// evaluate constant condition...
- const auto *E = cast<ConstantExpr>(S->getCond());
- const bool isTrue = E->getResultAsAPSInt().getExtValue();
+ const bool isTrue = evaluateConstantCondition(S->getCond());
extendRegion(S);
diff --git a/clang/test/CoverageMapping/if.cpp b/clang/test/CoverageMapping/if.cpp
index 3045ffe43948c..4de1467aa7ee3 100644
--- a/clang/test/CoverageMapping/if.cpp
+++ b/clang/test/CoverageMapping/if.cpp
@@ -234,6 +234,35 @@ constexpr int check_macro_consteval_if_skipped(int i) { // CHECK-NEXT: [[@LINE
return i;
}
+struct false_value {
+ constexpr operator bool() {
+ return false;
+ }
+};
+
+template <typename> struct dependable_false_value {
+ constexpr operator bool() {
+ return false;
+ }
+};
+
+// GH-80285
+void should_not_crash() {
+ if constexpr (false_value{}) { };
+}
+
+template <typename> void should_not_crash_dependable() {
+ if constexpr (dependable_false_value<int>{}) { };
+}
+
+void should_not_crash_with_template_instance() {
+ should_not_crash_dependable<int>();
+}
+
+void should_not_crash_with_requires_expr() {
+ if constexpr (requires {42;}) { };
+}
+
int instantiate_consteval(int i) {
i *= check_consteval_with_else_discarded_then(i);
i *= check_notconsteval_with_else_discarded_else(i);
``````````
</details>
https://github.com/llvm/llvm-project/pull/80292
More information about the cfe-commits
mailing list