aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2022-04-15 00:11:00 -0400
committerJason Merrill <jason@redhat.com>2022-04-28 22:59:10 -0400
commit97b30a399ef561f6f37a2c08c830fdf3141bb504 (patch)
treee5bef915442055e9d666eb2178cdc703331c6eb2
parent654f6978cdc85a3970ff2c478d4df3e55cf4d3ab (diff)
downloadgcc-97b30a399ef561f6f37a2c08c830fdf3141bb504.zip
gcc-97b30a399ef561f6f37a2c08c830fdf3141bb504.tar.gz
gcc-97b30a399ef561f6f37a2c08c830fdf3141bb504.tar.bz2
c++: typeid and instantiation [PR102651]
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. 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.
-rw-r--r--gcc/cp/rtti.cc15
-rw-r--r--gcc/testsuite/g++.dg/rtti/typeid-complete1.C14
2 files changed, 25 insertions, 4 deletions
diff --git a/gcc/cp/rtti.cc b/gcc/cp/rtti.cc
index a4dedc3..f5b43ec 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 0000000..8d3fec4
--- /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>** );
+}