Patchwork C++ PATCH for c++/52035 (LTO ICE with typedef in class template)

login
register
mail settings
Submitter Jason Merrill
Date Feb. 8, 2012, 9:27 a.m.
Message ID <4F323FF3.2070002@redhat.com>
Download mbox | patch
Permalink /patch/140079/
State New
Headers show

Comments

Jason Merrill - Feb. 8, 2012, 9:27 a.m.
The issue here is that when we go to instantiate QVector<int>::insert, 
we use the out-of-class definition which uses the typedef rather than 
the in-class declaration which uses plain int.  But we haven't 
instantiated the typedef yet, so when we look for the instantiation we 
get nothing and end up just returning the template version of the 
typedef.  So we end up referring to uninstantiated trees, which leads to 
an abort in the LTO streamer.

Fixed by stripping the typedef if we don't find an instantiation.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit d8cfecd974c2515465f9be396d52a128db88f9e9
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Feb 6 11:29:37 2012 -1000

    	PR c++/52035
    	* pt.c (tsubst): Strip uninstantiated typedef.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 4c93b31..a0b2a0b 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11178,7 +11178,9 @@  tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	     complain | tf_ignore_bad_quals);
 	  return r;
 	}
-      /* Else we must be instantiating the typedef, so fall through.  */
+      else
+	/* We don't have an instantiation yet, so drop the typedef.  */
+	t = DECL_ORIGINAL_TYPE (decl);
     }
 
   if (type
diff --git a/gcc/testsuite/g++.dg/lto/README b/gcc/testsuite/g++.dg/lto/README
index 5fa3123..1a13dd9 100644
--- a/gcc/testsuite/g++.dg/lto/README
+++ b/gcc/testsuite/g++.dg/lto/README
@@ -24,9 +24,9 @@  $ g++ -o <executable> a_0.o a_1.o a_2.o
 Tests that do not need more than one file are a special case
 where there is a single file named 'foo_0.C'.
 
-The only supported dg-lto-do option are 'compile', 'run' and 'link'.
+The only supported dg-lto-do option are 'assemble', 'run' and 'link'.
 Additionally, these can only be used in the main file.  If
-'compile' is used, only the individual object files are
+'assemble' is used, only the individual object files are
 generated.  If 'link' is used, the final executable is generated
 but not executed (in this case, function main() needs to exist
 but it does not need to do anything).  If 'run' is used, the
diff --git a/gcc/testsuite/g++.dg/lto/pr52035_0.C b/gcc/testsuite/g++.dg/lto/pr52035_0.C
new file mode 100644
index 0000000..3de4ea5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr52035_0.C
@@ -0,0 +1,14 @@ 
+// PR c++/52035
+// { dg-lto-do assemble }
+
+template <typename T> struct QVector {
+    typedef T* iterator;
+    static void insert(int n);
+    typedef int size_type;
+};
+template <typename T> void QVector<T>::insert(size_type n) {}
+void error()
+{
+    int n;
+    QVector<int>::insert(n);
+}