On Sun, Feb 08, 2026 at 11:27:40AM +0900, Jason Merrill wrote:
> > + && !DECL_CONSTRUCTOR_P (fun))
> > + error ("body of %<constexpr%> function %qD not a return-statement",
> > + fun);
> > require_potential_rvalue_constant_expression (massaged);
> > if (DECL_CONSTRUCTOR_P (fun))
>
> Since we have this DECL_CONSTRUCTOR_P check already, let's make the new code
> an else?
Thanks, here is what I've committed after another x86_64/i686-linux
bootstrap/regtest:
2026-02-09 Jakub Jelinek <[email protected]>
PR c++/123889
* constexpr.cc (explain_invalid_constexpr_fn): Diagnose
NULL or error_mark_node massaged on non-constructor.
* g++.dg/cpp0x/constexpr-123889.C: New test.
--- gcc/cp/constexpr.cc.jj 2026-02-04 11:21:46.975769787 +0100
+++ gcc/cp/constexpr.cc 2026-02-08 21:04:44.816563912 +0100
@@ -1124,6 +1124,9 @@ explain_invalid_constexpr_fn (tree fun)
/* Also check the body, not just the ctor-initializer. */
require_potential_rvalue_constant_expression (body);
}
+ else if (massaged == NULL_TREE || massaged == error_mark_node)
+ error ("body of %<constexpr%> function %qD not a return-statement",
+ fun);
}
}
}
--- gcc/testsuite/g++.dg/cpp0x/constexpr-123889.C.jj 2026-02-02
14:42:30.345152859 +0100
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-123889.C 2026-02-02
14:44:10.958435899 +0100
@@ -0,0 +1,14 @@
+// PR c++/123889
+// { dg-do compile { target c++11 } }
+
+template <class T>
+constexpr int func (T) {
+// { dg-message "'constexpr int func\\\(T\\\) \\\[with T = int\\\]' is not
usable as a 'constexpr' function because:" "" { target c++11_only } .-1 }
+// { dg-error "body of 'constexpr' function 'constexpr int func\\\(T\\\)
\\\[with T = int\\\]' not a return-statement" "" { target c++11_only } .-2 }
+ return 1;
+ return 2;
+}
+
+static_assert (func (1) == 1, "");
+// { dg-error "non-constant condition for static assertion" "" { target
c++11_only } .-1 }
+// { dg-error "'constexpr int func\\\(T\\\) \\\[with T = int\\\]' called in a
constant expression" "" { target c++11_only } .-2 }
Jakub