Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

PR116696 expressed surprise that explicit 'constexpr' was needed on one
function; this was because the function isn't 'inline', and
-fimplicit-constexpr doesn't try to promote non-inline functions.  Let's be
more helpful in that situation, and also help trace through functions that
were promoted.

        PR c++/116696

gcc/cp/ChangeLog:

        * constexpr.cc (explain_invalid_constexpr_fn): When
        -fimplicit-constexpr, also explain inline functions, and point out
        non-inline functions.

gcc/testsuite/ChangeLog:

        * g++.dg/DRs/dr2478.C: Prune extra diagnostic.
        * g++.dg/ext/fimplicit-constexpr1.C: New test.
---
 gcc/cp/constexpr.cc                             | 7 +++++++
 gcc/testsuite/g++.dg/DRs/dr2478.C               | 2 +-
 gcc/testsuite/g++.dg/ext/fimplicit-constexpr1.C | 8 ++++++++
 3 files changed, 16 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/fimplicit-constexpr1.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index db2a9c1543e..d0f61748141 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -1057,9 +1057,16 @@ explain_invalid_constexpr_fn (tree fun)
   /* Only diagnose defaulted functions, lambdas, or instantiations.  */
   else if (!DECL_DEFAULTED_FN (fun)
           && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun))
+          && !(flag_implicit_constexpr
+               && !DECL_DECLARED_CONSTEXPR_P (fun)
+               && DECL_DECLARED_INLINE_P (fun))
           && !is_instantiation_of_constexpr (fun))
     {
       inform (DECL_SOURCE_LOCATION (fun), "%qD declared here", fun);
+      if (flag_implicit_constexpr && !maybe_constexpr_fn (fun)
+         && decl_defined_p (fun))
+       inform (DECL_SOURCE_LOCATION (fun),
+               "%<-fimplicit-constexpr%> only affects %<inline%> functions");
       return;
     }
   if (diagnosed == NULL)
diff --git a/gcc/testsuite/g++.dg/DRs/dr2478.C 
b/gcc/testsuite/g++.dg/DRs/dr2478.C
index 7f581cabb7b..b2292561381 100644
--- a/gcc/testsuite/g++.dg/DRs/dr2478.C
+++ b/gcc/testsuite/g++.dg/DRs/dr2478.C
@@ -2,7 +2,7 @@
 // { dg-do compile { target c++20 } }
 
 // Defeat -fimplicit-constexpr
-int ii;
+int ii; // { dg-prune-output "value of 'ii' is not usable in a constant expr" }
 
 template <typename T>
 struct S {
diff --git a/gcc/testsuite/g++.dg/ext/fimplicit-constexpr1.C 
b/gcc/testsuite/g++.dg/ext/fimplicit-constexpr1.C
new file mode 100644
index 00000000000..fc4b2829b65
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/fimplicit-constexpr1.C
@@ -0,0 +1,8 @@
+// { dg-additional-options -fimplicit-constexpr }
+// { dg-do compile { target c++14 } }
+
+void f() { } // { dg-message "'-fimplicit-constexpr' only affects 'inline' 
functions" }
+
+inline int g() { f(); return 42; } // { dg-error {non-'constexpr' function 
'void f\(\)'} }
+
+constexpr int i = g(); // { dg-error {'int g\(\)' called in a constant 
expression} }

base-commit: 99988464fc86354f0359c0fd91eee444fb5bd8a2
-- 
2.46.0

Reply via email to