[clang] [Clang] avoid adding consteval condition as the last statement to preserve valid CFG (PR #116513)
Oleksandr T. via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 19 12:31:29 PST 2024
https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/116513
>From 69689f6ba5ac1715cc1df6cf08b79bb4b8bbe107 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Sun, 17 Nov 2024 01:34:42 +0200
Subject: [PATCH 1/2] [Clang] avoid adding consteval condition as the last
statement to preserve valid CFG
---
clang/docs/ReleaseNotes.rst | 2 ++
clang/lib/Analysis/CFG.cpp | 5 ++++-
clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp | 6 ++++++
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a8830a5658c7da..d81085d011b866 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -535,6 +535,8 @@ Improvements to Clang's diagnostics
- Improved diagnostic message for ``__builtin_bit_cast`` size mismatch (#GH115870).
+- Clang now diagnoses missing return value in functions containing ``if consteval`` (#GH116485).
+
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index f678ac6f2ff36a..7a6bd8b6f8d070 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -3177,11 +3177,14 @@ CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) {
if (!I->isConsteval())
KnownVal = tryEvaluateBool(I->getCond());
- // Add the successors. If we know that specific branches are
+ // Add the successors. If we know that specific branches are
// unreachable, inform addSuccessor() of that knowledge.
addSuccessor(Block, ThenBlock, /* IsReachable = */ !KnownVal.isFalse());
addSuccessor(Block, ElseBlock, /* IsReachable = */ !KnownVal.isTrue());
+ if (I->isConsteval())
+ return Block;
+
// Add the condition as the last statement in the new block. This may
// create new blocks as the condition may contain control-flow. Any newly
// created blocks will be pointed to be "Block".
diff --git a/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp b/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp
index 25d1f8df7f7166..3d993f000e8dda 100644
--- a/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp
+++ b/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp
@@ -5,3 +5,9 @@ static_assert(__is_same(decltype([] constexpr -> int { }( )), int)); // expected
consteval int g() { } // expected-warning {{non-void function does not return a value}}
static_assert(__is_same(decltype([] consteval -> int { }( )), int)); // expected-warning {{non-void lambda does not return a value}}
+
+namespace GH116485 {
+int h() {
+ if consteval { }
+} // expected-warning {{non-void function does not return a value}}
+}
>From d97a778a5e26749d4f3ae6ff9d8e03185e95d2fb Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Tue, 19 Nov 2024 22:30:55 +0200
Subject: [PATCH 2/2] add additional tests
---
.../constexpr-return-non-void-cxx2b.cpp | 25 ++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp b/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp
index 3d993f000e8dda..19e7d4976428a7 100644
--- a/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp
+++ b/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only -Wimplicit-fallthrough -verify %s
constexpr int f() { } // expected-warning {{non-void function does not return a value}}
static_assert(__is_same(decltype([] constexpr -> int { }( )), int)); // expected-warning {{non-void lambda does not return a value}}
@@ -10,4 +10,27 @@ namespace GH116485 {
int h() {
if consteval { }
} // expected-warning {{non-void function does not return a value}}
+
+void i(int x) {
+ if consteval {
+ }
+ switch (x) {
+ case 1:
+ i(1);
+ case 2: // expected-warning {{unannotated fall-through between switch labels}} \
+ // expected-note {{insert 'break;' to avoid fall-through}}
+ break;
+ }
+}
+
+constexpr bool j() {
+ if !consteval { return true; }
+} // expected-warning {{non-void function does not return a value in all control paths}} \
+ // expected-note {{control reached end of constexpr function}}
+
+bool k = j();
+constinit bool l = j(); // expected-error {{variable does not have a constant initializer}} \
+ // expected-note {{required by 'constinit' specifier here}} \
+ // expected-note {{in call to 'j()'}}
+
}
More information about the cfe-commits
mailing list