From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id BCC26385DC35 for ; Fri, 28 Jan 2022 03:21:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BCC26385DC35 Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-493-F1ofzqnpMRuM6Nv0g_p4pQ-1; Thu, 27 Jan 2022 22:21:33 -0500 X-MC-Unique: F1ofzqnpMRuM6Nv0g_p4pQ-1 Received: by mail-qk1-f198.google.com with SMTP id p20-20020a05620a22b400b0047ecab0db4fso3944889qkh.2 for ; Thu, 27 Jan 2022 19:21:33 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=1dEapfQdc6kqE5Ujo72pF5mzuOA/qZMKEZlI/zFlyos=; b=u+0RMI+g6q0WF8PDhnxREzSufZ4iKLQN3R3XNlwltyZruVNsypDRgwHCEafP0CJFMb vtMyTKvxv9bxPGQNHanHXi/cuNtKsprIGHJthCcPeOFmp6TTQe0x6QuYvcGqLtlu+w6w WX7O2Lm/F2fREWoFEMbjh0iervDVkTzzwxloTpOdTiEQPFNaBscKrgfk/FE63ffsyZBl Y2VVg2zLwNu/xL6YFeeitjWoVTUCUwrkahQz2s88ugPhZU6cwbhSonXCxdK0SHDOAIQK 3FrdSxJ5adBKLFXj7ReSgAUPYk7DK99ysyO0rzI9JEIUKDqvzW81f8WsOE9tOSNxH2YU peZg== X-Gm-Message-State: AOAM5305Md2bMnr+4vfD4Ifq0F1IejP2NC2mRKa30HR0SbxFWSVcH1f7 NPi9EcXnOJLP5v1nFgD9MCdlegHTZZfFfoIYoeLC4fJhc9VmqIIKo3ERq8+AgKcrLmY49Jn5oRq zqqjkC+WrWv3pinz4IRalLkQ/Hs2nqCY21lrQVv027v+qipFWv2i7WVdH55nJnEj2sg== X-Received: by 2002:a05:620a:2891:: with SMTP id j17mr4660718qkp.350.1643340092139; Thu, 27 Jan 2022 19:21:32 -0800 (PST) X-Google-Smtp-Source: ABdhPJzrjwTxDb3ImKgxXMK/Myg2AWhkLxRjxDc8NXugoJSBxr4xoP7vubovLvmtn7UIVP1xcjt8TA== X-Received: by 2002:a05:620a:2891:: with SMTP id j17mr4660706qkp.350.1643340091674; Thu, 27 Jan 2022 19:21:31 -0800 (PST) Received: from barrymore.redhat.com (130-44-159-43.s15913.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.159.43]) by smtp.gmail.com with ESMTPSA id a8sm2167721qti.71.2022.01.27.19.21.30 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Jan 2022 19:21:30 -0800 (PST) From: Jason Merrill To: gcc-patches@gcc.gnu.org Subject: [pushed] c++: pack in enumerator in lambda [PR100198] Date: Thu, 27 Jan 2022 22:21:28 -0500 Message-Id: <20220128032128.1399214-1-jason@redhat.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" X-Spam-Status: No, score=-13.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, 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-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-List-Received-Date: Fri, 28 Jan 2022 03:21:38 -0000 The GCC 8 lambda overhaul fixed most uses of lambdas in pack expansions, but local enums and classes within such lambdas that depend on parameter packs are still broken. For now, give a sorry instead of an ICE or incorrect error. Tested x86_64-pc-linux-gnu, applying to trunk. PR c++/100198 PR c++/100030 PR c++/100282 gcc/cp/ChangeLog: * parser.cc (cp_parser_enumerator_definition): Sorry on parameter pack in lambda. (cp_parser_class_head): And in class attributes. * pt.cc (check_for_bare_parameter_packs): Sorry instead of error in lambda. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/lambda/lambda-variadic13.C: Accept the sorry as well as the correct error. * g++.dg/cpp0x/lambda/lambda-variadic14.C: Likewise. * g++.dg/cpp0x/lambda/lambda-variadic14a.C: New test. * g++.dg/cpp0x/lambda/lambda-variadic15.C: New test. * g++.dg/cpp0x/lambda/lambda-variadic16.C: New test. --- gcc/cp/parser.cc | 19 ++++++++++++++- gcc/cp/pt.cc | 23 +++++++++++++++---- .../g++.dg/cpp0x/lambda/lambda-variadic13.C | 2 +- .../g++.dg/cpp0x/lambda/lambda-variadic14.C | 2 +- .../g++.dg/cpp0x/lambda/lambda-variadic14a.C | 9 ++++++++ .../g++.dg/cpp0x/lambda/lambda-variadic15.C | 14 +++++++++++ .../g++.dg/cpp0x/lambda/lambda-variadic16.C | 13 +++++++++++ 7 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14a.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic15.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic16.C diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index f1947ee3a1c..94a5c64be4c 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -21146,7 +21146,16 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type) /* If we are processing a template, make sure the initializer of the enumerator doesn't contain any bare template parameter pack. */ - if (check_for_bare_parameter_packs (value)) + if (current_lambda_expr ()) + { + /* In a lambda it should work, but doesn't currently. */ + if (uses_parameter_packs (value)) + { + sorry ("unexpanded parameter pack in enumerator in lambda"); + value = error_mark_node; + } + } + else if (check_for_bare_parameter_packs (value)) value = error_mark_node; /* Create the enumerator. */ @@ -26624,6 +26633,14 @@ cp_parser_class_head (cp_parser* parser, if (type) { + if (current_lambda_expr () + && uses_parameter_packs (attributes)) + { + /* In a lambda this should work, but doesn't currently. */ + sorry ("unexpanded parameter pack in local class in lambda"); + attributes = NULL_TREE; + } + /* Apply attributes now, before any use of the class as a template argument in its base list. */ cplus_decl_attributes (&type, attributes, (int)ATTR_FLAG_TYPE_IN_PLACE); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 19e73b3b77d..f46a7ad6655 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -4273,10 +4273,27 @@ check_for_bare_parameter_packs (tree t, location_t loc /* = UNKNOWN_LOCATION */) cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited); delete ppd.visited; + if (!parameter_packs) + return false; + + if (loc == UNKNOWN_LOCATION) + loc = cp_expr_loc_or_input_loc (t); + /* It's OK for a lambda to have an unexpanded parameter pack from the containing context, but do complain about unexpanded capture packs. */ - if (current_class_type && LAMBDA_TYPE_P (current_class_type) - && CLASSTYPE_TEMPLATE_INFO (current_class_type)) + tree lam = current_lambda_expr (); + if (lam) + lam = TREE_TYPE (lam); + + if (lam && lam != current_class_type) + { + /* We're in a lambda, but it isn't the innermost class. + This should work, but currently doesn't. */ + sorry_at (loc, "unexpanded parameter pack in local class in lambda"); + return true; + } + + if (lam && CLASSTYPE_TEMPLATE_INFO (lam)) for (; parameter_packs; parameter_packs = TREE_CHAIN (parameter_packs)) { @@ -4287,8 +4304,6 @@ check_for_bare_parameter_packs (tree t, location_t loc /* = UNKNOWN_LOCATION */) if (parameter_packs) { - if (loc == UNKNOWN_LOCATION) - loc = cp_expr_loc_or_input_loc (t); error_at (loc, "parameter packs not expanded with %<...%>:"); while (parameter_packs) { diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic13.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic13.C index ac4e631ebb5..3df88296726 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic13.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic13.C @@ -3,7 +3,7 @@ template void f() { - [] { struct S : Ts { }; }; // { dg-error "not expanded" } + [] { struct S : Ts { }; }; // { dg-message "" } } int main() { diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14.C index 185aa0332e7..4634f16ccb0 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14.C @@ -3,6 +3,6 @@ template void f() { - [] { enum e { e = E }; }; // { dg-error "not expanded" } + [] { enum e { e = E }; }; // { dg-message "" } } template void f<>(); diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14a.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14a.C new file mode 100644 index 00000000000..810b4a4e045 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic14a.C @@ -0,0 +1,9 @@ +// PR c++/100198 +// { dg-do compile { target c++11 } } + +template +void f() { + ([] { enum e { e = E }; }(), ...); // { dg-bogus "" "" { xfail *-*-* } } +} + +template void f<0>(); diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic15.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic15.C new file mode 100644 index 00000000000..730215a7a41 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic15.C @@ -0,0 +1,14 @@ +// PR c++/100030 +// { dg-do compile { target c++11 } } + +template +void sink(Ts...); + +template +void f(Ts...) { + sink([] { struct alignas(Ts) S {}; }...); // { dg-bogus "" "" { xfail *-*-* } } +} + +int main() { + f(0); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic16.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic16.C new file mode 100644 index 00000000000..8e48e38a345 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic16.C @@ -0,0 +1,13 @@ +// PR c++/100282 +// { dg-do compile { target c++11 } } + +template +void +local_class () +{ + int { []{ struct ZZ : Ts {}; }... }; // { dg-bogus "" "" { xfail *-*-* } } +} + +template // <> +void +local_class (); base-commit: 66b86171188dcb61d2d0e0a4a98a7467e58a84a7 -- 2.27.0