Skip to content

Commit b8865c8

Browse files
committed
[clang] add -fimplicit-constexpr flag
1 parent 6196b4e commit b8865c8

File tree

6 files changed

+71
-0
lines changed

6 files changed

+71
-0
lines changed

Diff for: clang/include/clang/Basic/LangOptions.def

+1
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ BENIGN_LANGOPT(ArrowDepth, 32, 256,
413413
"maximum number of operator->s to follow")
414414
BENIGN_LANGOPT(InstantiationDepth, 32, 1024,
415415
"maximum template instantiation depth")
416+
LANGOPT(ImplicitConstexpr, 1, 0, "evaluate everything as it is a constexpr enabled")
416417
BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
417418
"maximum constexpr call depth")
418419
BENIGN_LANGOPT(ConstexprStepLimit, 32, 1048576,

Diff for: clang/include/clang/Driver/Options.td

+6
Original file line numberDiff line numberDiff line change
@@ -1991,6 +1991,12 @@ defm constant_cfstrings : BoolFOption<"constant-cfstrings",
19911991
"Disable creation of CodeFoundation-type constant strings">,
19921992
PosFlag<SetFalse>>;
19931993
def fconstant_string_class_EQ : Joined<["-"], "fconstant-string-class=">, Group<f_Group>;
1994+
def fimplicit_constexpr
1995+
: Joined<["-"], "fimplicit-constexpr">,
1996+
Group<f_Group>,
1997+
Visibility<[ClangOption, CC1Option]>,
1998+
HelpText<"All function declarations will be implicitly constexpr.">,
1999+
MarshallingInfoFlag<LangOpts<"ImplicitConstexpr">>;
19942000
def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>,
19952001
Visibility<[ClangOption, CC1Option]>,
19962002
HelpText<"Set the maximum depth of recursive constexpr function calls">,

Diff for: clang/include/clang/Sema/Sema.h

+1
Original file line numberDiff line numberDiff line change
@@ -2826,6 +2826,7 @@ class Sema final : public SemaBase {
28262826
bool buildCoroutineParameterMoves(SourceLocation Loc);
28272827
VarDecl *buildCoroutinePromise(SourceLocation Loc);
28282828
void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body);
2829+
void AnalyseCoroutineBody(const CoroutineBodyStmt *);
28292830

28302831
// As a clang extension, enforces that a non-coroutine function must be marked
28312832
// with [[clang::coro_wrapper]] if it returns a type marked with

Diff for: clang/lib/Driver/ToolChains/Clang.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -6612,6 +6612,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
66126612
Args.AddLastArg(CmdArgs, options::OPT_fconstexpr_depth_EQ);
66136613
Args.AddLastArg(CmdArgs, options::OPT_fconstexpr_steps_EQ);
66146614

6615+
Args.AddLastArg(CmdArgs, options::OPT_fimplicit_constexpr);
6616+
66156617
Args.AddLastArg(CmdArgs, options::OPT_fexperimental_library);
66166618

66176619
if (Args.hasArg(options::OPT_fexperimental_new_constant_interpreter))

Diff for: clang/lib/Sema/SemaDecl.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -10163,6 +10163,16 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
1016310163
}
1016410164

1016510165
ConstexprSpecKind ConstexprKind = D.getDeclSpec().getConstexprSpecifier();
10166+
10167+
// Clang's option -fimplicit-constexpr will make functions without constexpr
10168+
// or consteval specifier implicitly constexpr (compatibility with GCC.)
10169+
if (ConstexprKind == ConstexprSpecKind::Unspecified &&
10170+
getLangOpts().ImplicitConstexpr) {
10171+
10172+
NewFD->setConstexprKind(ConstexprSpecKind::Constexpr);
10173+
ConstexprKind = ConstexprSpecKind::Constexpr;
10174+
}
10175+
1016610176
if (ConstexprKind != ConstexprSpecKind::Unspecified) {
1016710177
// C++11 [dcl.constexpr]p2: constexpr functions and constexpr constructors
1016810178
// are implicitly inline.

Diff for: clang/test/Sema/implicit-constexpr.cpp

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// RUN: %clang_cc1 -verify=normal,both -std=c++23 %s
2+
// RUN: %clang_cc1 -verify=implicit,both -fimplicit-constexpr -std=c++23 %s
3+
4+
bool function_test() { // normal-note+ {{declared here}}
5+
return true;
6+
}
7+
8+
// const variables should work as before
9+
const auto cvar = function_test();
10+
11+
constexpr auto constexpr_var = function_test(); // normal-error {{constexpr variable 'constexpr_var' must be initialized by a constant expression}}
12+
// normal-note@-1 {{non-constexpr function 'function_test' cannot be used in a constant expression}}
13+
14+
static_assert(function_test()); // normal-error {{static assertion expression is not an integral constant expression}}
15+
// normal-note@-1 {{non-constexpr function 'function_test' cannot be used in a constant expression}}
16+
17+
18+
struct full_nonconstexpr_type {
19+
full_nonconstexpr_type() { } // normal-note {{declared here}}
20+
~full_nonconstexpr_type() { }
21+
};
22+
23+
constexpr bool constructor_destructor_test() {
24+
full_nonconstexpr_type var{}; // normal-note {{non-constexpr constructor 'full_nonconstexpr_type' cannot be used in a constant expression}}
25+
return true;
26+
}
27+
28+
static_assert(constructor_destructor_test()); // normal-error {{static assertion expression is not an integral constant expression}}
29+
// normal-note@-1 {{in call to 'constructor_destructor_test()'}}
30+
31+
32+
struct only_destructor_type {
33+
constexpr only_destructor_type() { }
34+
~only_destructor_type() { } // normal-note {{declared here}}
35+
};
36+
37+
constexpr bool destructor_test() {
38+
only_destructor_type var{}; // normal-note {{non-constexpr function '~only_destructor_type' cannot be used in a constant expression}}
39+
return true;
40+
}
41+
42+
static_assert(destructor_test()); // normal-error {{static assertion expression is not an integral constant expression}}
43+
// normal-note@-1 {{in call to 'destructor_test()'}}
44+
45+
46+
bool undefined_test(); // both-note {{declared here}}
47+
48+
static_assert(undefined_test()); // both-error {{static assertion expression is not an integral constant expression}}
49+
// normal-note@-1 {{non-constexpr function 'undefined_test' cannot be used in a constant expressio}}
50+
// implicit-note@-2 {{undefined function 'undefined_test' cannot be used in a constant expression}}
51+

0 commit comments

Comments
 (0)