Patchwork C++ PATCH for c++/48115 (ICE with ellipsis and templates)

login
register
mail settings
Submitter Jason Merrill
Date March 16, 2011, 7:54 p.m.
Message ID <4D811585.2020106@redhat.com>
Download mbox | patch
Permalink /patch/87296/
State New
Headers show

Comments

Jason Merrill - March 16, 2011, 7:54 p.m.
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 <jason@redhat.com>
Date:   Wed Mar 16 14:15:41 2011 -0400

    	PR c++/48115
    	* call.c (convert_arg_to_ellipsis): Handle incomplete type.
Jakub Jelinek - March 16, 2011, 7:58 p.m.
On Wed, Mar 16, 2011 at 03:54:45PM -0400, Jason Merrill wrote:
> 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.

Yes, please.  Thanks.

> commit dbba5904d0fb00a0ddd934ee4c827592630c653e
> Author: Jason Merrill <jason@redhat.com>
> Date:   Wed Mar 16 14:15:41 2011 -0400
> 
>     	PR c++/48115
>     	* call.c (convert_arg_to_ellipsis): Handle incomplete type.
> 

	Jakub

Patch

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);
+}