From patchwork Mon Oct 16 15:10:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 1849407 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=WpKf0Wcz; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4S8LD308jfz20Zj for ; Tue, 17 Oct 2023 02:11:14 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id F2F953856951 for ; Mon, 16 Oct 2023 15:11:12 +0000 (GMT) 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.129.124]) by sourceware.org (Postfix) with ESMTPS id 3146A38582BD for ; Mon, 16 Oct 2023 15:10:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3146A38582BD Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3146A38582BD Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697469060; cv=none; b=iCAc6Yz1QiuiemJtTwsR1qIf2+fjuhD2TY/hR7PlR1/SpHNy9lQ4D8geEdwp3TOYPS52zgu3C/tbezGpcldylzD1gKvmH1iV/X/f9DPfNDlM+EIGU9NyA3hsvecYa2Ml/od1AYlaSnPLhrA6WkE11RSz8rUaCIDNjrUd4XFESnA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697469060; c=relaxed/simple; bh=yzetSkmhvMez2GOvF90UAdyphvxjxavJuefAa2AvGww=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=aKXENRULgb/c5efZ3PiNWocc4Dk1xJ3uRysFU4+SeufipCGyGkeo+J4F8OUsqE4FmLFWCrxW80jKkHyeCQzbDQrDa2aUT2NPndAEyUKLQZa83WViS9KF1beD2a+MIxTLCogyKfVKO5vM0P1lvKe6M3G+rEd+spheEsH6j9t1XQ0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1697469057; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=mt5G7A2pOxncGjZ+obVSyB4pAtc3JkNC9QbxDg0Nxs0=; b=WpKf0Wcz8yOTVtGrhTV72MgFuVzwfHNPGctpJzUetgaF5L6kz3sWez6PQKAl6LOxoOVoYZ xtX0wmZwUPKNLTKlcgdmGOnjAUodqFmGvEHVwKsFQbIYfknwpc6MLzURCNoVUT2cwaiMZA sdF5CJMNtay7jHcWijfES0vTXuC66CY= Received: from mail-yw1-f200.google.com (mail-yw1-f200.google.com [209.85.128.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-679-WmcIixELMkmleBuvSF4gDw-1; Mon, 16 Oct 2023 11:10:54 -0400 X-MC-Unique: WmcIixELMkmleBuvSF4gDw-1 Received: by mail-yw1-f200.google.com with SMTP id 00721157ae682-5a7b3ae01c0so69717357b3.3 for ; Mon, 16 Oct 2023 08:10:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697469051; x=1698073851; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=mt5G7A2pOxncGjZ+obVSyB4pAtc3JkNC9QbxDg0Nxs0=; b=Z6BoUX3AJCYwE1jzhQdBMsI+hSDEcrNNyyEf6TbrfLCnRAtUBEbd75vcfIotMlDpoK J5RAcVkXBaHwozYKckL14aMgxqgGSHBMMXgHFI9zff9AqAeGWjlzs1Gc8TRd4cSmbHL3 rLsDbAd5d4tIpQL9AOUKBpyWVysmcYn80fGtPe+JG+JRynDJKHTFQdrgTTZ2OI0KJaEP Ik7u8/NLNIlYaky7A0hiFpwbpefwloqaw0eTzNcRgYvGeBP3yh367mFVZWpumQurG1xe 28GExdpHqnBoyLGS6XKBiGQdljNKMElANlaTeYgEHDWfbS71rIJIwR4CuXLkx3cHI8dQ wWVg== X-Gm-Message-State: AOJu0Yzibh300/p1WNIZVMM2Fsv/2Mrb2+u1N7fTahQ5SSrz8R3dsKKV 4VuLyUGIzkHRqQBBNl5rLRfOMt8XeiCEav0VMMa+RwBI39Vl+J94z+fTPfPFw7cHHv+Y3WnrKPn 3WYMVxIh6XCJ2p5sE5z3irPkxtJfX9ct/kalE67mExn9pNyhoxIUmviYLYNwIvcyWnXrGbZi4RA == X-Received: by 2002:a0d:ea4a:0:b0:5a7:bff2:12fd with SMTP id t71-20020a0dea4a000000b005a7bff212fdmr21057341ywe.10.1697469051342; Mon, 16 Oct 2023 08:10:51 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHxWjErNUvA4d0Arn1wO0H7A/va6ZNC7NIBmINPEF/7D+feUA8E/zenke2v6Cuq3F/7igd1qQ== X-Received: by 2002:a0d:ea4a:0:b0:5a7:bff2:12fd with SMTP id t71-20020a0dea4a000000b005a7bff212fdmr21057316ywe.10.1697469050845; Mon, 16 Oct 2023 08:10:50 -0700 (PDT) Received: from jason.cygnus.csb (130-44-146-16.s12558.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.146.16]) by smtp.gmail.com with ESMTPSA id cz16-20020a056214089000b0065b0554ae78sm3441932qvb.100.2023.10.16.08.10.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Oct 2023 08:10:50 -0700 (PDT) From: Jason Merrill To: gcc-patches@gcc.gnu.org Subject: [pushed] c++: improve fold-expr location Date: Mon, 16 Oct 2023 11:10:48 -0400 Message-Id: <20231016151048.1238073-1-jason@redhat.com> X-Mailer: git-send-email 2.39.3 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.5 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_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Tested x86_64-pc-linux-gnu, applying to trunk. -- 8< -- I want to distinguish between constraint && and fold-expressions there of written by the user and those implied by template parameter type-constraints; to that end, let's improve our EXPR_LOCATION for an explicit fold-expression. The fold3.C change is needed because this moves the caret from the end of the expression to the operator, which means the location of the error refers to the macro invocation rather than the macro definition; both locations are still printed, but which one is an error and which a note changes. gcc/cp/ChangeLog: * parser.cc (cp_parser_fold_expression): Track location range. * semantics.cc (finish_unary_fold_expr) (finish_left_unary_fold_expr, finish_right_unary_fold_expr) (finish_binary_fold_expr): Add location parm. * constraint.cc (finish_shorthand_constraint): Pass it. * pt.cc (convert_generic_types_to_packs): Likewise. * cp-tree.h: Adjust. gcc/testsuite/ChangeLog: * g++.dg/concepts/diagnostic3.C: Add expected column. * g++.dg/cpp1z/fold3.C: Adjust diagnostic lines. --- gcc/cp/cp-tree.h | 6 +- gcc/cp/constraint.cc | 3 +- gcc/cp/parser.cc | 16 ++++-- gcc/cp/pt.cc | 4 +- gcc/cp/semantics.cc | 25 +++++---- gcc/testsuite/g++.dg/concepts/diagnostic3.C | 4 +- gcc/testsuite/g++.dg/cpp1z/fold3.C | 62 ++++++++++----------- 7 files changed, 66 insertions(+), 54 deletions(-) base-commit: b7a28c0904fa67f98d7ca7e9d828fc5fc58c7078 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6e34952da99..efcd2de54e5 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8209,9 +8209,9 @@ extern void maybe_warn_about_useless_cast (location_t, tree, tree, tsubst_flags_t); extern tree cp_perform_integral_promotions (tree, tsubst_flags_t); -extern tree finish_left_unary_fold_expr (tree, int); -extern tree finish_right_unary_fold_expr (tree, int); -extern tree finish_binary_fold_expr (tree, tree, int); +extern tree finish_left_unary_fold_expr (location_t, tree, int); +extern tree finish_right_unary_fold_expr (location_t, tree, int); +extern tree finish_binary_fold_expr (location_t, tree, tree, int); extern tree treat_lvalue_as_rvalue_p (tree, bool); extern bool decl_in_std_namespace_p (tree); extern void maybe_warn_pessimizing_move (tree, tree, bool); diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index c9e4e7043cd..64b64e17857 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -1607,7 +1607,8 @@ finish_shorthand_constraint (tree decl, tree constr) /* Make the check a fold-expression if needed. */ if (apply_to_each_p && declared_pack_p) - check = finish_left_unary_fold_expr (check, TRUTH_ANDIF_EXPR); + check = finish_left_unary_fold_expr (DECL_SOURCE_LOCATION (decl), + check, TRUTH_ANDIF_EXPR); return check; } diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index f3abae716fe..59b9852895e 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -5533,6 +5533,8 @@ static cp_expr cp_parser_fold_expression (cp_parser *parser, tree expr1) { cp_id_kind pidk; + location_t loc = cp_lexer_peek_token (parser->lexer)->location; + const cp_token *token = nullptr; // Left fold. if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) @@ -5540,6 +5542,7 @@ cp_parser_fold_expression (cp_parser *parser, tree expr1) if (expr1) return error_mark_node; cp_lexer_consume_token (parser->lexer); + token = cp_lexer_peek_token (parser->lexer); int op = cp_parser_fold_operator (parser); if (op == ERROR_MARK) { @@ -5551,10 +5554,11 @@ cp_parser_fold_expression (cp_parser *parser, tree expr1) false, &pidk); if (expr == error_mark_node) return error_mark_node; - return finish_left_unary_fold_expr (expr, op); + loc = make_location (token->location, loc, parser->lexer); + return finish_left_unary_fold_expr (loc, expr, op); } - const cp_token* token = cp_lexer_peek_token (parser->lexer); + token = cp_lexer_peek_token (parser->lexer); int op = cp_parser_fold_operator (parser); if (op == ERROR_MARK) { @@ -5585,7 +5589,10 @@ cp_parser_fold_expression (cp_parser *parser, tree expr1) // Right fold. if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - return finish_right_unary_fold_expr (expr1, op); + { + loc = make_location (token->location, loc, parser->lexer); + return finish_right_unary_fold_expr (loc, expr1, op); + } if (cp_lexer_next_token_is_not (parser->lexer, token->type)) { @@ -5598,7 +5605,8 @@ cp_parser_fold_expression (cp_parser *parser, tree expr1) tree expr2 = cp_parser_cast_expression (parser, false, false, false, &pidk); if (expr2 == error_mark_node) return error_mark_node; - return finish_binary_fold_expr (expr1, expr2, op); + loc = make_location (token->location, loc, parser->lexer); + return finish_binary_fold_expr (loc, expr1, expr2, op); } /* Parse a primary-expression. diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 73ac1cb597c..7cbf903ae29 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -31423,7 +31423,9 @@ convert_generic_types_to_packs (tree parm, int start_idx, int end_idx) { tree id = unpack_concept_check (constr); TREE_VEC_ELT (TREE_OPERAND (id, 1), 0) = t; - tree fold = finish_left_unary_fold_expr (constr, TRUTH_ANDIF_EXPR); + location_t loc = DECL_SOURCE_LOCATION (TYPE_NAME (t)); + tree fold = finish_left_unary_fold_expr (loc, constr, + TRUTH_ANDIF_EXPR); TEMPLATE_PARM_CONSTRAINTS (node) = fold; /* If there was a constraint, we also need to replace that in diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 80ef1364e33..2a0cf963e91 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -12605,7 +12605,7 @@ capture_decltype (tree decl) this is a right unary fold. Otherwise it is a left unary fold. */ static tree -finish_unary_fold_expr (tree expr, int op, tree_code dir) +finish_unary_fold_expr (location_t loc, tree expr, int op, tree_code dir) { /* Build a pack expansion (assuming expr has pack type). */ if (!uses_parameter_packs (expr)) @@ -12618,7 +12618,7 @@ finish_unary_fold_expr (tree expr, int op, tree_code dir) /* Build the fold expression. */ tree code = build_int_cstu (integer_type_node, abs (op)); - tree fold = build_min_nt_loc (input_location, dir, code, pack); + tree fold = build_min_nt_loc (loc, dir, code, pack); FOLD_EXPR_MODIFY_P (fold) = (op < 0); TREE_TYPE (fold) = build_dependent_operator_type (NULL_TREE, FOLD_EXPR_OP (fold), @@ -12627,27 +12627,28 @@ finish_unary_fold_expr (tree expr, int op, tree_code dir) } tree -finish_left_unary_fold_expr (tree expr, int op) +finish_left_unary_fold_expr (location_t loc, tree expr, int op) { - return finish_unary_fold_expr (expr, op, UNARY_LEFT_FOLD_EXPR); + return finish_unary_fold_expr (loc, expr, op, UNARY_LEFT_FOLD_EXPR); } tree -finish_right_unary_fold_expr (tree expr, int op) +finish_right_unary_fold_expr (location_t loc, tree expr, int op) { - return finish_unary_fold_expr (expr, op, UNARY_RIGHT_FOLD_EXPR); + return finish_unary_fold_expr (loc, expr, op, UNARY_RIGHT_FOLD_EXPR); } /* Build a binary fold expression over EXPR1 and EXPR2. The associativity of the fold is determined by EXPR1 and EXPR2 (whichever has an unexpanded parameter pack). */ -tree -finish_binary_fold_expr (tree pack, tree init, int op, tree_code dir) +static tree +finish_binary_fold_expr (location_t loc, tree pack, tree init, + int op, tree_code dir) { pack = make_pack_expansion (pack); tree code = build_int_cstu (integer_type_node, abs (op)); - tree fold = build_min_nt_loc (input_location, dir, code, pack, init); + tree fold = build_min_nt_loc (loc, dir, code, pack, init); FOLD_EXPR_MODIFY_P (fold) = (op < 0); TREE_TYPE (fold) = build_dependent_operator_type (NULL_TREE, FOLD_EXPR_OP (fold), @@ -12656,16 +12657,16 @@ finish_binary_fold_expr (tree pack, tree init, int op, tree_code dir) } tree -finish_binary_fold_expr (tree expr1, tree expr2, int op) +finish_binary_fold_expr (location_t loc, tree expr1, tree expr2, int op) { // Determine which expr has an unexpanded parameter pack and // set the pack and initial term. bool pack1 = uses_parameter_packs (expr1); bool pack2 = uses_parameter_packs (expr2); if (pack1 && !pack2) - return finish_binary_fold_expr (expr1, expr2, op, BINARY_RIGHT_FOLD_EXPR); + return finish_binary_fold_expr (loc, expr1, expr2, op, BINARY_RIGHT_FOLD_EXPR); else if (pack2 && !pack1) - return finish_binary_fold_expr (expr2, expr1, op, BINARY_LEFT_FOLD_EXPR); + return finish_binary_fold_expr (loc, expr2, expr1, op, BINARY_LEFT_FOLD_EXPR); else { if (pack1) diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic3.C b/gcc/testsuite/g++.dg/concepts/diagnostic3.C index 410651a9c1a..52b2f23c95e 100644 --- a/gcc/testsuite/g++.dg/concepts/diagnostic3.C +++ b/gcc/testsuite/g++.dg/concepts/diagnostic3.C @@ -7,7 +7,7 @@ template concept foo = (bool)(foo_v | foo_v); template -requires (foo && ...) // { dg-message "with Ts = .int, char... evaluated to .false." } +requires (foo && ...) // { dg-message "19:with Ts = .int, char... evaluated to .false." } void bar() { } @@ -16,7 +16,7 @@ template struct S { }; template -requires (foo> && ...) // { dg-message "with Is = .2, 3, 4... evaluated to .false." } +requires (foo> && ...) // { dg-message "22:with Is = .2, 3, 4... evaluated to .false." } void baz() { } diff --git a/gcc/testsuite/g++.dg/cpp1z/fold3.C b/gcc/testsuite/g++.dg/cpp1z/fold3.C index 787bf792be9..a2561410ec4 100644 --- a/gcc/testsuite/g++.dg/cpp1z/fold3.C +++ b/gcc/testsuite/g++.dg/cpp1z/fold3.C @@ -7,44 +7,44 @@ #define MAKE_FN(name, op) \ template \ - constexpr auto name (Ts... ts) { return (... op ts); } // { dg-error "empty" } + constexpr auto name (Ts... ts) { return (... op ts); } // { dg-message "" } -MAKE_FN (add, +); -MAKE_FN (sub, -); -MAKE_FN (mul, *); -MAKE_FN (div, /); -MAKE_FN (mod, %); -MAKE_FN (bxor, ^); -MAKE_FN (bor, |); -MAKE_FN (band, &); -MAKE_FN (lsh, <<); -MAKE_FN (rsh, >>); +MAKE_FN (add, +); // { dg-message "" } +MAKE_FN (sub, -); // { dg-message "" } +MAKE_FN (mul, *); // { dg-message "" } +MAKE_FN (div, /); // { dg-message "" } +MAKE_FN (mod, %); // { dg-message "" } +MAKE_FN (bxor, ^); // { dg-message "" } +MAKE_FN (bor, |); // { dg-message "" } +MAKE_FN (band, &); // { dg-message "" } +MAKE_FN (lsh, <<); // { dg-message "" } +MAKE_FN (rsh, >>); // { dg-message "" } -MAKE_FN (assign, =); -MAKE_FN (addi, +=); -MAKE_FN (subi, -=); -MAKE_FN (muli, *=); -MAKE_FN (divi, /=); -MAKE_FN (modi, %=); -MAKE_FN (bxori, ^=); -MAKE_FN (bori, |=); -MAKE_FN (bandi, &=); -MAKE_FN (lshi, <<=); -MAKE_FN (rshi, >>=); +MAKE_FN (assign, =); // { dg-message "" } +MAKE_FN (addi, +=); // { dg-message "" } +MAKE_FN (subi, -=); // { dg-message "" } +MAKE_FN (muli, *=); // { dg-message "" } +MAKE_FN (divi, /=); // { dg-message "" } +MAKE_FN (modi, %=); // { dg-message "" } +MAKE_FN (bxori, ^=); // { dg-message "" } +MAKE_FN (bori, |=); // { dg-message "" } +MAKE_FN (bandi, &=); // { dg-message "" } +MAKE_FN (lshi, <<=); // { dg-message "" } +MAKE_FN (rshi, >>=); // { dg-message "" } -MAKE_FN (eq, ==); -MAKE_FN (ne, !=); -MAKE_FN (lt, <); -MAKE_FN (gt, >); -MAKE_FN (le, <); -MAKE_FN (ge, >); +MAKE_FN (eq, ==); // { dg-message "" } +MAKE_FN (ne, !=); // { dg-message "" } +MAKE_FN (lt, <); // { dg-message "" } +MAKE_FN (gt, >); // { dg-message "" } +MAKE_FN (le, <); // { dg-message "" } +MAKE_FN (ge, >); // { dg-message "" } MAKE_FN (land, &&); MAKE_FN (lor, ||); MAKE_FN (comma, COMMA); -MAKE_FN (dot_star, .*); -MAKE_FN (arrow_star, ->*); +MAKE_FN (dot_star, .*); // { dg-message "" } +MAKE_FN (arrow_star, ->*); // { dg-message "" } int main() { static_assert(land() == true, ""); @@ -52,7 +52,7 @@ int main() { comma(); // No value to theck // These are all errors, but the error is emitted at the point - // of instantiation (line 10). + // of macro definition or expansion above. add(); // { dg-message "required from here" } mul(); // { dg-message "required from here" } bor(); // { dg-message "required from here" }