From patchwork Tue Nov 3 21:15:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1393427 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=ag0feDV0; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CQjHx1mnbz9sXx for ; Wed, 4 Nov 2020 08:15:57 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C0BCD39874A1; Tue, 3 Nov 2020 21:15:54 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qk1-x732.google.com (mail-qk1-x732.google.com [IPv6:2607:f8b0:4864:20::732]) by sourceware.org (Postfix) with ESMTPS id 09639398748A for ; Tue, 3 Nov 2020 21:15:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 09639398748A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nathanmsidwell@gmail.com Received: by mail-qk1-x732.google.com with SMTP id k9so16624944qki.6 for ; Tue, 03 Nov 2020 13:15:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:subject:to:references:message-id:date:user-agent :mime-version:in-reply-to:content-language; bh=m9DwVFXhfHKUKuVWEu6S7vgIT97ypx1mlWE7yVr4M44=; b=ag0feDV0J9KwLSD/qnEXd41w440+YEgVvv9tU1xZCcQaYajIvsZi3SPO1zquMm5pXZ uJjphKi8sB++s4uBmCbH4Jbtpbo4whRcW5vzZq8xKl1RjY+xxZKD+erNwyTAzCRMBoci uZNSeqbnGUPTwqbyz0HuhnLfRlg433kWSMUf1h384mnqU/2fJAhDARp16A/0jUsKYZ8V 2pW6xDKnXfFW/EwWLvx3yIKelVDDrYUBjMDl4x3Voo6lQyOCgI9n4cO4SEEijVtUQplF oWI4qxs0z19AqMKuwBQ1EOM5+YFKFl5tQaKTcCSXM+ahjVljALzvucsiPnoiqLwH936H fAXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:subject:to:references:message-id :date:user-agent:mime-version:in-reply-to:content-language; bh=m9DwVFXhfHKUKuVWEu6S7vgIT97ypx1mlWE7yVr4M44=; b=ZEABFOv3JV+Hbs8jR6gSKigv1pXr30yZbHmJ98jQNAzKLik4QvPJkhpPYgzsFZ6oS1 Y5vxIjWfA7HlWzmnV/zFRIsZVlGGgYDJGWdLAXxDZjYMSJix5+Hxct0YCpztE9QUaiWH l80Q6dfq/kpS5EOdk8r3KuTbTp84pMpQZWaX/iA0S1oM12C560H8l6er6ydq9JcGXm0y A5OIL6CpXL7FRlDiYWLCaYFSLFc1BufXej4g0MBVnOFR77ZZgO2Rqd357Z91Rz3G2hNy UjeuKA2OuxGjbDcrext42kpJPrwtaEfhk1fy3BHWztx/ZY2yL0nJBLGZwHQxou/U6stO 54Zg== X-Gm-Message-State: AOAM532Pr0D34PgCaeOJMWLWzK9zIBOGl39xdcEMe2tLnkA8km4qIvxc UQjcDNjNKBLqSQ3F3gqpu+o= X-Google-Smtp-Source: ABdhPJyUFAFc2j9U9UlhIRvoHwt1unm7ww60511ed382eKDzqQbSGXdQG5Ja06WegzQ25UfBk4uhPA== X-Received: by 2002:a37:73c6:: with SMTP id o189mr21923277qkc.216.1604438151287; Tue, 03 Nov 2020 13:15:51 -0800 (PST) Received: from ?IPv6:2620:10d:c0a8:1102:e5ef:7eb4:1609:98bb? ([2620:10d:c091:480::1:bc2d]) by smtp.googlemail.com with ESMTPSA id p77sm11494900qke.39.2020.11.03.13.15.49 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 03 Nov 2020 13:15:50 -0800 (PST) From: Nathan Sidwell Subject: [16/32] new C++ infrastructure To: GCC Patches , Jason Merrill , Richard Biener References: <7fc9e868-3db9-4972-ed67-6ff249f549c3@acm.org> <0bdf00a8-d8ad-9e97-134d-6668c0e8c86b@acm.org> <85996243-86cf-88b4-5b3b-451eaf3a0df6@acm.org> <4d14b230-3263-9a13-3159-c4853f282761@acm.org> <688bd28f-5998-0def-8c40-03b817832d63@acm.org> <89819c10-e86d-9b01-5673-5223a525a135@acm.org> <35879e15-d74a-c664-4d44-15f4b3783d77@acm.org> <9ae23c4c-67a5-a267-c939-5a96e9488612@acm.org> <6666545b-0583-4812-4745-d51994465818@acm.org> Message-ID: <9d1fa530-8f5a-3603-5d60-5ef10c09e9b2@acm.org> Date: Tue, 3 Nov 2020 16:15:49 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" We have to expose a few entry points in the c++ handling. when loading a module we need to do template argument comparisons and not resolve typenames. I added a comparing_typenames global flag that;ll end up doing a but more than the 'comparing_specializations' flag we already have. Some of the node creation routines need lower level access. The rtti machinery needs to be driven externally. We need to create template type parameters, and we need to create explicitly dependent array types (we can't call dependent_type_p in the middle of loading something). Oh, this also has some pieces handling parameter packs as structurally-compared types. IIRC when we fixed some of that in the GCC10 release, we tried to handle them as not-types. I never addressed that on the modules branch. nathan diff --git c/gcc/cp/cp-tree.h w/gcc/cp/cp-tree.h index fdb8ee57f0b..e8e4d0af2d8 100644 --- c/gcc/cp/cp-tree.h +++ w/gcc/cp/cp-tree.h @@ -5327,6 +5500,10 @@ extern int function_depth; in structrual_comptypes. */ extern int comparing_specializations; +/* Nonzero if we are inside eq_specializations, which affects + resolving of typenames in structural_comptypes. */ +extern int comparing_typenames; + /* In parser.c. */ /* Nonzero if we are parsing an unevaluated operand: an operand to @@ -6457,6 +6651,7 @@ extern bool check_omp_return (void); extern tree make_typename_type (tree, tree, enum tag_types, tsubst_flags_t); extern tree build_typename_type (tree, tree, tree, tag_types); extern tree make_unbound_class_template (tree, tree, tree, tsubst_flags_t); +extern tree make_unbound_class_template_raw (tree, tree, tree); extern tree build_library_fn_ptr (const char *, tree, int); extern tree build_cp_library_fn_ptr (const char *, tree, int); extern tree push_library_fn (tree, tree, tree, int); @@ -6731,8 +6926,11 @@ extern tree unqualified_fn_lookup_error (cp_expr); extern tree make_conv_op_name (tree); extern tree build_lang_decl (enum tree_code, tree, tree); extern tree build_lang_decl_loc (location_t, enum tree_code, tree, tree); +extern bool maybe_add_lang_decl_raw (tree, bool decomp_p); +extern bool maybe_add_lang_type_raw (tree); extern void retrofit_lang_decl (tree); extern void fit_decomposition_lang_decl (tree, tree); +extern void fit_ptrmem_type_decl (tree, tree); extern tree copy_decl (tree CXX_MEM_STAT_INFO); extern tree copy_type (tree CXX_MEM_STAT_INFO); extern tree cxx_make_type (enum tree_code CXX_MEM_STAT_INFO); @@ -6793,6 +7089,7 @@ extern void maybe_show_extern_c_location (void); extern bool literal_integer_zerop (const_tree); /* in pt.c */ +extern tree canonical_type_parameter (tree); extern void push_access_scope (tree); extern void pop_access_scope (tree); extern bool check_template_shadow (tree); @@ -6986,6 +7293,7 @@ extern GTY(()) vec *unemitted_tinfo_decls; extern void init_rtti_processing (void); extern tree build_typeid (tree, tsubst_flags_t); +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 build_headof (tree); @@ -6993,6 +7301,8 @@ extern tree build_dynamic_cast (location_t, tree, tree, tsubst_flags_t); extern void emit_support_tinfos (void); extern bool emit_tinfo_decl (tree); +extern unsigned get_pseudo_tinfo_index (tree); +extern tree get_pseudo_tinfo_type (unsigned); /* in search.c */ extern bool accessible_base_p (tree, tree, bool); @@ -7340,7 +7650,7 @@ extern bool is_local_temp (tree); extern tree build_aggr_init_expr (tree, tree); extern tree get_target_expr (tree); extern tree get_target_expr_sfinae (tree, tsubst_flags_t); -extern tree build_cplus_array_type (tree, tree); +extern tree build_cplus_array_type (tree, tree, int is_dep = -1); extern tree build_array_of_n_type (tree, int); extern bool array_of_runtime_bound_p (tree); extern bool vla_type_p (tree); diff --git c/gcc/cp/lex.c w/gcc/cp/lex.c index 8a69bc4f170..013cbadf625 100644 --- c/gcc/cp/lex.c +++ w/gcc/cp/lex.c @@ -678,7 +880,7 @@ build_lang_decl_loc (location_t loc, enum tree_code code, tree name, tree type) /* Maybe add a raw lang_decl to T, a decl. Return true if it needed one. */ -static bool +bool maybe_add_lang_decl_raw (tree t, bool decomp_p) { size_t size; @@ -803,6 +1005,9 @@ cxx_dup_lang_specific_decl (tree node) struct lang_decl *ld = (struct lang_decl *) ggc_internal_alloc (size); memcpy (ld, DECL_LANG_SPECIFIC (node), size); DECL_LANG_SPECIFIC (node) = ld; + DECL_MODULE_ENTITY_P (node) = false; + DECL_MODULE_IMPORT_P (node) = false; + DECL_ATTACHED_DECLS_P (node) = false; if (GATHER_STATISTICS) { @@ -831,8 +1036,7 @@ copy_lang_type (tree node) if (! TYPE_LANG_SPECIFIC (node)) return; - struct lang_type *lt - = (struct lang_type *) ggc_internal_alloc (sizeof (struct lang_type)); + auto *lt = (struct lang_type *) ggc_internal_alloc (sizeof (struct lang_type)); memcpy (lt, TYPE_LANG_SPECIFIC (node), (sizeof (struct lang_type))); TYPE_LANG_SPECIFIC (node) = lt; @@ -858,15 +1062,15 @@ copy_type (tree type MEM_STAT_DECL) /* Add a raw lang_type to T, a type, should it need one. */ -static bool +bool maybe_add_lang_type_raw (tree t) { if (!RECORD_OR_UNION_CODE_P (TREE_CODE (t))) return false; - TYPE_LANG_SPECIFIC (t) - = (struct lang_type *) (ggc_internal_cleared_alloc - (sizeof (struct lang_type))); + auto *lt = (struct lang_type *) (ggc_internal_cleared_alloc + (sizeof (struct lang_type))); + TYPE_LANG_SPECIFIC (t) = lt; if (GATHER_STATISTICS) { diff --git c/gcc/cp/pt.c w/gcc/cp/pt.c index aa162d2a4f9..497ac5aafec 100644 --- c/gcc/cp/pt.c +++ w/gcc/cp/pt.c @@ -1709,9 +1708,11 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, return spec; } -/* Returns true iff two spec_entry nodes are equivalent. */ - +/* Restricts tree and type comparisons. */ int comparing_specializations; +int comparing_typenames; + +/* Returns true iff two spec_entry nodes are equivalent. */ bool spec_hasher::equal (spec_entry *e1, spec_entry *e2) @@ -1719,6 +1720,7 @@ spec_hasher::equal (spec_entry *e1, spec_entry *e2) int equal; ++comparing_specializations; + ++comparing_typenames; equal = (e1->tmpl == e2->tmpl && comp_template_args (e1->args, e2->args)); if (equal && flag_concepts @@ -1734,6 +1736,7 @@ spec_hasher::equal (spec_entry *e1, spec_entry *e2) equal = equivalent_constraints (c1, c2); } --comparing_specializations; + --comparing_typenames; return equal; } @@ -4435,7 +4438,7 @@ build_template_parm_index (int index, parameter. Returns the canonical type parameter, which may be TYPE if no such parameter existed. */ -static tree +tree canonical_type_parameter (tree type) { int idx = TEMPLATE_TYPE_IDX (type); @@ -13205,19 +13244,24 @@ tsubst_argument_pack (tree orig_arg, tree args, tsubst_flags_t complain, tree in_decl) { /* Substitute into each of the arguments. */ - tree new_arg = TYPE_P (orig_arg) - ? cxx_make_type (TREE_CODE (orig_arg)) - : make_node (TREE_CODE (orig_arg)); - tree pack_args = tsubst_template_args (ARGUMENT_PACK_ARGS (orig_arg), args, complain, in_decl); - if (pack_args == error_mark_node) - new_arg = error_mark_node; - else - SET_ARGUMENT_PACK_ARGS (new_arg, pack_args); + tree new_arg = error_mark_node; + if (pack_args != error_mark_node) + { + if (TYPE_P (orig_arg)) + { + new_arg = cxx_make_type (TREE_CODE (orig_arg)); + SET_TYPE_STRUCTURAL_EQUALITY (new_arg); + } + else + { + new_arg = make_node (TREE_CODE (orig_arg)); + TREE_CONSTANT (new_arg) = TREE_CONSTANT (orig_arg); + } - if (TREE_CODE (new_arg) == NONTYPE_ARGUMENT_PACK) - TREE_CONSTANT (new_arg) = TREE_CONSTANT (orig_arg); + SET_ARGUMENT_PACK_ARGS (new_arg, pack_args); + } return new_arg; } diff --git c/gcc/cp/typeck.c w/gcc/cp/typeck.c index d3b701610cf..49b895349c8 100644 --- c/gcc/cp/typeck.c +++ w/gcc/cp/typeck.c @@ -1256,16 +1256,15 @@ structural_comptypes (tree t1, tree t2, int strict) gcc_assert (TYPE_P (t1) && TYPE_P (t2)); - if (!comparing_specializations) - { - /* TYPENAME_TYPEs should be resolved if the qualifying scope is the - current instantiation. */ - if (TREE_CODE (t1) == TYPENAME_TYPE) - t1 = resolve_typename_type (t1, /*only_current_p=*/true); - - if (TREE_CODE (t2) == TYPENAME_TYPE) - t2 = resolve_typename_type (t2, /*only_current_p=*/true); - } + /* TYPENAME_TYPEs should be resolved if the qualifying scope is the + current instantiation, and we don't care about typename + structural equality. The comparing_typenames check is after the + code check, in order to early-out the common case. */ + if (TREE_CODE (t1) == TYPENAME_TYPE && !comparing_typenames) + t1 = resolve_typename_type (t1, /*only_current_p=*/true); + + if (TREE_CODE (t2) == TYPENAME_TYPE && !comparing_typenames) + t2 = resolve_typename_type (t2, /*only_current_p=*/true); if (TYPE_PTRMEMFUNC_P (t1)) t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1); diff --git c/gcc/cp/rtti.c w/gcc/cp/rtti.c index 887aae31bf6..0be9eff54ad 100644 --- c/gcc/cp/rtti.c +++ w/gcc/cp/rtti.c @@ -123,7 +123,6 @@ static GTY (()) vec *tinfo_descs; static tree ifnonnull (tree, tree, tsubst_flags_t); static tree tinfo_name (tree, bool); -static tree get_tinfo_decl_direct (tree type, tree name, int pseudo_ix); 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); @@ -431,7 +434,7 @@ get_tinfo_decl (tree type) /* Get or create a tinfo VAR_DECL directly from the provided information. The caller must have already checked it is valid to do so. */ -static tree +tree get_tinfo_decl_direct (tree type, tree name, int pseudo_ix) { /* For a class type, the variable is cached in the type node @@ -1491,6 +1495,36 @@ get_tinfo_desc (unsigned ix) return res; } +/* Return an identifying index for the pseudo type_info TYPE. + We wrote the index at the end of the name, so just scan it from + there. This isn't critical, as it's only on the first use of this + type during module stream out. */ + +unsigned +get_pseudo_tinfo_index (tree type) +{ + tree name = DECL_NAME (TYPE_NAME (type)); + unsigned ix = 0, scale = 1; + size_t len = IDENTIFIER_LENGTH (name); + const char *ptr = IDENTIFIER_POINTER (name) + len; + + for (; *--ptr != '_'; scale *= 10) + { + len--; + gcc_checking_assert (len && ISDIGIT (*ptr)); + ix += (*ptr - '0') * scale; + } + + gcc_assert (len != IDENTIFIER_LENGTH (name)); + return ix; +} + +tree +get_pseudo_tinfo_type (unsigned ix) +{ + return get_tinfo_desc (ix)->type; +} + /* We lazily create the type info types. */ static void diff --git c/gcc/cp/tree.c w/gcc/cp/tree.c index 3087c4ab52c..d125fa5e793 100644 --- c/gcc/cp/tree.c +++ w/gcc/cp/tree.c @@ -998,7 +998,7 @@ build_min_array_type (tree elt_type, tree index_type) build_cplus_array_type. */ static void -set_array_type_canon (tree t, tree elt_type, tree index_type) +set_array_type_canon (tree t, tree elt_type, tree index_type, bool dep) { /* Set the canonical type for this new node. */ if (TYPE_STRUCTURAL_EQUALITY_P (elt_type) @@ -1009,30 +1009,33 @@ set_array_type_canon (tree t, tree elt_type, tree index_type) TYPE_CANONICAL (t) = build_cplus_array_type (TYPE_CANONICAL (elt_type), index_type - ? TYPE_CANONICAL (index_type) : index_type); + ? TYPE_CANONICAL (index_type) : index_type, + dep); else TYPE_CANONICAL (t) = t; } /* Like build_array_type, but handle special C++ semantics: an array of a variant element type is a variant of the array of the main variant of - the element type. */ + the element type. IS_DEPENDENT is -ve if we should determine the + dependency. Otherwise its bool value indicates dependency. */ tree -build_cplus_array_type (tree elt_type, tree index_type) +build_cplus_array_type (tree elt_type, tree index_type, int dependent) { tree t; if (elt_type == error_mark_node || index_type == error_mark_node) return error_mark_node; - bool dependent = (uses_template_parms (elt_type) - || (index_type && uses_template_parms (index_type))); + if (dependent < 0) + dependent = (uses_template_parms (elt_type) + || (index_type && uses_template_parms (index_type))); if (elt_type != TYPE_MAIN_VARIANT (elt_type)) /* Start with an array of the TYPE_MAIN_VARIANT. */ t = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type), - index_type); + index_type, dependent); else if (dependent) { /* Since type_hash_canon calls layout_type, we need to use our own @@ -1062,7 +1065,11 @@ build_cplus_array_type (tree elt_type, tree index_type) *e = t; /* Set the canonical type for this new node. */ - set_array_type_canon (t, elt_type, index_type); + set_array_type_canon (t, elt_type, index_type, dependent); + + /* Mark it as dependent now, this saves time later. */ + TYPE_DEPENDENT_P_VALID (t) = true; + TYPE_DEPENDENT_P (t) = true; } } else @@ -1083,7 +1090,7 @@ build_cplus_array_type (tree elt_type, tree index_type) if (!t) { t = build_min_array_type (elt_type, index_type); - set_array_type_canon (t, elt_type, index_type); + set_array_type_canon (t, elt_type, index_type, dependent); if (!dependent) { layout_type (t); @@ -1319,7 +1326,8 @@ cp_build_qualified_type_real (tree type, if (!t) { - t = build_cplus_array_type (element_type, TYPE_DOMAIN (type)); + t = build_cplus_array_type (element_type, TYPE_DOMAIN (type), + TYPE_DEPENDENT_P (type)); /* Keep the typedef name. */ if (TYPE_NAME (t) != TYPE_NAME (type)) @@ -1555,7 +1563,7 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags) case ARRAY_TYPE: type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags); t0 = strip_typedefs (TYPE_DOMAIN (t), remove_attributes, flags); - result = build_cplus_array_type (type, t0); + result = build_cplus_array_type (type, t0, TYPE_DEPENDENT_P (t)); break; case FUNCTION_TYPE: case METHOD_TYPE: