This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]