Author: Oleksandr T. Date: 2024-11-20T08:26:55-05:00 New Revision: fe697efe0c4ac34f30e28b77bb155c4fa996dab0
URL: https://github.com/llvm/llvm-project/commit/fe697efe0c4ac34f30e28b77bb155c4fa996dab0 DIFF: https://github.com/llvm/llvm-project/commit/fe697efe0c4ac34f30e28b77bb155c4fa996dab0.diff LOG: [Clang] avoid adding consteval condition as the last statement to preserve valid CFG (#116513) Fixes #116485 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Analysis/CFG.cpp clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index fcbb3a9e6c6f81..999c88455b64a5 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -559,6 +559,8 @@ Improvements to Clang's diagnostics - Clang now diagnoses ``= delete("reason")`` extension warnings only in pedantic mode rather than on by default. (#GH109311). +- 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..19e7d4976428a7 100644 --- a/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp +++ b/clang/test/SemaCXX/constexpr-return-non-void-cxx2b.cpp @@ -1,7 +1,36 @@ -// 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}} 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}} + +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()'}} + +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits