[gcc r17-3533] c++: modules vs typeid [PR124888]
Jason Merrill via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:f1933b5ba13bb2abd1329cfb1ba9501c90f4c516 commit r17-3533-gf1933b5ba13bb2abd1329cfb1ba9501c90f4c516 Author: Jason Merrill <[email protected]> Date: Fri Aug 21 20:14:25 2026 -0400 c++: modules vs typeid [PR124888] Instantiating a template from a TU which included <typeinfo> in an importing TU which didn't should still work. Instead of messing with lookup in the other TU, let's reuse the type that we already gave the TYPEID_EXPR. PR c++/124888 gcc/cp/ChangeLog: * pt.cc (tsubst_expr): Pass type to {get,build}_typeid. * rtti.cc (build_typeid, get_typeid): Take it. (type_info_ptr_type): Remove. (get_tinfo_ptr): Take tinfo_ptr_type instead of voidp. (get_tinfo_ptr_dynamic): Likewise. (get_void_tinfo_ptr): Pass const_ptr_type_node. * cp-tree.h (build_typeid, get_typeid): Adjust. gcc/testsuite/ChangeLog: * g++.dg/modules/typeid-2_a.C: New test. * g++.dg/modules/typeid-2_b.C: New test. Diff: --- gcc/cp/cp-tree.h | 4 +-- gcc/cp/pt.cc | 4 +-- gcc/cp/rtti.cc | 53 +++++++++++++++++-------------- gcc/testsuite/g++.dg/modules/typeid-2_a.C | 12 +++++++ gcc/testsuite/g++.dg/modules/typeid-2_b.C | 12 +++++++ 5 files changed, 58 insertions(+), 27 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a8af4d389450..76468700fc62 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8413,10 +8413,10 @@ extern tree convert_reflect_constant_arg (tree, tree); extern GTY(()) vec<tree, va_gc> *unemitted_tinfo_decls; extern void init_rtti_processing (void); -extern tree build_typeid (tree, tsubst_flags_t); +extern tree build_typeid (tree, tsubst_flags_t, tree = NULL_TREE); extern tree get_tinfo_decl_direct (tree, tree, int); extern tree get_tinfo_decl (tree); -extern tree get_typeid (tree, tsubst_flags_t); +extern tree get_typeid (tree, tsubst_flags_t, tree = NULL_TREE); extern tree build_headof (tree); extern tree build_dynamic_cast (location_t, tree, tree, tsubst_flags_t); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index d9a002e36b74..4f7943f625f1 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -23081,7 +23081,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (TYPE_P (operand_0)) { operand_0 = tsubst (operand_0, args, complain, in_decl); - RETURN (get_typeid (operand_0, complain)); + RETURN (get_typeid (operand_0, complain, TREE_TYPE (t))); } else { @@ -23103,7 +23103,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) operand = RECUR (operand_0); else operand = uneval; - RETURN (build_typeid (operand, complain)); + RETURN (build_typeid (operand, complain, TREE_TYPE (t))); } } diff --git a/gcc/cp/rtti.cc b/gcc/cp/rtti.cc index e92e8a7ddf66..fcca2bec8841 100644 --- a/gcc/cp/rtti.cc +++ b/gcc/cp/rtti.cc @@ -222,31 +222,22 @@ throw_bad_typeid (void) 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) +get_tinfo_ptr (tree type, tree tinfo_ptr_type) { 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)); + return build_nop (tinfo_ptr_type, build_address (decl)); } static inline tree get_void_tinfo_ptr (tree type) { - return get_tinfo_ptr (type, true); + return get_tinfo_ptr (type, const_ptr_type_node); } /* Return an lvalue expression whose type is "const std::type_info" @@ -255,7 +246,7 @@ get_void_tinfo_ptr (tree type) otherwise return the static type of the expression. */ static tree -get_tinfo_ptr_dynamic (tree exp, tsubst_flags_t complain) +get_tinfo_ptr_dynamic (tree exp, tsubst_flags_t complain, tree tinfo_ptr_type) { tree type; tree t; @@ -291,11 +282,11 @@ get_tinfo_ptr_dynamic (tree exp, tsubst_flags_t complain) 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 (tinfo_ptr_type, t); } else /* Otherwise return the type_info for the static type of the expr. */ - t = get_tinfo_ptr (type); + t = get_tinfo_ptr (type, tinfo_ptr_type); return t; } @@ -371,15 +362,22 @@ typeid_evaluated_p (tree exp, int *nonnull) an lvalue of type "const std::type_info". */ tree -build_typeid (tree exp, tsubst_flags_t complain) +build_typeid (tree exp, tsubst_flags_t complain, tree tinfo_type/*=NULL_TREE*/) { tree cond = NULL_TREE, initial_expr = exp; - if (exp == error_mark_node || !typeid_ok_p ()) + if (exp == error_mark_node) return error_mark_node; + if (!tinfo_type) + { + if (!typeid_ok_p ()) + return error_mark_node; + tinfo_type = const_type_info_type_node; + } + if (processing_template_decl) - return build_min (TYPEID_EXPR, const_type_info_type_node, exp); + return build_min (TYPEID_EXPR, tinfo_type, exp); int nonnull = 0; if (typeid_evaluated_p (exp, &nonnull)) @@ -394,7 +392,8 @@ build_typeid (tree exp, tsubst_flags_t complain) } } - exp = get_tinfo_ptr_dynamic (exp, complain); + exp = get_tinfo_ptr_dynamic (exp, complain, + build_pointer_type (tinfo_type)); if (exp == error_mark_node) return error_mark_node; @@ -528,13 +527,20 @@ get_tinfo_decl_direct (tree type, tree name, int pseudo_ix) /* Return the type_info object for TYPE. */ tree -get_typeid (tree type, tsubst_flags_t complain) +get_typeid (tree type, tsubst_flags_t complain, tree tinfo_type/*=NULL_TREE*/) { - if (type == error_mark_node || !typeid_ok_p ()) + if (type == error_mark_node) return error_mark_node; + if (!tinfo_type) + { + if (!typeid_ok_p ()) + return error_mark_node; + tinfo_type = const_type_info_type_node; + } + if (processing_template_decl) - return build_min (TYPEID_EXPR, const_type_info_type_node, type); + return build_min (TYPEID_EXPR, tinfo_type, type); /* If the type of the type-id is a reference type, the result of the typeid expression refers to a type_info object representing the @@ -563,7 +569,8 @@ get_typeid (tree type, tsubst_flags_t complain) if (!type) return error_mark_node; - return cp_build_fold_indirect_ref (get_tinfo_ptr (type)); + tinfo_type = build_pointer_type (tinfo_type); + return cp_build_fold_indirect_ref (get_tinfo_ptr (type, tinfo_type)); } /* Check whether TEST is null before returning RESULT. If TEST is used in diff --git a/gcc/testsuite/g++.dg/modules/typeid-2_a.C b/gcc/testsuite/g++.dg/modules/typeid-2_a.C new file mode 100644 index 000000000000..d0df289f9254 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/typeid-2_a.C @@ -0,0 +1,12 @@ +// PR c++/124888 +// { dg-additional-options -fmodules } + +module; +#include <typeinfo> +export module foo; + +export template <class T> +const std::type_info &f(T *p) +{ + return typeid (*p); +} diff --git a/gcc/testsuite/g++.dg/modules/typeid-2_b.C b/gcc/testsuite/g++.dg/modules/typeid-2_b.C new file mode 100644 index 000000000000..78a18c6c5f36 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/typeid-2_b.C @@ -0,0 +1,12 @@ +// { dg-additional-options -fmodules } + +import foo; + +struct A { }; +struct B { virtual void f() { } }; + +void g(A* a, B* b) +{ + f (a); + f (b); +}