Skip to content

Commit fe697ef

Browse files
authored
[Clang] avoid adding consteval condition as the last statement to preserve valid CFG (#116513)
Fixes #116485
1 parent 2c094ac commit fe697ef

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,8 @@ Improvements to Clang's diagnostics
559559

560560
- Clang now diagnoses ``= delete("reason")`` extension warnings only in pedantic mode rather than on by default. (#GH109311).
561561

562+
- Clang now diagnoses missing return value in functions containing ``if consteval`` (#GH116485).
563+
562564
Improvements to Clang's time-trace
563565
----------------------------------
564566

clang/lib/Analysis/CFG.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3177,11 +3177,14 @@ CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) {
31773177
if (!I->isConsteval())
31783178
KnownVal = tryEvaluateBool(I->getCond());
31793179

3180-
// Add the successors. If we know that specific branches are
3180+
// Add the successors. If we know that specific branches are
31813181
// unreachable, inform addSuccessor() of that knowledge.
31823182
addSuccessor(Block, ThenBlock, /* IsReachable = */ !KnownVal.isFalse());
31833183
addSuccessor(Block, ElseBlock, /* IsReachable = */ !KnownVal.isTrue());
31843184

3185+
if (I->isConsteval())
3186+
return Block;
3187+
31853188
// Add the condition as the last statement in the new block. This may
31863189
// create new blocks as the condition may contain control-flow. Any newly
31873190
// created blocks will be pointed to be "Block".
Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,36 @@
1-
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
1+
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -Wimplicit-fallthrough -verify %s
22

33
constexpr int f() { } // expected-warning {{non-void function does not return a value}}
44
static_assert(__is_same(decltype([] constexpr -> int { }( )), int)); // expected-warning {{non-void lambda does not return a value}}
55

66
consteval int g() { } // expected-warning {{non-void function does not return a value}}
77
static_assert(__is_same(decltype([] consteval -> int { }( )), int)); // expected-warning {{non-void lambda does not return a value}}
8+
9+
namespace GH116485 {
10+
int h() {
11+
if consteval { }
12+
} // expected-warning {{non-void function does not return a value}}
13+
14+
void i(int x) {
15+
if consteval {
16+
}
17+
switch (x) {
18+
case 1:
19+
i(1);
20+
case 2: // expected-warning {{unannotated fall-through between switch labels}} \
21+
// expected-note {{insert 'break;' to avoid fall-through}}
22+
break;
23+
}
24+
}
25+
26+
constexpr bool j() {
27+
if !consteval { return true; }
28+
} // expected-warning {{non-void function does not return a value in all control paths}} \
29+
// expected-note {{control reached end of constexpr function}}
30+
31+
bool k = j();
32+
constinit bool l = j(); // expected-error {{variable does not have a constant initializer}} \
33+
// expected-note {{required by 'constinit' specifier here}} \
34+
// expected-note {{in call to 'j()'}}
35+
36+
}

0 commit comments

Comments
 (0)