Clang warning: use of this statement in a constexpr ... is a C++20 extension [-Wc++20-extensions] (ext_constexpr_body_invalid_stmt_cxx20)

From emmtrix Wiki
Jump to navigation Jump to search
Text
error: use of this statement in a constexpr
function
constructor
is a C++20 extension

(since 11.0)

Type Warning
Category Semantic Issue (since 11.0)
Internal Id ext_constexpr_body_invalid_stmt_cxx20 (since 11.0)
Active by Default Yes
Flags -Wno-c++20-extensions (23 elements)
-Wno-c++2a-extensions (23 elements)
Internal Message use of this statement in a constexpr %select{function|constructor}0 is a C++20 extension (since 11.0)
Regular Expression (?:warning|error|fatal error)\: use of this statement in a constexpr (?:function|constructor) is a C\+\+20 extension \[(?:\-Werror,)?\-Wc\+\+20\-extensions[^\]]*\]
First Commit 2018-12-10 5c1399a58237 [constexpr][c++2a] Try-catch blocks in constexpr functions

Description

The warning is issued by the Clang compiler when a statement is used in a constexpr function or constructor that is only allowed in C++20 and later versions. This situation arises because the C++ standards prior to C++20 have more restrictive rules about what can appear inside a constexpr function or constructor. These rules ensure that a constexpr function or constructor can be evaluated at compile time. However, C++20 relaxed some of these constraints, allowing for a broader set of statements to be used.

When compiling code that targets C++ standards earlier than C++20, but includes such C++20-specific statements in constexpr functions or constructors, Clang will generate this warning to alert the developer that they are using a feature that is not part of the currently targeted standard. This can be particularly relevant when aiming for portability or when compiling with strict adherence to a specific C++ standard version.

The warning can be controlled using the -Wc++20-extensions or -Wno-c++20-extensions flag. Enabling this warning helps developers identify places where their code may not be compliant with the standard they are targeting. If the use of C++20 features in a constexpr context is intentional and compatibility with older standards is not a concern, the warning can be explicitly disabled.

 
AI Generated

Example

In the following example, a constexpr function named f is defined, which attempts to use a try-catch block within its body. This function returns an integer value and is declared with the noexcept specifier, implying that it promises not to throw any exceptions. The body of the function consists of a try-catch block where the try section contains a return statement returning 0, and the catch section is designed to catch any exception, returning 1 instead.

The inclusion of the try-catch block within a constexpr function is a feature introduced in C++20. Since the example specifies the C++ standard as C++17 using the compiler flag -std=c++17, the Clang compiler issues a warning. This warning informs that the use of the try-catch block within the constexpr function is an extension of C++20 and not part of the C++17 standard, thereby making the developer aware of potential portability issues when targeting C++ standards prior to C++20.

 
AI Generated


Flags -xc++ -std=c++17

[Try out in Compiler Explorer]

Source
constexpr int f() noexcept {
  // try-catch in constexpr
  try { return 0; } catch (...) { return 1; }
}
Compiler Output
<source>:3:3: warning: use of this statement in a constexpr function is a C++20 extension [-Wc++20-extensions]


Clang Internals (17.0.6)

Git Commit Message

[constexpr][c++2a] Try-catch blocks in constexpr functions

Implement support for try-catch blocks in constexpr functions, as
proposed in http://wg21.link/P1002 and voted in San Diego for c++20.

The idea is that we can still never throw inside constexpr, so the catch
block is never entered. A try-catch block like this:

try { f(); } catch (...) { }

is then morally equivalent to just

{ f(); }

Same idea should apply for function/constructor try blocks.

rdar://problem/45530773

Differential Revision: https://reviews.llvm.org/D55097

llvm-svn: 348789

Used in Clang Sources

This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.

clang/lib/Sema/SemaDeclCXX.cpp (line 2294)

/// Check the body for the given constexpr function declaration only contains
/// the permitted types of statement. C++11 [dcl.constexpr]p3,p4.
///
/// \return true if the body is OK, false if we have found or diagnosed a
/// problem.
static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *Body, Sema::CheckConstexprKind Kind) {
  // ...
  if (Kind == Sema::CheckConstexprKind::CheckValid) {
  // ...
  } else if (Cxx2bLoc.isValid()) {
  // ...
  } else if (Cxx2aLoc.isValid()) {
    SemaRef.Diag(Cxx2aLoc, SemaRef.getLangOpts().CPlusPlus20 ? diag::warn_cxx17_compat_constexpr_body_invalid_stmt : diag::ext_constexpr_body_invalid_stmt_cxx20) << isa<CXXConstructorDecl>(Dcl);

Triggered in Clang Tests

This section lists all internal Clang test cases that trigger the diagnostic.

clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp

  • clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp:124:5: warning: use of this statement in a constexpr function is a C++20 extension [-Wc++20-extensions]
  • clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp:140:3: warning: use of this statement in a constexpr function is a C++20 extension [-Wc++20-extensions]