From patchwork Mon Dec 7 16:44:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1412134 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=2620:52:3:1:0:246e:9693:128c; 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=HMm5k08g; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (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 4CqTfv1166z9sW0 for ; Tue, 8 Dec 2020 03:44:21 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0238A3950CB9; Mon, 7 Dec 2020 16:44:18 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qk1-x734.google.com (mail-qk1-x734.google.com [IPv6:2607:f8b0:4864:20::734]) by sourceware.org (Postfix) with ESMTPS id 0DF6D3950C6D for ; Mon, 7 Dec 2020 16:44:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 0DF6D3950C6D 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-x734.google.com with SMTP id q22so13085152qkq.6 for ; Mon, 07 Dec 2020 08:44:14 -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=OYmPUhBvraLai1oy+rYu/tRO6w6g+7dpRmEhEX2YYJU=; b=HMm5k08gXUuRBGpKeK7guc44Zu4EERCrdW8hEQ6rafZRxezUXZhYPO0Ev13SSIlOLM +7e0J+JnY5+hAXxshPgN1PJkhb3Y2q8H4rmU+V0wj4naHBGr3FyP09aogPwsWNKgeJ8Y AMTkenmUWaQQ+x4RXZLM6BPXHWMlCXebJgv/tWYhkr6qLoAgpolPpOs3hGU0/TIIsyle xQ2xmjf6SezopqF6S9j7FWvib+jNFY+FHhBIfch0NYqgUARq7ga3i/p97/QT36UeZWOs 8uV8XLnZbHos3nRfddVzBnk6XRhNOy2Cu+tw4kUScQwqyBjdc2V3LnoA+GOZ75nUGwX1 ddKA== 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=OYmPUhBvraLai1oy+rYu/tRO6w6g+7dpRmEhEX2YYJU=; b=dbKUW8SNBAaiNqAJlqtIgte+Ih+JTo/45jDCL6n37+Tt7z1MZlneitgmQ+81hUajdR Ubsywp5iwt9UhVh22SZzs0lbXMTTEaGoBDa3Z2A+QUT2k2sBYTLbRk6n58GCzwhapw0+ UEGxqwkbuLMEX0hsobLX6IMuq211ruPsmqKFhM3d4rWGtOJZI11TgiyPq/ChwUv0r+6F pcwJx3SGHOfEGsF+4pfPpsV6w2+IntTN0wRgkiwciO0/Kqejzw2TrhQRPSpP0Q0a/knr PHpyadRTxXoYn/sjJe8Y4hHgh7JOdxvODarBBpkfc6/qNglvLaqTAymwWVtirZEjT4ln FvBA== X-Gm-Message-State: AOAM530VkCkFlUkEkmGHhTe2ofAuJ5tX9NiK+SG26nMHJiowudJy1/1B yB07n7cQlwlY9i+mmvV6sTg= X-Google-Smtp-Source: ABdhPJxXWQKM05tNdxC9z/xTxQl3JjqpA29CYBPNLxhHon5P2e4PZd83NZDoqnXAbYNSbpOLy7czYA== X-Received: by 2002:a37:b5c6:: with SMTP id e189mr6602032qkf.483.1607359453058; Mon, 07 Dec 2020 08:44:13 -0800 (PST) Received: from ?IPv6:2620:10d:c0a8:1102:9dac:8e60:ec40:b071? ([2620:10d:c091:480::1:cf7d]) by smtp.googlemail.com with ESMTPSA id q32sm2457255qtb.0.2020.12.07.08.44.11 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 07 Dec 2020 08:44:11 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: c++: check alias match for specializations [PR98116] Message-ID: <9e21f5f8-83b5-4b90-d04c-ec5232e19ca3@acm.org> Date: Mon, 7 Dec 2020 11:44:10 -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=-11.4 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 fixes the underlying problem my recent (backedout) changes to array type creation uncovered. We had paths through structural_comptypes that ignored alias templates, even when significant. This adds the necessary checks. PR c++/98116 gcc/cp/ * typeck.c (structural_comptypes): Move early outs to comptype. Always check template-alias match when comparing_specializations. (comptypes): Do early out checking here. gcc/testsuite/ * g++.dg/template/pr98116.C: Remove dg-ice. * g++.dg/template/pr98116-2.C: New. pushing to trunk diff --git c/gcc/cp/typeck.c w/gcc/cp/typeck.c index 267b284ea40..4d499af5ccb 100644 --- c/gcc/cp/typeck.c +++ w/gcc/cp/typeck.c @@ -1247,14 +1247,8 @@ cxx_safe_function_type_cast_p (tree t1, tree t2) static bool structural_comptypes (tree t1, tree t2, int strict) { - if (t1 == t2) - return true; - - /* Suppress errors caused by previously reported errors. */ - if (t1 == error_mark_node || t2 == error_mark_node) - return false; - - gcc_assert (TYPE_P (t1) && TYPE_P (t2)); + /* Both should be types that are not obviously the same. */ + gcc_checking_assert (t1 != t2 && TYPE_P (t1) && TYPE_P (t2)); if (!comparing_specializations) { @@ -1300,13 +1294,13 @@ structural_comptypes (tree t1, tree t2, int strict) /* Allow for two different type nodes which have essentially the same definition. Note that we already checked for equality of the type qualifiers (just above). */ - if (TREE_CODE (t1) != ARRAY_TYPE && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) - return true; - + goto check_alias; - /* Compare the types. Break out if they could be the same. */ + /* Compare the types. Return false on known not-same. Break on not + known. Never return true from this switch -- you'll break + specialization comparison. */ switch (TREE_CODE (t1)) { case VOID_TYPE: @@ -1332,7 +1326,11 @@ structural_comptypes (tree t1, tree t2, int strict) have identical properties, different TYPE_MAIN_VARIANTs, but represent the same type. The canonical type system keeps track of equivalence in this case, so we fall back on it. */ - return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2); + if (TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2)) + return false; + + /* We don't need or want the attribute comparison. */ + goto check_alias; case TEMPLATE_TEMPLATE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM: @@ -1477,24 +1475,28 @@ structural_comptypes (tree t1, tree t2, int strict) return false; } - /* Don't treat an alias template specialization with dependent - arguments as equivalent to its underlying type when used as a - template argument; we need them to be distinct so that we - substitute into the specialization arguments at instantiation - time. And aliases can't be equivalent without being ==, so - we don't need to look any deeper. */ + /* If we get here, we know that from a target independent POV the + types are the same. Make sure the target attributes are also + the same. */ + if (!comp_type_attributes (t1, t2)) + return false; + + check_alias: if (comparing_specializations) { + /* Don't treat an alias template specialization with dependent + arguments as equivalent to its underlying type when used as a + template argument; we need them to be distinct so that we + substitute into the specialization arguments at instantiation + time. And aliases can't be equivalent without being ==, so + we don't need to look any deeper. */ tree dep1 = dependent_alias_template_spec_p (t1, nt_transparent); tree dep2 = dependent_alias_template_spec_p (t2, nt_transparent); if ((dep1 || dep2) && dep1 != dep2) return false; } - /* If we get here, we know that from a target independent POV the - types are the same. Make sure the target attributes are also - the same. */ - return comp_type_attributes (t1, t2); + return true; } /* Return true if T1 and T2 are related as allowed by STRICT. STRICT @@ -1509,6 +1511,13 @@ comptypes (tree t1, tree t2, int strict) gcc_checking_assert (TREE_CODE (t1) != TYPE_ARGUMENT_PACK && TREE_CODE (t2) != TYPE_ARGUMENT_PACK); + if (t1 == t2) + return true; + + /* Suppress errors caused by previously reported errors. */ + if (t1 == error_mark_node || t2 == error_mark_node) + return false; + if (strict == COMPARE_STRICT && comparing_specializations && (t1 != TYPE_CANONICAL (t1) || t2 != TYPE_CANONICAL (t2))) /* If comparing_specializations, treat dependent aliases as distinct. */ @@ -1516,12 +1525,6 @@ comptypes (tree t1, tree t2, int strict) if (strict == COMPARE_STRICT) { - if (t1 == t2) - return true; - - if (t1 == error_mark_node || t2 == error_mark_node) - return false; - if (TYPE_STRUCTURAL_EQUALITY_P (t1) || TYPE_STRUCTURAL_EQUALITY_P (t2)) /* At least one of the types requires structural equality, so perform a deep check. */ diff --git c/gcc/testsuite/g++.dg/template/pr98116-2.C w/gcc/testsuite/g++.dg/template/pr98116-2.C new file mode 100644 index 00000000000..fd12bb19be0 --- /dev/null +++ w/gcc/testsuite/g++.dg/template/pr98116-2.C @@ -0,0 +1,34 @@ +// PR 98116, ICE with stripping typedef array type +// { dg-do compile { target c++11 } } +// { dg-additional-options {--param=hash-table-verification-limit=10000000 -fchecking=2} } + +// We got confused by alias templates that alias the same type. Their +// hashes were different (good), but they compared equal (bad) + +namespace std { +typedef int is_convertible; +template using remove_pointer_t = typename _Tp ::type; +template struct enable_if; +template void declval(); +template using enable_if_t = typename enable_if<_Cond>::type; +template class Trans_NS___cxx11_basic_string { + long _M_string_length; +}; +} // namespace std +struct string16_char_traits; +template class std::Trans_NS___cxx11_basic_string; +template using IsLegalDataConversion = std::is_convertible; +template +using ContainerHasConvertibleData = IsLegalDataConversion< + std::remove_pointer_t)>, T>; +template +using EnableIfSpanCompatibleArray = + std::enable_if_t)>; +template class span { + template [N], + std::Trans_NS___cxx11_basic_string, Extent>> + span(); +}; diff --git c/gcc/testsuite/g++.dg/template/pr98116.C w/gcc/testsuite/g++.dg/template/pr98116.C index 874c590f9d2..7d54314b26b 100644 --- c/gcc/testsuite/g++.dg/template/pr98116.C +++ w/gcc/testsuite/g++.dg/template/pr98116.C @@ -1,10 +1,9 @@ // PR 98116, ICE with stripping typedef array type // { dg-do compile { target c++11 } } // { dg-additional-options {--param=hash-table-verification-limit=10000000 -fchecking=2} } -// { dg-ice "spec_hasher::equal" } -// We get confused by alias templates that alias the same type. -// { dg-prune-output "hash table checking failed" } +// We got confused by alias templates that alias the same type. Their +// hashes were different (good), but they compared equal (bad) namespace std { struct is_convertible;