From 4ee692337c4ec18fe9be3df34f3607ea3de5ef93 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 12 Sep 2024 16:22:02 -0400 Subject: [PATCH] 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. --- 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 % 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 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} }