From patchwork Thu Mar 11 17:50:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1451426 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; 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=CU4/+wQK; dkim-atps=neutral Received: from sourceware.org (unknown [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 4DxGgX57j5z9sS8 for ; Fri, 12 Mar 2021 04:50:15 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E573A3834427; Thu, 11 Mar 2021 17:50:11 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qv1-xf2f.google.com (mail-qv1-xf2f.google.com [IPv6:2607:f8b0:4864:20::f2f]) by sourceware.org (Postfix) with ESMTPS id C5F903834427 for ; Thu, 11 Mar 2021 17:50:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C5F903834427 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-qv1-xf2f.google.com with SMTP id h13so2944467qvu.6 for ; Thu, 11 Mar 2021 09:50:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=DXN1sWjivCpBNQYXCWmJyuTNyV8RzCS46T22FXsQy6Y=; b=CU4/+wQKmvt1vUYlyG8ll86EOseshVWwIL6DtcgMeXMyZz/2+mcHzMvL/GKMOxaYmm dBj/TAVQueDttb6yXiAop+tPseOXOnQaZDA12UM2ZpCxVP7RQgxJTC1k6+63/JXLD0ha j0u49H62v/ge9fD5SSAPl9LCppVFtapjwgVHkIf92IgD+VPuFYwq1BbhtgCtE2OrEgER MpokSL6nwVpPJ8y6o1THbijbrHn9DrrO3Oq6VQOlUL/b0xpHPLJAnVHFC66U1xM6vmLv ahdm4MJltiZkJh7NHE55yAn2j7SThCDcxDu/r2EnSx+28S7upxcE6LEh2Mh2YPZLpKj8 4cCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=DXN1sWjivCpBNQYXCWmJyuTNyV8RzCS46T22FXsQy6Y=; b=npasHf+N3pzXeAT1FHPhdARX5wp+Rb1NCJ+tq047L5XpJixdmePvPyOSK7XSUCLFnJ xF8WtJJ54nKy9G+ILS3MUdAdsLM5X49G7PbdZj8G8FilnMJ5oV5VysPO1Kb4659si/HP DdwPOsiUvP7QEiWLMfdrhoKAllHmdIqaQy1nTp1LHNJR536rQcPBBVa8/nr59aTzLQLd W6cVLnnAAUxjk5IbPT++rzGTu3IWK8B2OLufPBKBJlJpoqvoP20xBHHBTEC2hOT9Bp4k +pbhxFIM5bw8OIoNTIpCMJnVQuygdBez6Z/bc+r2l0E3Z1s64/w2izz4bgTqctm+yCcU XO1g== X-Gm-Message-State: AOAM5301LSWvfV5I3Ho4SDOMIXH0MYxZa91zsz+mZa4lpfImKFebqXjL di1Hy69z169gmX7JwsG5ogE= X-Google-Smtp-Source: ABdhPJxQA6aY+Kb+lsHgUcUCkIWUVDzdCR5Ebsa9jjgvlIyhbPn7LuyGg4CgPI/r0ysJnewrIU4d0A== X-Received: by 2002:a05:6214:15d1:: with SMTP id p17mr8520411qvz.28.1615485008289; Thu, 11 Mar 2021 09:50:08 -0800 (PST) Received: from ?IPv6:2620:10d:c0a8:1102:ad18:ae8d:5ca2:307e? ([2620:10d:c091:480::1:326f]) by smtp.googlemail.com with ESMTPSA id 79sm2512743qki.37.2021.03.11.09.50.07 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 11 Mar 2021 09:50:07 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: c++: template partial instantiation mismatch [PR 99528] Message-ID: Date: Thu, 11 Mar 2021 12:50:06 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-10.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" This turned out to be an existing problem, which had been hidden by other bugs. Templated members of templated classes can end up instantiating the template itself, and we were not handling the mergeableness of that correctly. PR c++/99528 gcc/cp/ * module.cc (enum merge_kind): Delete MK_type_tmpl_spec, MK_decl_tmpl_spec. (trees_in::decl_value): Adjust add_mergeable_specialization call. (trees_out::get_merge_kind): Adjust detecting a partial template instantiation. (trees_out::key_mergeable): Adjust handling same. (trees_in::key_mergeabvle): Likewise. gcc/testsuite/ * g++.dg/modules/pr99528.h: New. * g++.dg/modules/pr99528_a.H: New. * g++.dg/modules/pr99528_b.H: New. * g++.dg/modules/pr99528_c.C: New. diff --git c/gcc/cp/module.cc w/gcc/cp/module.cc index db5fa9076c3..03359db28e1 100644 --- c/gcc/cp/module.cc +++ w/gcc/cp/module.cc @@ -2783,11 +2783,7 @@ enum merge_kind MK_tmpl_tmpl_mask = 0x1, /* We want TEMPLATE_DECL. */ MK_type_spec = MK_template_mask, - MK_type_tmpl_spec = MK_type_spec | MK_tmpl_tmpl_mask, - MK_decl_spec = MK_template_mask | MK_tmpl_decl_mask, - MK_decl_tmpl_spec = MK_decl_spec | MK_tmpl_tmpl_mask, - MK_alias_spec = MK_decl_spec | MK_tmpl_alias_mask, MK_hwm = 0x20 @@ -8062,10 +8058,10 @@ trees_in::decl_value () { /* Add to specialization tables now that constraints etc are added. */ - bool is_decl = (mk & MK_template_mask) && (mk & MK_tmpl_decl_mask); + bool is_type = mk == MK_partial || !(mk & MK_tmpl_decl_mask); - spec.spec = is_decl ? inner : type; - add_mergeable_specialization (is_decl, &spec, decl, spec_flags); + spec.spec = is_type ? type : mk & MK_tmpl_tmpl_mask ? inner : decl; + add_mergeable_specialization (!is_type, &spec, decl, spec_flags); } if (TREE_CODE (decl) == INTEGER_CST && !TREE_OVERFLOW (decl)) @@ -10229,7 +10225,6 @@ trees_out::get_merge_kind (tree decl, depset *dep) case depset::EK_SPECIALIZATION: { gcc_checking_assert (dep->is_special ()); - spec_entry *entry = reinterpret_cast (dep->deps[0]); if (TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL) /* An block-scope classes of templates are themselves @@ -10247,13 +10242,8 @@ trees_out::get_merge_kind (tree decl, depset *dep) if (TREE_CODE (decl) == TEMPLATE_DECL) { - tree res = DECL_TEMPLATE_RESULT (decl); - if (!(mk & MK_tmpl_decl_mask)) - res = TREE_TYPE (res); - - if (res == entry->spec) - /* We check we can get back to the template during - streaming. */ + spec_entry *entry = reinterpret_cast (dep->deps[0]); + if (TREE_CODE (entry->spec) != TEMPLATE_DECL) mk = merge_kind (mk | MK_tmpl_tmpl_mask); } } @@ -10362,15 +10352,14 @@ trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner, gcc_assert (match_mergeable_specialization (false, entry) == TREE_TYPE (existing)); else if (mk & MK_tmpl_tmpl_mask) - if (tree ti = DECL_TEMPLATE_INFO (existing)) - existing = TI_TEMPLATE (ti); + existing = DECL_TI_TEMPLATE (existing); } else { - if (!(mk & MK_tmpl_tmpl_mask)) + if (mk & MK_tmpl_tmpl_mask) + existing = CLASSTYPE_TI_TEMPLATE (existing); + else existing = TYPE_NAME (existing); - else if (tree ti = CLASSTYPE_TEMPLATE_INFO (existing)) - existing = TI_TEMPLATE (ti); } /* The walkabout should have found ourselves. */ @@ -10677,13 +10666,6 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner, DECL_NAME (inner) = DECL_NAME (decl); DECL_CONTEXT (inner) = DECL_CONTEXT (decl); - spec.spec = decl; - if (mk & MK_tmpl_tmpl_mask) - { - if (inner == decl) - return error_mark_node; - spec.spec = inner; - } tree constr = NULL_TREE; bool is_decl = mk & MK_tmpl_decl_mask; if (is_decl) @@ -10694,13 +10676,10 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner, if (constr) set_constraints (inner, constr); } + spec.spec = (mk & MK_tmpl_tmpl_mask) ? inner : decl; } else - { - if (mk == MK_type_spec && inner != decl) - return error_mark_node; - spec.spec = type; - } + spec.spec = type; existing = match_mergeable_specialization (is_decl, &spec); if (constr) /* We'll add these back later, if this is the new decl. */ @@ -10712,24 +10691,15 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner, { /* A declaration specialization. */ if (mk & MK_tmpl_tmpl_mask) - if (tree ti = DECL_TEMPLATE_INFO (existing)) - { - tree tmpl = TI_TEMPLATE (ti); - if (DECL_TEMPLATE_RESULT (tmpl) == existing) - existing = tmpl; - } + existing = DECL_TI_TEMPLATE (existing); } else { /* A type specialization. */ - if (!(mk & MK_tmpl_tmpl_mask)) + if (mk & MK_tmpl_tmpl_mask) + existing = CLASSTYPE_TI_TEMPLATE (existing); + else existing = TYPE_NAME (existing); - else if (tree ti = CLASSTYPE_TEMPLATE_INFO (existing)) - { - tree tmpl = TI_TEMPLATE (ti); - if (DECL_TEMPLATE_RESULT (tmpl) == TYPE_NAME (existing)) - existing = tmpl; - } } } else if (mk == MK_unique) diff --git c/gcc/testsuite/g++.dg/modules/pr99528.h w/gcc/testsuite/g++.dg/modules/pr99528.h new file mode 100644 index 00000000000..ea5d60f489a --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pr99528.h @@ -0,0 +1,9 @@ +template +class new_allocator +{ +public: + template + new_allocator(const new_allocator<_Tp1>&) noexcept { } +}; + +extern template class new_allocator; diff --git c/gcc/testsuite/g++.dg/modules/pr99528_a.H w/gcc/testsuite/g++.dg/modules/pr99528_a.H new file mode 100644 index 00000000000..08f766bd879 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pr99528_a.H @@ -0,0 +1,4 @@ +// PR 99528, ICE with template/function mismatch +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } +#include "pr99528.h" diff --git c/gcc/testsuite/g++.dg/modules/pr99528_b.H w/gcc/testsuite/g++.dg/modules/pr99528_b.H new file mode 100644 index 00000000000..48c4b4d9741 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pr99528_b.H @@ -0,0 +1,4 @@ +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } +#include "pr99528.h" + diff --git c/gcc/testsuite/g++.dg/modules/pr99528_c.C w/gcc/testsuite/g++.dg/modules/pr99528_c.C new file mode 100644 index 00000000000..ca8d8677ce1 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/pr99528_c.C @@ -0,0 +1,3 @@ +// { dg-additional-options {-fmodules-ts -fno-module-lazy} } +import "pr99528_a.H"; +import "pr99528_b.H";