diff mbox series

[pushed] c++: typeid and instantiation [PR102651]

Message ID 20220429030038.1097605-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: typeid and instantiation [PR102651] | expand

Commit Message

Jason Merrill April 29, 2022, 3 a.m. UTC
PR49387 was a problem with initially asking for a typeid for a class
template specialization before it was complete, and later actually filling
in the descriptor when the class was complete, and thus disagreeing on the
form of the descriptor.  I fixed that by forcing the class to be complete,
but this testcase shows why that approach is problematic.  So instead let's
adjust the type of the descriptor later if needed.

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

	PR c++/102651
	PR c++/49387

gcc/cp/ChangeLog:

	* rtti.cc (get_tinfo_decl_direct): Don't complete_type.
	(emit_tinfo_decl): Update tdesc type if needed.

gcc/testsuite/ChangeLog:

	* g++.dg/rtti/typeid-complete1.C: New test.
---
 gcc/cp/rtti.cc                               | 15 +++++++++++----
 gcc/testsuite/g++.dg/rtti/typeid-complete1.C | 14 ++++++++++++++
 2 files changed, 25 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/rtti/typeid-complete1.C


base-commit: 654f6978cdc85a3970ff2c478d4df3e55cf4d3ab
diff mbox series

Patch

diff --git a/gcc/cp/rtti.cc b/gcc/cp/rtti.cc
index a4dedc31f0a..f5b43ec0fb2 100644
--- a/gcc/cp/rtti.cc
+++ b/gcc/cp/rtti.cc
@@ -446,9 +446,6 @@  get_tinfo_decl_direct (tree type, tree name, int pseudo_ix)
 
   gcc_checking_assert (TREE_CODE (type) != METHOD_TYPE);
 
-  if (pseudo_ix < 0)
-    type = complete_type (type);
-
   if (CLASS_TYPE_P (type))
     d = CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type));
 
@@ -1693,7 +1690,17 @@  emit_tinfo_decl (tree decl)
       tree init;
 
       DECL_EXTERNAL (decl) = 0;
-      init = get_pseudo_ti_init (type, get_pseudo_ti_index (type));
+      int pseudo_ix = get_pseudo_ti_index (type);
+      const tinfo_s *ti = get_tinfo_desc (pseudo_ix);
+      if (TREE_TYPE (decl) != ti->type)
+	{
+	  /* If the class became complete since we first called get_tinfo_decl,
+	     its type_info descriptor may have switched from __class_type_info
+	     to e.g. __si_class_type_info.  */
+	  TREE_TYPE (decl) = ti->type;
+	  relayout_decl (decl);
+	}
+      init = get_pseudo_ti_init (type, pseudo_ix);
       DECL_INITIAL (decl) = init;
       mark_used (decl);
       cp_finish_decl (decl, init, false, NULL_TREE, 0);
diff --git a/gcc/testsuite/g++.dg/rtti/typeid-complete1.C b/gcc/testsuite/g++.dg/rtti/typeid-complete1.C
new file mode 100644
index 00000000000..8d3fec46801
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/typeid-complete1.C
@@ -0,0 +1,14 @@ 
+// PR c++/102651
+
+#include <typeinfo>
+
+template <typename T>
+struct S : T{
+    T x;
+};
+
+const void *p;
+int main()
+{
+  p = &typeid( S<void>** );
+}