An instantiation of a constexpr template that does not satisfy the rules
for a constexpr function is still well-formed, just not constexpr.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit f31ad5fe09e8d973926e32fa9617970e53b1ad19
Author: Jason Merrill <ja...@redhat.com>
Date: Tue Jan 20 17:51:30 2015 -0500
PR c++/64647
* constexpr.c (ensure_literal_type_for_constexpr_object): Don't
give a hard error in a template instantiation.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 0d47424..decc84d 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -102,15 +102,21 @@ ensure_literal_type_for_constexpr_object (tree decl)
else if (!literal_type_p (type))
{
if (DECL_DECLARED_CONSTEXPR_P (decl))
- error ("the type %qT of constexpr variable %qD is not literal",
- type, decl);
+ {
+ error ("the type %qT of constexpr variable %qD is not literal",
+ type, decl);
+ explain_non_literal_class (type);
+ }
else
{
- error ("variable %qD of non-literal type %qT in %<constexpr%> "
- "function", decl, type);
+ if (!DECL_TEMPLATE_INSTANTIATION (current_function_decl))
+ {
+ error ("variable %qD of non-literal type %qT in %<constexpr%> "
+ "function", decl, type);
+ explain_non_literal_class (type);
+ }
cp_function_chain->invalid_constexpr = true;
}
- explain_non_literal_class (type);
return NULL;
}
}
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-local3.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-local3.C
new file mode 100644
index 0000000..76d4b55
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-local3.C
@@ -0,0 +1,20 @@
+// PR c++/64647
+// { dg-do compile { target c++14 } }
+
+template<typename T>
+constexpr T foo(T t)
+{
+ T tt = t;
+ return tt;
+}
+
+struct X
+{
+ X() { }
+};
+
+int main()
+{
+ X x;
+ foo(x);
+}