From: Patrick Palka Date: Mon, 15 Dec 2025 20:03:36 +0000 (-0500) Subject: c++: restrict TYPE_POLYMORPHIC_P to class types X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=09a9ae0dcb34ef7c57ef997f017eb5a2ddb926d4;p=thirdparty%2Fgcc.git c++: restrict TYPE_POLYMORPHIC_P to class types Since TYPE_POLYMORPHIC_P shares the same storage as other flags for TYPENAME_TYPE and DECLTYPE_TYPE, we should avoid accidentally using this accessor on those tree codes. This patch restricts the accessor to RECORD/UNION_TYPE which allows callers to conveniently guard any uses with CLASS_TYPE_P. Otherwise with the next patch applied that rearranges TYPENAME_TYPE flags, noexcept_override_late_checks would not skip over a TYPENAME_TYPE base for which TYPE_POLYMORPHIC_P nonsensically returns true, leading to an eventual ICE. gcc/cp/ChangeLog: * cp-tree.h (CLASSTYPE_LAMBDA_EXPR): Check CLASS_TYPE_P before inspecting TYPE_POLYMORPHIC_P. (TYPE_POLYMORPHIC_P): Restrict to RECORD_TYPE or UNION_TYPE. Document its use of TREE_LANG_FLAG_2. * parser.cc (noexcept_override_late_checks): Only check TYPE_POLYMORPHIC_P on CLASS_TYPE_P types. * rtti.cc (build_headof): Likewise. (get_tinfo_ptr_dynamic): Likewise. (build_typeid): Likewise. Reviewed-by: Jason Merrill --- diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 180c0cad593..6f244a8bdfd 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -481,6 +481,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL) STATEMENT_LIST_TRY_BLOCK (in STATEMENT_LIST) TYPENAME_IS_RESOLVING_P (in TYPENAME_TYPE) + TYPE_POLYMORPHIC_P (in RECORD_TYPE and UNION_TYPE) TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR) FNDECL_USED_AUTO (in FUNCTION_DECL) DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE) @@ -2815,7 +2816,7 @@ struct GTY(()) lang_type { /* The associated LAMBDA_EXPR that made this class. */ #define CLASSTYPE_LAMBDA_EXPR(NODE) \ - (TYPE_POLYMORPHIC_P (NODE) \ + (CLASS_TYPE_P (NODE) && TYPE_POLYMORPHIC_P (NODE) \ ? NULL_TREE \ : LANG_TYPE_CLASS_CHECK (NODE)->key_method) #define SET_CLASSTYPE_LAMBDA_EXPR(NODE, VALUE) \ @@ -4570,7 +4571,8 @@ get_vec_init_expr (tree t) A class that declares or inherits a virtual function is called a polymorphic class. */ -#define TYPE_POLYMORPHIC_P(NODE) (TREE_LANG_FLAG_2 (NODE)) +#define TYPE_POLYMORPHIC_P(NODE) \ + (TREE_LANG_FLAG_2 (RECORD_OR_UNION_CHECK (NODE))) /* Nonzero if this class has a virtual function table pointer. */ #define TYPE_CONTAINS_VPTR_P(NODE) \ diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 74c08f23188..17199e013ba 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -31060,7 +31060,7 @@ noexcept_override_late_checks (tree fndecl, tree class_type) { tree basetype = BINFO_TYPE (base_binfo); - if (!TYPE_POLYMORPHIC_P (basetype)) + if (!CLASS_TYPE_P (basetype) || !TYPE_POLYMORPHIC_P (basetype)) continue; tree fn = look_for_overrides_here (basetype, fndecl); diff --git a/gcc/cp/rtti.cc b/gcc/cp/rtti.cc index c06a18b3ff1..1e787157b7b 100644 --- a/gcc/cp/rtti.cc +++ b/gcc/cp/rtti.cc @@ -166,7 +166,7 @@ build_headof (tree exp) gcc_assert (TYPE_PTR_P (type)); type = TREE_TYPE (type); - if (!TYPE_POLYMORPHIC_P (type)) + if (!CLASS_TYPE_P (type) || !TYPE_POLYMORPHIC_P (type)) return exp; /* We use this a couple of times below, protect it. */ @@ -280,7 +280,9 @@ get_tinfo_ptr_dynamic (tree exp, tsubst_flags_t complain) return error_mark_node; /* If exp is a reference to polymorphic type, get the real type_info. */ - if (TYPE_POLYMORPHIC_P (type) && ! resolves_to_fixed_type_p (exp, 0)) + if (CLASS_TYPE_P (type) + && TYPE_POLYMORPHIC_P (type) + && ! resolves_to_fixed_type_p (exp, 0)) { /* build reference to type_info from vtable. */ tree index; @@ -353,7 +355,8 @@ build_typeid (tree exp, tsubst_flags_t complain) if (processing_template_decl) return build_min (TYPEID_EXPR, const_type_info_type_node, exp); - if (TYPE_POLYMORPHIC_P (TREE_TYPE (exp)) + if (CLASS_TYPE_P (TREE_TYPE (exp)) + && TYPE_POLYMORPHIC_P (TREE_TYPE (exp)) && ! resolves_to_fixed_type_p (exp, &nonnull) && ! nonnull) {