]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: -fimplicit-constexpr diagnostic improvement [PR116696]
authorJason Merrill <jason@redhat.com>
Thu, 12 Sep 2024 20:22:02 +0000 (16:22 -0400)
committerJason Merrill <jason@redhat.com>
Fri, 13 Sep 2024 15:18:29 +0000 (17:18 +0200)
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
gcc/testsuite/g++.dg/DRs/dr2478.C
gcc/testsuite/g++.dg/ext/fimplicit-constexpr1.C [new file with mode: 0644]

index db2a9c1543e15ee5a9fc44504308e77ae8d0c2ca..d0f617481413973cd15c8eac2c8bae14254b67b3 100644 (file)
@@ -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)
index 7f581cabb7b0d764f7b9b3f9dc1ec855ac1ffcac..b2292561381a3581c2e564ab6ecc01cded97cfd5 100644 (file)
@@ -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 (file)
index 0000000..fc4b282
--- /dev/null
@@ -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} }