Skip to content

Commit 84c3e12

Browse files
committed
[coverage] fix crash in code coverage and if constexpr with ExprWithCleanups
1 parent d2565bb commit 84c3e12

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

clang/lib/CodeGen/CoverageMappingGen.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,12 +1808,24 @@ struct CounterCoverageMappingBuilder
18081808
}
18091809
}
18101810

1811+
private:
1812+
static bool evaluateConstantCondition(const Expr *Condition) {
1813+
if (const auto *Expr = dyn_cast<ConstantExpr>(Condition))
1814+
return Expr->getResultAsAPSInt().getExtValue();
1815+
1816+
if (const auto *Expr = dyn_cast<ExprWithCleanups>(Condition))
1817+
return evaluateConstantCondition(Expr->getSubExpr()); // recursion
1818+
1819+
assert(false && "Unexpected node in 'if constexpr' condition");
1820+
return false;
1821+
}
1822+
1823+
public:
18111824
void coverIfConstexpr(const IfStmt *S) {
18121825
assert(S->isConstexpr());
18131826

18141827
// evaluate constant condition...
1815-
const auto *E = cast<ConstantExpr>(S->getCond());
1816-
const bool isTrue = E->getResultAsAPSInt().getExtValue();
1828+
const bool isTrue = evaluateConstantCondition(S->getCond());
18171829

18181830
extendRegion(S);
18191831

clang/test/CoverageMapping/if.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,35 @@ constexpr int check_macro_consteval_if_skipped(int i) { // CHECK-NEXT: [[@LINE
234234
return i;
235235
}
236236

237+
struct false_value {
238+
constexpr operator bool() {
239+
return false;
240+
}
241+
};
242+
243+
template <typename> struct dependable_false_value {
244+
constexpr operator bool() {
245+
return false;
246+
}
247+
};
248+
249+
// GH-80285
250+
void should_not_crash() {
251+
if constexpr (false_value{}) { };
252+
}
253+
254+
template <typename> void should_not_crash_dependable() {
255+
if constexpr (dependable_false_value<int>{}) { };
256+
}
257+
258+
void should_not_crash_with_template_instance() {
259+
should_not_crash_dependable<int>();
260+
}
261+
262+
void should_not_crash_with_requires_expr() {
263+
if constexpr (requires {42;}) { };
264+
}
265+
237266
int instantiate_consteval(int i) {
238267
i *= check_consteval_with_else_discarded_then(i);
239268
i *= check_notconsteval_with_else_discarded_else(i);

0 commit comments

Comments
 (0)