From patchwork Fri Sep 17 16:44:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Barrett Adair X-Patchwork-Id: 45136 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B23183857016 for ; Fri, 17 Sep 2021 16:45:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B23183857016 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1631897106; bh=30Srh7USvVB30y7rnmKaAw2TgtyU5cxX8DuEptu/oC4=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=cT+MQyh9DNo6gyLGsELm30LLvGNrULRmiW/FKij674Xq86B3CLTXAZzlodUItN4qR 0QHShCW0Ft11eaetD7n3vwHQEnulhcZ1FXoDeATMPsHmaBX+wW+5oJISry/CJl+uvu Mbs89HQfxh5W4BeS1hBV967qThGrbSjc2a4RTUrc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qv1-xf35.google.com (mail-qv1-xf35.google.com [IPv6:2607:f8b0:4864:20::f35]) by sourceware.org (Postfix) with ESMTPS id E6DAC3858420 for ; Fri, 17 Sep 2021 16:44:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E6DAC3858420 Received: by mail-qv1-xf35.google.com with SMTP id r18so6786671qvy.8 for ; Fri, 17 Sep 2021 09:44:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=hcxC9vTGHMtoaIK0QB+JC/Z2M17vZEEa7WW7FBkKRsA=; b=oq/ub3UItu/U9X9nEm1/AsAJSdIdHPDUB8sgtiGEUEIWvzsTqPybCnZTLEzq3DiMOw CkGRGsc5I5yPBKhNvKIPBcGCLyqytvRv52qqbg2wyac0yUmCm96mciC1cfsSojoJZuRQ fnn+PBLJp/CWUkb2e95ZU/hy978oel6nH2au8hZUPU1obejrP0hsGg4ucMfMyrXLzJeq 4MGfYNuYmFAPx4HnXw7WfcDlA5vv5k18OXhmOOHmX92G1ZuhmOJmte5px/dLTXkJhYMX zl7s/L1+Dq+4XwaFO6COYlAIwAIIYwXPLouRRYq3f66zA++HbdZtOoZ4LmySJDhtjWTt PBlQ== X-Gm-Message-State: AOAM532MVHRhJnhN23tXBzBmXVL4+Ck+PI1vA3hn+TjCkd6qmeYzq9Xu YwiQhaayjJLdm+X7wSb7jspmUH6blKHihWLYxcNl1UPUNQc= X-Google-Smtp-Source: ABdhPJx7qlqJtVLqhZRW2dDNOaEd9hmDQboH3XR+qvNLHTs/D9SoN6Q7Sr4xjHiNbnmdEhm7ViKWh/Nxn3d5TyCiTB0= X-Received: by 2002:a0c:fca2:: with SMTP id h2mr11955434qvq.5.1631897076376; Fri, 17 Sep 2021 09:44:36 -0700 (PDT) MIME-Version: 1.0 Date: Fri, 17 Sep 2021 11:44:25 -0500 Message-ID: Subject: [PATCH v4] c++: Fix cp_tree_equal for template value args using dependent sizeof/alignof/noexcept expressions To: gcc-patches@gcc.gnu.org, Jason Merrill X-Spam-Status: No, score=-9.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, HTML_MESSAGE, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-Content-Filtered-By: Mailman/MimeDel 2.1.29 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: , X-Patchwork-Original-From: Barrett Adair via Gcc-patches From: Barrett Adair Reply-To: Barrett Adair Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" I think the patch is in good shape now, thanks for the help. canon-type*.C fail with trunk and pass with patch, dependent-name*.C are regression tests that pass with both. I removed the dg-ice from constexpr-52830.C. I didn't dig much into the churn history there, but the test code looks valid to me and clang agrees. I also returned the copyright assignment form yesterday to assign@gnu.org. From 9bea055c84d307ade7095fa2cdf7432b42ee0897 Mon Sep 17 00:00:00 2001 From: Barrett Adair Date: Wed, 15 Sep 2021 15:26:22 -0500 Subject: [PATCH] Fix template instantiation comparison outside function body --- gcc/cp/pt.c | 18 ++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C | 1 - gcc/testsuite/g++.dg/template/canon-type-15.C | 7 +++++++ gcc/testsuite/g++.dg/template/canon-type-16.C | 6 ++++++ gcc/testsuite/g++.dg/template/canon-type-17.C | 5 +++++ gcc/testsuite/g++.dg/template/canon-type-18.C | 6 ++++++ .../g++.dg/template/dependent-name15.C | 18 ++++++++++++++++++ .../g++.dg/template/dependent-name16.C | 14 ++++++++++++++ 8 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/template/canon-type-15.C create mode 100644 gcc/testsuite/g++.dg/template/canon-type-16.C create mode 100644 gcc/testsuite/g++.dg/template/canon-type-17.C create mode 100644 gcc/testsuite/g++.dg/template/canon-type-18.C create mode 100644 gcc/testsuite/g++.dg/template/dependent-name15.C create mode 100644 gcc/testsuite/g++.dg/template/dependent-name16.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 224dd9ebd2b..597422045d3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -27766,6 +27766,19 @@ dependent_template_arg_p (tree arg) return value_dependent_expression_p (arg); } +/* Identify any expressions that use function parms */ +static tree +find_parm_usage_r (tree *tp, int *walk_subtrees, void*) +{ + tree t = *tp; + if (PACK_EXPANSION_P (t) || (TREE_CODE (t) == PARM_DECL)) + { + *walk_subtrees = 0; + return t; + } + return NULL_TREE; +} + /* Returns true if ARGS (a collection of template arguments) contains any types that require structural equality testing. */ @@ -27810,6 +27823,11 @@ any_template_arguments_need_structural_equality_p (tree args) else if (!TYPE_P (arg) && TREE_TYPE (arg) && TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (arg))) return true; + else if (!current_function_decl + && dependent_template_arg_p (arg) + && cp_walk_tree_without_duplicates (&arg, + find_parm_usage_r, NULL)) + return true; } } } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C index eae0d8c377b..d6057f13497 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C @@ -1,7 +1,6 @@ // PR c++/52830 // { dg-do compile { target c++11 } } // { dg-additional-options "-fchecking" } -// { dg-ice "comptypes" } template struct eif { typedef void type; }; template<> struct eif {}; diff --git a/gcc/testsuite/g++.dg/template/canon-type-15.C b/gcc/testsuite/g++.dg/template/canon-type-15.C new file mode 100644 index 00000000000..b001b5c841d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-15.C @@ -0,0 +1,7 @@ +// { dg-do compile { target c++11 } } +template struct size_c{ static constexpr unsigned value = u; }; +namespace g { +template auto return_size(T t) -> size_c; +template auto return_size(T t) -> size_c; +} +static_assert(decltype(g::return_size('a'))::value == 1u, ""); diff --git a/gcc/testsuite/g++.dg/template/canon-type-16.C b/gcc/testsuite/g++.dg/template/canon-type-16.C new file mode 100644 index 00000000000..99361cbac30 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-16.C @@ -0,0 +1,6 @@ +// { dg-do compile { target c++11 } } +template struct bool_c{ static constexpr bool value = u; }; +template auto noexcepty(T t) -> bool_c; +template auto noexcepty(T t) -> bool_c; +struct foo { void operator()() noexcept; }; +static_assert(decltype(noexcepty(foo{}))::value, ""); diff --git a/gcc/testsuite/g++.dg/template/canon-type-17.C b/gcc/testsuite/g++.dg/template/canon-type-17.C new file mode 100644 index 00000000000..0555c8d0a42 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-17.C @@ -0,0 +1,5 @@ +// { dg-do compile { target c++11 } } +template struct size_c{ static constexpr unsigned value = u; }; +template auto return_size(T... t) -> size_c; +template auto return_size(T... t) -> size_c; +static_assert(decltype(return_size('a'))::value == 1u, ""); diff --git a/gcc/testsuite/g++.dg/template/canon-type-18.C b/gcc/testsuite/g++.dg/template/canon-type-18.C new file mode 100644 index 00000000000..2510181725c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-18.C @@ -0,0 +1,6 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-Wno-pedantic" } +template struct size_c{ static constexpr unsigned value = u; }; +template auto get_align(T t) -> size_c; +template auto get_align(T t) -> size_c; +static_assert(decltype(get_align('a'))::value == 1u, ""); diff --git a/gcc/testsuite/g++.dg/template/dependent-name15.C b/gcc/testsuite/g++.dg/template/dependent-name15.C new file mode 100644 index 00000000000..1c34bc704f9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-name15.C @@ -0,0 +1,18 @@ +// { dg-do compile { target c++11 } } +template struct A { static void foo(){} }; +template <> struct A { using foo = int; }; + +template void f(T t1) { + A::foo(); +} + +template void g(T t2) { + /* if the comparing_specializations check breaks in cp_tree_equal + case PARM_DECL, the error will incorrectly report A */ + A::foo(); // { dg-error "dependent-name .A::foo" } +} + +void h() { + f(0); + g('0'); +} diff --git a/gcc/testsuite/g++.dg/template/dependent-name16.C b/gcc/testsuite/g++.dg/template/dependent-name16.C new file mode 100644 index 00000000000..ef8c4f23077 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-name16.C @@ -0,0 +1,14 @@ +// { dg-do compile { target c++11 } } +template struct A { static void foo(){} }; +template <> struct A { using foo = int; }; + +template auto f(T1 t1) -> decltype(A::foo()); + +/* if the comparing_specializations check breaks in cp_tree_equal +case PARM_DECL, the error will incorrectly report A */ +template auto g(T2 t2) -> decltype(A::foo()); // { dg-error "dependent-name .A::foo" } + +void h() { + f(0); + g('0'); // { dg-error "no matching function" } +} -- 2.30.2