Here the issue was that require_complete_type doesn't do anything in
templates, but convert_arg_to_ellipsis was assuming that it did. The
simple fix is to make sure we really do have a complete type.
Tested x86_64-pc-linux-gnu, applying to trunk. Also OK for 4.6? The
patch seems extremely safe.
commit dbba5904d0fb00a0ddd934ee4c827592630c653e
Author: Jason Merrill <ja...@redhat.com>
Date: Wed Mar 16 14:15:41 2011 -0400
PR c++/48115
* call.c (convert_arg_to_ellipsis): Handle incomplete type.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 388f46c..f75c248 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5671,6 +5671,10 @@ convert_arg_to_ellipsis (tree arg)
arg_type = TREE_TYPE (arg);
if (arg != error_mark_node
+ /* In a template (or ill-formed code), we can have an incomplete type
+ even after require_complete_type, in which case we don't know
+ whether it has trivial copy or not. */
+ && COMPLETE_TYPE_P (arg_type)
&& (type_has_nontrivial_copy_init (arg_type)
|| TYPE_HAS_NONTRIVIAL_DESTRUCTOR (arg_type)))
{
diff --git a/gcc/testsuite/g++.dg/template/incomplete6.C
b/gcc/testsuite/g++.dg/template/incomplete6.C
new file mode 100644
index 0000000..7138b6a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/incomplete6.C
@@ -0,0 +1,22 @@
+// PR c++/48115
+
+template<typename> struct templ { };
+
+template<typename T> T declval();
+
+typedef int (*F2)(...);
+
+template<int> struct Int { };
+
+template<typename F, typename T>
+struct S
+{
+ template<typename A>
+ Int<sizeof( declval<F>()(T()) )>
+ f(A);
+};
+
+int main()
+{
+ S<F2, templ<int> >().f(0);
+}