https://github.com/hanickadot updated 
https://github.com/llvm/llvm-project/pull/136436

From b8865c8f7eddfd7bfaba1b0f5399ea03c6780070 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hana=20Dusi=CC=81kova=CC=81?= <hani...@hanicka.net>
Date: Sat, 19 Apr 2025 16:52:33 +0200
Subject: [PATCH] [clang] add -fimplicit-constexpr flag

---
 clang/include/clang/Basic/LangOptions.def |  1 +
 clang/include/clang/Driver/Options.td     |  6 +++
 clang/include/clang/Sema/Sema.h           |  1 +
 clang/lib/Driver/ToolChains/Clang.cpp     |  2 +
 clang/lib/Sema/SemaDecl.cpp               | 10 +++++
 clang/test/Sema/implicit-constexpr.cpp    | 51 +++++++++++++++++++++++
 6 files changed, 71 insertions(+)
 create mode 100644 clang/test/Sema/implicit-constexpr.cpp

diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 930c1c06d1a76..97527f7a0d1f3 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -413,6 +413,7 @@ BENIGN_LANGOPT(ArrowDepth, 32, 256,
                "maximum number of operator->s to follow")
 BENIGN_LANGOPT(InstantiationDepth, 32, 1024,
                "maximum template instantiation depth")
+LANGOPT(ImplicitConstexpr, 1, 0, "evaluate everything as it is a constexpr 
enabled")
 BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
                "maximum constexpr call depth")
 BENIGN_LANGOPT(ConstexprStepLimit, 32, 1048576,
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 919c1c643d080..877235147a044 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1991,6 +1991,12 @@ defm constant_cfstrings : 
BoolFOption<"constant-cfstrings",
           "Disable creation of CodeFoundation-type constant strings">,
   PosFlag<SetFalse>>;
 def fconstant_string_class_EQ : Joined<["-"], "fconstant-string-class=">, 
Group<f_Group>;
+def fimplicit_constexpr
+    : Joined<["-"], "fimplicit-constexpr">,
+      Group<f_Group>,
+      Visibility<[ClangOption, CC1Option]>,
+      HelpText<"All function declarations will be implicitly constexpr.">,
+      MarshallingInfoFlag<LangOpts<"ImplicitConstexpr">>;
 def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option]>,
   HelpText<"Set the maximum depth of recursive constexpr function calls">,
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 96d81e618494a..603a44bbba910 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2826,6 +2826,7 @@ class Sema final : public SemaBase {
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl *buildCoroutinePromise(SourceLocation Loc);
   void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body);
+  void AnalyseCoroutineBody(const CoroutineBodyStmt *);
 
   // As a clang extension, enforces that a non-coroutine function must be 
marked
   // with [[clang::coro_wrapper]] if it returns a type marked with
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index f2f5231933c88..27baf602e2703 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6612,6 +6612,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
   Args.AddLastArg(CmdArgs, options::OPT_fconstexpr_depth_EQ);
   Args.AddLastArg(CmdArgs, options::OPT_fconstexpr_steps_EQ);
 
+  Args.AddLastArg(CmdArgs, options::OPT_fimplicit_constexpr);
+
   Args.AddLastArg(CmdArgs, options::OPT_fexperimental_library);
 
   if (Args.hasArg(options::OPT_fexperimental_new_constant_interpreter))
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 46933c5c43168..1d4328db4dc41 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10163,6 +10163,16 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, 
DeclContext *DC,
     }
 
     ConstexprSpecKind ConstexprKind = D.getDeclSpec().getConstexprSpecifier();
+
+    // Clang's option -fimplicit-constexpr will make functions without 
constexpr
+    // or consteval specifier implicitly constexpr (compatibility with GCC.)
+    if (ConstexprKind == ConstexprSpecKind::Unspecified &&
+        getLangOpts().ImplicitConstexpr) {
+
+      NewFD->setConstexprKind(ConstexprSpecKind::Constexpr);
+      ConstexprKind = ConstexprSpecKind::Constexpr;
+    }
+
     if (ConstexprKind != ConstexprSpecKind::Unspecified) {
       // C++11 [dcl.constexpr]p2: constexpr functions and constexpr 
constructors
       // are implicitly inline.
diff --git a/clang/test/Sema/implicit-constexpr.cpp 
b/clang/test/Sema/implicit-constexpr.cpp
new file mode 100644
index 0000000000000..4b1314c342361
--- /dev/null
+++ b/clang/test/Sema/implicit-constexpr.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -verify=normal,both -std=c++23 %s
+// RUN: %clang_cc1 -verify=implicit,both -fimplicit-constexpr -std=c++23 %s
+
+bool function_test() { // normal-note+ {{declared here}}
+       return true;
+}
+
+// const variables should work as before
+const auto cvar = function_test();
+
+constexpr auto constexpr_var = function_test(); // normal-error {{constexpr 
variable 'constexpr_var' must be initialized by a constant expression}}
+// normal-note@-1 {{non-constexpr function 'function_test' cannot be used in a 
constant expression}}
+
+static_assert(function_test()); // normal-error {{static assertion expression 
is not an integral constant expression}}
+// normal-note@-1 {{non-constexpr function 'function_test' cannot be used in a 
constant expression}}
+
+
+struct full_nonconstexpr_type {
+       full_nonconstexpr_type() { } // normal-note {{declared here}}
+  ~full_nonconstexpr_type() { }
+};
+
+constexpr bool constructor_destructor_test() {
+  full_nonconstexpr_type var{}; // normal-note {{non-constexpr constructor 
'full_nonconstexpr_type' cannot be used in a constant expression}}
+  return true;
+}
+
+static_assert(constructor_destructor_test()); // normal-error {{static 
assertion expression is not an integral constant expression}}
+// normal-note@-1 {{in call to 'constructor_destructor_test()'}}
+
+
+struct only_destructor_type {
+  constexpr only_destructor_type() { }
+  ~only_destructor_type() { } // normal-note {{declared here}}
+};
+
+constexpr bool destructor_test() {
+  only_destructor_type var{}; // normal-note {{non-constexpr function 
'~only_destructor_type' cannot be used in a constant expression}}
+  return true;
+}
+
+static_assert(destructor_test()); // normal-error {{static assertion 
expression is not an integral constant expression}}
+// normal-note@-1 {{in call to 'destructor_test()'}}
+
+
+bool undefined_test(); // both-note {{declared here}}
+
+static_assert(undefined_test()); // both-error {{static assertion expression 
is not an integral constant expression}}
+// normal-note@-1 {{non-constexpr function 'undefined_test' cannot be used in 
a constant expressio}}
+// implicit-note@-2 {{undefined function 'undefined_test' cannot be used in a 
constant expression}}
+

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to