From patchwork Tue Nov 29 12:32:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 61220 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 D4E783852C48 for ; Tue, 29 Nov 2022 12:32:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D4E783852C48 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1669725177; bh=H9rL3wWVTmJm2kazCp8n7yj3FjJGc1VgGpnRi82WfaM=; h=Date:To:Cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=wiVAzZe5AB6aM+UTzc9j0us0vuEQyHsSXNh5igjUNlyb4XFT7M9C56diSCOz8rdzI 4LDmBSV/acGkkrZkOvYorQCkhxftD2Tu6rcygsDTKcXoXmVxtAGTXmB639R3ptB/OY Jj5EmjULGXZFm6dCdWYh9hEcHCiUtTAIZyw4zwgo= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 4B5EC3858407 for ; Tue, 29 Nov 2022 12:32:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4B5EC3858407 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-210-PWMgdLPPNeajZbYRPbdvUg-1; Tue, 29 Nov 2022 07:32:24 -0500 X-MC-Unique: PWMgdLPPNeajZbYRPbdvUg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4DEC7833AFB for ; Tue, 29 Nov 2022 12:32:24 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.195.114]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0FFB4112131E; Tue, 29 Nov 2022 12:32:23 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 2ATCWJ5O4185428 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 29 Nov 2022 13:32:19 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 2ATCWJQJ4185427; Tue, 29 Nov 2022 13:32:19 +0100 Date: Tue, 29 Nov 2022 13:32:18 +0100 To: gcc-patches@gcc.gnu.org Cc: Jason Merrill Subject: [PATCH] c++: Incremental fix for g++.dg/gomp/for-21.C [PR84469] Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi! The PR84469 patch I've just posted regresses the for-21.C testcase, when in OpenMP loop there are at least 2 associated loops and in a template outer structured binding with non type dependent expression is used in the expressions of some inner loop, we don't diagnose those any longer, as the (weirdly worded) diagnostics was only done during finish_id_expression -> mark_used which for the inner loop expressions happens before the structured bindings are finalized. When in templates, mark_used doesn't diagnose uses of non-deduced variables, and if the range for expression is type dependent, it is similarly diagnosed during instantiation. But newly with the PR84469 fix if the range for expression is not type dependent, there is no place that would diagnose it, as during instantiation the structured bindings are already deduced. The following patch diagnoses it in that case during finish_omp_for (for consistency with the same weird message). I'll commit this to trunk if the other patch is approved and it passes bootstrap/regtest. 2022-11-29 Jakub Jelinek PR c++/84469 * semantics.cc: Define INCLUDE_MEMORY before including system.h. (struct finish_omp_for_data): New type. (finish_omp_for_decomps_r): New function. (finish_omp_for): Diagnose uses of non-type-dependent range for loop decompositions in inner OpenMP associated loops in templates. * g++.dg/gomp/for-21.C (f6): Adjust lines of expected diagnostics. * g++.dg/gomp/for-22.C: New test. Jakub --- gcc/cp/semantics.cc.jj 2022-11-19 09:21:14.897436616 +0100 +++ gcc/cp/semantics.cc 2022-11-29 12:58:36.165771985 +0100 @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. . */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "target.h" @@ -10401,6 +10402,47 @@ handle_omp_for_class_iterator (int i, lo return false; } +struct finish_omp_for_data { + std::unique_ptr> decomps; + bool fail; + location_t loc; +}; + +/* Helper function for finish_omp_for. Diagnose uses of structured + bindings of OpenMP collapsed loop range for loops in the associated + loops. If not processing_template_decl, this is diagnosed by + finish_id_expression -> mark_used before the range for is deduced. + And if processing_template_decl and the range for expression is + type dependent, it is similarly diagnosed during instantiation. + Only when processing_template_decl and range for expression is + not type dependent, we wouldn't diagnose it at all, so do it + from finish_omp_for in that case. */ + +static tree +finish_omp_for_decomps_r (tree *tp, int *, void *d) +{ + if (VAR_P (*tp) + && DECL_DECOMPOSITION_P (*tp) + && !type_dependent_expression_p (*tp) + && DECL_HAS_VALUE_EXPR_P (*tp)) + { + tree v = DECL_VALUE_EXPR (*tp); + if (TREE_CODE (v) == ARRAY_REF + && VAR_P (TREE_OPERAND (v, 0)) + && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0))) + { + finish_omp_for_data *data = (finish_omp_for_data *) d; + if (data->decomps->contains (TREE_OPERAND (v, 0))) + { + error_at (data->loc, "use of %qD before deduction of %", + *tp); + data->fail = true; + } + } + } + return NULL_TREE; +} + /* Build and validate an OMP_FOR statement. CLAUSES, BODY, COND, INCR are directly for their associated operands in the statement. DECL and INIT are a combo; if DECL is NULL then INIT ought to be a @@ -10419,6 +10461,7 @@ finish_omp_for (location_t locus, enum t int i; int collapse = 1; int ordered = 0; + finish_omp_for_data data; gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv)); gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv)); @@ -10479,7 +10522,25 @@ finish_omp_for (location_t locus, enum t elocus = EXPR_LOCATION (init); if (cond == global_namespace) - continue; + { + gcc_assert (processing_template_decl); + if (TREE_VEC_LENGTH (declv) > 1 + && VAR_P (decl) + && DECL_DECOMPOSITION_P (decl) + && !type_dependent_expression_p (decl)) + { + gcc_assert (DECL_HAS_VALUE_EXPR_P (decl)); + tree v = DECL_VALUE_EXPR (decl); + gcc_assert (TREE_CODE (v) == ARRAY_REF + && VAR_P (TREE_OPERAND (v, 0)) + && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0))); + if (!data.decomps) + data.decomps + = std::unique_ptr> (new hash_set); + data.decomps->add (TREE_OPERAND (v, 0)); + } + continue; + } if (cond == NULL) { @@ -10497,6 +10558,37 @@ finish_omp_for (location_t locus, enum t TREE_VEC_ELT (initv, i) = init; } + if (data.decomps) + { + data.fail = false; + data.loc = locus; + hash_set pset; + for (i = 0; i < TREE_VEC_LENGTH (declv); i++) + { + init = TREE_VEC_ELT (initv, i); + cond = TREE_VEC_ELT (condv, i); + incr = TREE_VEC_ELT (incrv, i); + data.loc = EXPR_LOC_OR_LOC (init, locus); + cp_walk_tree (&init, finish_omp_for_decomps_r, &data, &pset); + data.loc = EXPR_LOC_OR_LOC (cond, locus); + cp_walk_tree (&cond, finish_omp_for_decomps_r, &data, &pset); + data.loc = EXPR_LOC_OR_LOC (incr, locus); + cp_walk_tree (&incr, finish_omp_for_decomps_r, &data, &pset); + } + if (orig_inits && !data.fail) + { + tree orig_init; + FOR_EACH_VEC_ELT (*orig_inits, i, orig_init) + { + data.loc = EXPR_LOC_OR_LOC (orig_init, locus); + cp_walk_tree (&orig_init, finish_omp_for_decomps_r, + &data, &pset); + } + } + if (data.fail) + return NULL; + } + if (orig_inits) { bool fail = false; --- gcc/testsuite/g++.dg/gomp/for-21.C.jj 2020-01-12 11:54:37.178401867 +0100 +++ gcc/testsuite/g++.dg/gomp/for-21.C 2022-11-29 13:06:59.038410557 +0100 @@ -54,9 +54,9 @@ void f6 (S (&a)[10]) { #pragma omp for collapse (2) - for (auto [i, j, k] : a) // { dg-error "use of 'i' before deduction of 'auto'" "" { target *-*-* } .-1 } + for (auto [i, j, k] : a) // { dg-error "use of 'i' before deduction of 'auto'" } for (int l = i; l < j; l += k) // { dg-error "use of 'j' before deduction of 'auto'" } - ; // { dg-error "use of 'k' before deduction of 'auto'" "" { target *-*-* } .-3 } + ; // { dg-error "use of 'k' before deduction of 'auto'" "" { target *-*-* } .-1 } } template --- gcc/testsuite/g++.dg/gomp/for-22.C.jj 2022-11-29 13:07:10.859237506 +0100 +++ gcc/testsuite/g++.dg/gomp/for-22.C 2022-11-29 13:09:50.743897003 +0100 @@ -0,0 +1,57 @@ +// { dg-do compile { target c++17 } } + +namespace std { + template struct tuple_size; + template struct tuple_element; +} + +struct A { + int i; + template int& get() { return i; } +}; + +template<> struct std::tuple_size { static const int value = 3; }; +template struct std::tuple_element { using type = int; }; + +struct B { + A *begin(); + A *end(); +}; + +void +f1 (B a) +{ + #pragma omp for collapse (2) + for (auto [i, j, k] : a) // { dg-error "use of 'i' before deduction of 'auto'" "" { target *-*-* } .+1 } + for (int l = i; l < j; l += k) // { dg-error "use of 'j' before deduction of 'auto'" } + ; // { dg-error "use of 'k' before deduction of 'auto'" "" { target *-*-* } .-1 } +} + +template +void +f2 (B a) +{ + #pragma omp for collapse (2) + for (auto [i, j, k] : a) // { dg-error "use of 'i' before deduction of 'auto'" "" { target *-*-* } .+1 } + for (int l = i; l < j; l += k) // { dg-error "use of 'j' before deduction of 'auto'" } + ; // { dg-error "use of 'k' before deduction of 'auto'" "" { target *-*-* } .-1 } +} + +template +void +f3 (T a) +{ + #pragma omp for collapse (2) + for (auto [i, j, k] : a) // { dg-error "use of 'i' before deduction of 'auto'" "" { target *-*-* } .-1 } + for (int l = i; l < j; l += k) // { dg-error "use of 'j' before deduction of 'auto'" } + ; // { dg-error "use of 'k' before deduction of 'auto'" "" { target *-*-* } .-3 } +} + +void +test () +{ + B b; + f1 (b); + f2 <0> (b); + f3 (b); +}