c++: don't predeclare std::type_info [PR48396]
We've always predeclared std::type_info, which has been wrong for a while,
but now with modules it becomes more of a practical problem, if we want to
declare it in the purview of a module. So don't predeclare it. For
building up the type_info information to write out with the vtable, we can
use void* instead of type_info*, since they already aren't the real types.
PR c++/48396
gcc/cp/ChangeLog:
* cp-tree.h (enum cp_tree_index): Remove CPTI_TYPE_INFO_PTR_TYPE.
(type_info_ptr_type): Remove.
* rtti.c (init_rtti_processing): Don't predeclare std::type_info.
(typeid_ok_p): Check for null const_type_info_type_node.
(type_info_ptr_type, get_void_tinfo_ptr): New fns.
(get_tinfo_decl_dynamic, get_tinfo_ptr): Use them.
(ptr_initializer, ptm_initializer, get_pseudo_ti_init): Use them.
(get_tinfo_desc): Use const_ptr_type_node.
gcc/testsuite/ChangeLog:
* g++.dg/rtti/undeclared1.C: New test.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a82747c..060d1a0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -204,12 +204,11 @@
/* These are created at init time, but the library/headers provide
definitions. */
CPTI_ALIGN_TYPE,
- CPTI_CONST_TYPE_INFO_TYPE,
- CPTI_TYPE_INFO_PTR_TYPE,
CPTI_TERMINATE_FN,
CPTI_CALL_UNEXPECTED_FN,
/* These are lazily inited. */
+ CPTI_CONST_TYPE_INFO_TYPE,
CPTI_GET_EXCEPTION_PTR_FN,
CPTI_BEGIN_CATCH_FN,
CPTI_END_CATCH_FN,
@@ -251,7 +250,6 @@
#define abi_node cp_global_trees[CPTI_ABI]
#define global_namespace cp_global_trees[CPTI_GLOBAL]
#define const_type_info_type_node cp_global_trees[CPTI_CONST_TYPE_INFO_TYPE]
-#define type_info_ptr_type cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE]
#define conv_op_marker cp_global_trees[CPTI_CONV_OP_MARKER]
#define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL]
#define current_aggr cp_global_trees[CPTI_AGGR_TAG]
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index fcb3308..9c5066b 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -125,7 +125,6 @@
static tree build_dynamic_cast_1 (location_t, tree, tree, tsubst_flags_t);
static tree throw_bad_cast (void);
static tree throw_bad_typeid (void);
-static tree get_tinfo_ptr (tree);
static bool typeid_ok_p (void);
static int qualifier_flags (tree);
static bool target_incomplete_p (tree);
@@ -142,22 +141,11 @@
static int doing_runtime = 0;
-/* Declare language defined type_info type and a pointer to const
- type_info. This is incomplete here, and will be completed when
- the user #includes <typeinfo>. There are language defined
- restrictions on what can be done until that is included. Create
- the internal versions of the ABI types. */
+/* Create the internal versions of the ABI types. */
void
init_rtti_processing (void)
{
- push_nested_namespace (std_node);
- tree type_info_type = xref_tag (class_type, get_identifier ("type_info"));
- pop_nested_namespace (std_node);
- const_type_info_type_node
- = cp_build_qualified_type (type_info_type, TYPE_QUAL_CONST);
- type_info_ptr_type = build_pointer_type (const_type_info_type_node);
-
vec_alloc (unemitted_tinfo_decls, 124);
create_tinfo_types ();
@@ -238,6 +226,33 @@
return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
}
+/* const type_info*. */
+
+inline tree
+type_info_ptr_type ()
+{
+ return build_pointer_type (const_type_info_type_node);
+}
+
+/* Return a pointer to a type_info object describing TYPE, suitably
+ cast to the language defined type (for typeid) or void (for building
+ up the descriptors). */
+
+static tree
+get_tinfo_ptr (tree type, bool voidp = false)
+{
+ tree decl = get_tinfo_decl (type);
+ mark_used (decl);
+
+ tree ptype = voidp ? const_ptr_type_node : type_info_ptr_type ();
+ return build_nop (ptype, build_address (decl));
+}
+static inline tree
+get_void_tinfo_ptr (tree type)
+{
+ return get_tinfo_ptr (type, true);
+}
+
/* Return an lvalue expression whose type is "const std::type_info"
and whose value indicates the type of the expression EXP. If EXP
is a reference to a polymorphic class, return the dynamic type;
@@ -278,7 +293,7 @@
index = build_int_cst (NULL_TREE,
-1 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
t = build_vtbl_ref (exp, index);
- t = convert (type_info_ptr_type, t);
+ t = convert (type_info_ptr_type (), t);
}
else
/* Otherwise return the type_info for the static type of the expr. */
@@ -296,15 +311,22 @@
return false;
}
- if (!COMPLETE_TYPE_P (const_type_info_type_node))
+ if (!const_type_info_type_node)
{
- gcc_rich_location richloc (input_location);
- maybe_add_include_fixit (&richloc, "<typeinfo>", false);
- error_at (&richloc,
- "must %<#include <typeinfo>%> before using"
- " %<typeid%>");
+ tree name = get_identifier ("type_info");
+ tree decl = lookup_qualified_name (std_node, name);
+ if (TREE_CODE (decl) != TYPE_DECL)
+ {
+ gcc_rich_location richloc (input_location);
+ maybe_add_include_fixit (&richloc, "<typeinfo>", false);
+ error_at (&richloc,
+ "must %<#include <typeinfo>%> before using"
+ " %<typeid%>");
- return false;
+ return false;
+ }
+ const_type_info_type_node
+ = cp_build_qualified_type (TREE_TYPE (decl), TYPE_QUAL_CONST);
}
tree pseudo = TYPE_MAIN_VARIANT (get_tinfo_desc (TK_TYPE_INFO_TYPE)->type);
@@ -471,19 +493,6 @@
return d;
}
-/* Return a pointer to a type_info object describing TYPE, suitably
- cast to the language defined type. */
-
-static tree
-get_tinfo_ptr (tree type)
-{
- tree decl = get_tinfo_decl (type);
-
- mark_used (decl);
- return build_nop (type_info_ptr_type,
- build_address (decl));
-}
-
/* Return the type_info object for TYPE. */
tree
@@ -1032,7 +1041,7 @@
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, flags));
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
- get_tinfo_ptr (TYPE_MAIN_VARIANT (to)));
+ get_void_tinfo_ptr (TYPE_MAIN_VARIANT (to)));
init = build_constructor (init_list_type_node, v);
TREE_CONSTANT (init) = 1;
@@ -1063,8 +1072,8 @@
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, flags));
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
- get_tinfo_ptr (TYPE_MAIN_VARIANT (to)));
- CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, get_tinfo_ptr (klass));
+ get_void_tinfo_ptr (TYPE_MAIN_VARIANT (to)));
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, get_void_tinfo_ptr (klass));
init = build_constructor (init_list_type_node, v);
TREE_CONSTANT (init) = 1;
@@ -1156,7 +1165,7 @@
case TK_SI_CLASS_TYPE:
{
tree base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), 0);
- tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
+ tree tinfo = get_void_tinfo_ptr (BINFO_TYPE (base_binfo));
/* get_tinfo_ptr might have reallocated the tinfo_descs vector. */
ti = &(*tinfo_descs)[tk_index];
@@ -1187,7 +1196,7 @@
if ((*base_accesses)[ix] == access_public_node)
flags |= 2;
- tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
+ tinfo = get_void_tinfo_ptr (BINFO_TYPE (base_binfo));
if (BINFO_VIRTUAL_P (base_binfo))
{
/* We store the vtable offset at which the virtual
@@ -1360,7 +1369,7 @@
/* Base class internal helper. Pointer to base type, offset to
base, flags. */
tree fld_ptr = build_decl (BUILTINS_LOCATION, FIELD_DECL,
- NULL_TREE, type_info_ptr_type);
+ NULL_TREE, const_ptr_type_node);
DECL_CHAIN (fld_ptr) = fields;
fields = fld_ptr;
@@ -1396,7 +1405,7 @@
fields = fld_mask;
tree fld_ptr = build_decl (BUILTINS_LOCATION, FIELD_DECL,
- NULL_TREE, type_info_ptr_type);
+ NULL_TREE, const_ptr_type_node);
DECL_CHAIN (fld_ptr) = fields;
fields = fld_ptr;
@@ -1404,7 +1413,7 @@
{
/* Add a pointer to the class too. */
tree fld_cls = build_decl (BUILTINS_LOCATION, FIELD_DECL,
- NULL_TREE, type_info_ptr_type);
+ NULL_TREE, const_ptr_type_node);
DECL_CHAIN (fld_cls) = fields;
fields = fld_cls;
}
@@ -1421,7 +1430,7 @@
class. This is really a descendant of
__class_type_info. */
tree fld_ptr = build_decl (BUILTINS_LOCATION, FIELD_DECL,
- NULL_TREE, type_info_ptr_type);
+ NULL_TREE, const_ptr_type_node);
DECL_CHAIN (fld_ptr) = fields;
fields = fld_ptr;
break;
diff --git a/gcc/testsuite/g++.dg/rtti/undeclared1.C b/gcc/testsuite/g++.dg/rtti/undeclared1.C
new file mode 100644
index 0000000..9594c22
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/undeclared1.C
@@ -0,0 +1,5 @@
+// PR c++/48396
+
+namespace std {
+ type_info *p; // { dg-error "type_info" }
+}