aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2024-09-12 16:22:02 -0400
committerJason Merrill <jason@redhat.com>2024-09-13 17:18:29 +0200
commit4ee692337c4ec18fe9be3df34f3607ea3de5ef93 (patch)
treeffeca15a6d15e6bd6ad63873e877fa00834b0dd6
parent99988464fc86354f0359c0fd91eee444fb5bd8a2 (diff)
downloadgcc-4ee692337c4ec18fe9be3df34f3607ea3de5ef93.zip
gcc-4ee692337c4ec18fe9be3df34f3607ea3de5ef93.tar.gz
gcc-4ee692337c4ec18fe9be3df34f3607ea3de5ef93.tar.bz2
c++: -fimplicit-constexpr diagnostic improvement [PR116696]
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.
-rw-r--r--gcc/cp/constexpr.cc7
-rw-r--r--gcc/testsuite/g++.dg/DRs/dr2478.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/fimplicit-constexpr1.C8
3 files changed, 16 insertions, 1 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index db2a9c1..d0f6174 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 7f581ca..b229256 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 0000000..fc4b282
--- /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} }