From patchwork Tue May 15 23:56:59 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 159473 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 67775B6FAC for ; Wed, 16 May 2012 09:58:23 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1337731104; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Message-ID:Date:From:User-Agent:MIME-Version: To:CC:Subject:References:In-Reply-To:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=5TU1SPrYiofIAATNDUDih/pRBrE=; b=qo5ILWG9kNlfqED1KOWOi03kSn+364O8R5D6yKT5AK8ckctn371xIuAJ7c072L ptfNx+ZiwKhGUTxRtnw25NbgUL5T/qEVx3eghUq6Txz4IGRovC6paxw+3TsOuFJg U+aM9VHtkEEEVDhHRoC37oD/ZEisH6cYHYnVNBV/ua+50= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=PqcBIxEQlWIZ9KstIPEvtkWN06oN97ZRqKUJGeP7T2gpn9bb7L5Yjo0mY3NAaC xefCXiefSjyZ9o5qFDTM79XahsLtEcvYrQsBnHbqHnkZiscgsXdVVUy3TILITmF9 4Ov9AKThEX+zQUbpT1y6fyRD99GGoiH1gso0WGOCvY3KE=; Received: (qmail 6651 invoked by alias); 15 May 2012 23:58:19 -0000 Received: (qmail 6440 invoked by uid 22791); 15 May 2012 23:58:15 -0000 X-SWARE-Spam-Status: No, hits=-7.3 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_NO, RCVD_IN_HOSTKARMA_W, TW_TM, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from acsinet15.oracle.com (HELO acsinet15.oracle.com) (141.146.126.227) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 15 May 2012 23:57:57 +0000 Received: from ucsinet22.oracle.com (ucsinet22.oracle.com [156.151.31.94]) by acsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q4FNvs3X004596 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 15 May 2012 23:57:55 GMT Received: from acsmt356.oracle.com (acsmt356.oracle.com [141.146.40.156]) by ucsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q4FNvrAf023866 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 15 May 2012 23:57:53 GMT Received: from abhmt105.oracle.com (abhmt105.oracle.com [141.146.116.57]) by acsmt356.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q4FNvqMk032297; Tue, 15 May 2012 18:57:52 -0500 Received: from [192.168.1.4] (/79.52.195.202) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 15 May 2012 16:57:51 -0700 Message-ID: <4FB2ED4B.40204@oracle.com> Date: Wed, 16 May 2012 01:56:59 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20120421 Thunderbird/12.0 MIME-Version: 1.0 To: Jason Merrill CC: "gcc-patches@gcc.gnu.org" Subject: Re: [C++ Patch] PR 44516 References: <4FB042F7.1060802@oracle.com> <4FB064DE.1080907@redhat.com> <4FB07AF9.8050500@oracle.com> <4FB082F1.3020100@redhat.com> <4FB1072B.9030909@oracle.com> <4FB131DA.7050809@redhat.com> <4FB1388F.1020208@oracle.com> <4FB14313.8000001@redhat.com> <4FB1926F.1040100@oracle.com> <4FB2A630.2090003@redhat.com> <4FB2C307.6090509@oracle.com> <4FB2D47A.9020706@redhat.com> <4FB2DC57.8080100@oracle.com> <4FB2E89B.2090408@redhat.com> In-Reply-To: <4FB2E89B.2090408@redhat.com> X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, On 05/16/2012 01:36 AM, Jason Merrill wrote: > On 05/15/2012 06:44 PM, Paolo Carlini wrote: >> I can't change the build_min_non_dep_loc call in build_x_binary_op to >> simply use loc, that causes the diagnostic regression I mentioned >> before. Sorry, I wasn't clear in my previous message, it happens when >> one "naturally" just passes loc, not the EXPR_LOCATION from the >> intermediate expr. > Because loc is wrong? Yes, it's wrong in the sense that it's input_location, which is ahead of the right place. It looks like some of these problems have to do with this trick at the beginning of tsubst_expr: if (EXPR_HAS_LOCATION (t)) input_location = EXPR_LOCATION (t); thus, if at some point we pass down a real location (not an UNKNOWN_LOCATION), which is however wrong because past the right place, tsubst_expr takes it and all the next error messages have the wrong location. An UNKNOWN location would be more "robust", if I'm explaining myself well enough. Now, the problem is, this testcase giving us problems (libstdc++-v3/testsuite/20_util/bind/ref_neg.cc) is *huge*, I'm having troubles of the same size debugging it ;) >> Is it Ok with you if we return to a patch only touching the >> build_min_nt_locs? > > It seems like as long as we're messing with this area we ought to > finish the job, but if you want to split up the patch that's fine. We definitely have to finish the job. But I also like (as a general philosophy, so to speak) to work incrementally, to make small but solid progress, milestones. Now I'm fearing that in order to finally be able to adjust all the build_min_non_dep_loc calls I have like to remove the big trick at the beginning of tsubst_expr and take care of each and every case :( But, speaking of incremental work: what if, post the build_min_nt_loc chunk, we handle build_min_non_dep and build_min in a case by case way? Thus we keep around the non-_loc variant and gradually replace each call? With testcases (small!) checking columns too. Finally, I'm attaching my latest build_min_nt_loc patch. Turns out, in the light of the better understanding I now have, I can't justify most of the EXPR_LOC_OR_HERE, outside those for build_x_modify_expr which you explicitly indicated. Elsewhere I have EXPR_LOCATION, besides an EXPR_LOC_OR_HERE close to a build_x_modify_expr, dealing with the same tree. Passes testing... Thanks! Paolo. /////////////////////// Index: libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc =================================================================== --- libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc (revision 187559) +++ libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc (working copy) @@ -2,7 +2,7 @@ // { dg-options "-std=gnu++0x" } // { dg-require-cstdint "" } -// Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation +// Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -51,5 +51,5 @@ test04() // { dg-error "required from here" "" { target *-*-* } 46 } // { dg-error "denominator cannot be zero" "" { target *-*-* } 265 } // { dg-error "out of range" "" { target *-*-* } 266 } -// { dg-error "overflow in constant expression" "" { target *-*-* } 61 } +// { dg-error "overflow in constant expression" "" { target *-*-* } 62 } // { dg-prune-output "not a member" } Index: gcc/testsuite/g++.dg/parse/error48.C =================================================================== --- gcc/testsuite/g++.dg/parse/error48.C (revision 0) +++ gcc/testsuite/g++.dg/parse/error48.C (revision 0) @@ -0,0 +1,10 @@ +// PR c++/44516 + +struct WebService { }; +struct Server { }; + +void addHTTPService(Server const &server, + WebService const *http) +{ + server += http; // { dg-error "10:no match for 'operator\\+='" } +} Index: gcc/testsuite/g++.dg/template/crash89.C =================================================================== --- gcc/testsuite/g++.dg/template/crash89.C (revision 187559) +++ gcc/testsuite/g++.dg/template/crash89.C (working copy) @@ -1,8 +1,8 @@ // PR c++/34397 -template struct A +template struct A // { dg-error "subscripted|template" } { typedef A B; }; -A a; // { dg-error "subscripted|template|declaration" } +A a; // { dg-error "declaration" } Index: gcc/cp/typeck.c =================================================================== --- gcc/cp/typeck.c (revision 187559) +++ gcc/cp/typeck.c (working copy) @@ -2536,7 +2536,8 @@ finish_class_member_access_expr (tree object, tree || (TREE_CODE (name) == SCOPE_REF && TYPE_P (TREE_OPERAND (name, 0)) && dependent_type_p (TREE_OPERAND (name, 0)))) - return build_min_nt (COMPONENT_REF, object, name, NULL_TREE); + return build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF, + object, name, NULL_TREE); object = build_non_dependent_expr (object); } else if (c_dialect_objc () @@ -2743,7 +2744,7 @@ build_x_indirect_ref (location_t loc, tree expr, r if (TREE_TYPE (expr) && POINTER_TYPE_P (TREE_TYPE (expr))) return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr); if (type_dependent_expression_p (expr)) - return build_min_nt (INDIRECT_REF, expr); + return build_min_nt_loc (loc, INDIRECT_REF, expr); expr = build_non_dependent_expr (expr); } @@ -3597,7 +3598,7 @@ build_x_binary_op (location_t loc, enum tree_code { if (type_dependent_expression_p (arg1) || type_dependent_expression_p (arg2)) - return build_min_nt (code, arg1, arg2); + return build_min_nt_loc (loc, code, arg1, arg2); arg1 = build_non_dependent_expr (arg1); arg2 = build_non_dependent_expr (arg2); } @@ -3629,7 +3630,8 @@ build_x_binary_op (location_t loc, enum tree_code /* Build and return an ARRAY_REF expression. */ tree -build_x_array_ref (tree arg1, tree arg2, tsubst_flags_t complain) +build_x_array_ref (location_t loc, tree arg1, tree arg2, + tsubst_flags_t complain) { tree orig_arg1 = arg1; tree orig_arg2 = arg2; @@ -3639,13 +3641,13 @@ tree { if (type_dependent_expression_p (arg1) || type_dependent_expression_p (arg2)) - return build_min_nt (ARRAY_REF, arg1, arg2, - NULL_TREE, NULL_TREE); + return build_min_nt_loc (loc, ARRAY_REF, arg1, arg2, + NULL_TREE, NULL_TREE); arg1 = build_non_dependent_expr (arg1); arg2 = build_non_dependent_expr (arg2); } - expr = build_new_op (input_location, ARRAY_REF, LOOKUP_NORMAL, arg1, + expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, arg1, arg2, NULL_TREE, /*overload=*/NULL, complain); if (processing_template_decl && expr != error_mark_node) @@ -4671,7 +4673,7 @@ build_x_unary_op (location_t loc, enum tree_code c if (processing_template_decl) { if (type_dependent_expression_p (xarg)) - return build_min_nt (code, xarg, NULL_TREE); + return build_min_nt_loc (loc, code, xarg, NULL_TREE); xarg = build_non_dependent_expr (xarg); } @@ -5586,7 +5588,7 @@ cxx_mark_addressable (tree exp) /* Build and return a conditional expression IFEXP ? OP1 : OP2. */ tree -build_x_conditional_expr (tree ifexp, tree op1, tree op2, +build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2, tsubst_flags_t complain) { tree orig_ifexp = ifexp; @@ -5603,7 +5605,7 @@ tree /* As a GNU extension, the middle operand may be omitted. */ || (op1 && type_dependent_expression_p (op1)) || type_dependent_expression_p (op2)) - return build_min_nt (COND_EXPR, ifexp, op1, op2); + return build_min_nt_loc (loc, COND_EXPR, ifexp, op1, op2); ifexp = build_non_dependent_expr (ifexp); if (op1) op1 = build_non_dependent_expr (op1); @@ -5670,8 +5672,8 @@ build_x_compound_expr_from_list (tree list, expr_l return error_mark_node; for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list)) - expr = build_x_compound_expr (expr, TREE_VALUE (list), - complain); + expr = build_x_compound_expr (EXPR_LOCATION (TREE_VALUE (list)), + expr, TREE_VALUE (list), complain); } return expr; @@ -5699,7 +5701,8 @@ build_x_compound_expr_from_vec (VEC(tree,gc) *vec, expr = VEC_index (tree, vec, 0); for (ix = 1; VEC_iterate (tree, vec, ix, t); ++ix) - expr = build_x_compound_expr (expr, t, tf_warning_or_error); + expr = build_x_compound_expr (EXPR_LOCATION (t), expr, + t, tf_warning_or_error); return expr; } @@ -5708,7 +5711,8 @@ build_x_compound_expr_from_vec (VEC(tree,gc) *vec, /* Handle overloading of the ',' operator when needed. */ tree -build_x_compound_expr (tree op1, tree op2, tsubst_flags_t complain) +build_x_compound_expr (location_t loc, tree op1, tree op2, + tsubst_flags_t complain) { tree result; tree orig_op1 = op1; @@ -5718,12 +5722,12 @@ tree { if (type_dependent_expression_p (op1) || type_dependent_expression_p (op2)) - return build_min_nt (COMPOUND_EXPR, op1, op2); + return build_min_nt_loc (loc, COMPOUND_EXPR, op1, op2); op1 = build_non_dependent_expr (op1); op2 = build_non_dependent_expr (op2); } - result = build_new_op (input_location, COMPOUND_EXPR, LOOKUP_NORMAL, + result = build_new_op (loc, COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2, NULL_TREE, /*overload=*/NULL, complain); if (!result) result = cp_build_compound_expr (op1, op2, complain); @@ -7105,16 +7109,17 @@ cp_build_modify_expr (tree lhs, enum tree_code mod } tree -build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, - tsubst_flags_t complain) +build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, + tree rhs, tsubst_flags_t complain) { if (processing_template_decl) - return build_min_nt (MODOP_EXPR, lhs, - build_min_nt (modifycode, NULL_TREE, NULL_TREE), rhs); + return build_min_nt_loc (loc, MODOP_EXPR, lhs, + build_min_nt_loc (loc, modifycode, NULL_TREE, + NULL_TREE), rhs); if (modifycode != NOP_EXPR) { - tree rval = build_new_op (input_location, MODIFY_EXPR, LOOKUP_NORMAL, + tree rval = build_new_op (loc, MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs, make_node (modifycode), /*overload=*/NULL, complain); if (rval) Index: gcc/cp/tree.c =================================================================== --- gcc/cp/tree.c (revision 187559) +++ gcc/cp/tree.c (working copy) @@ -2025,7 +2025,7 @@ break_out_target_exprs (tree t) expressions */ tree -build_min_nt (enum tree_code code, ...) +build_min_nt_loc (location_t loc, enum tree_code code, ...) { tree t; int length; @@ -2037,6 +2037,7 @@ tree va_start (p, code); t = make_node (code); + SET_EXPR_LOCATION (t, loc); length = TREE_CODE_LENGTH (code); for (i = 0; i < length; i++) Index: gcc/cp/typeck2.c =================================================================== --- gcc/cp/typeck2.c (revision 187559) +++ gcc/cp/typeck2.c (working copy) @@ -1484,7 +1484,7 @@ build_x_arrow (location_t loc, tree expr, tsubst_f if (processing_template_decl) { if (type_dependent_expression_p (expr)) - return build_min_nt (ARROW_EXPR, expr); + return build_min_nt_loc (loc, ARROW_EXPR, expr); expr = build_non_dependent_expr (expr); } Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 187559) +++ gcc/cp/pt.c (working copy) @@ -11968,7 +11968,8 @@ tsubst_qualified_id (tree qualified_id, tree args, if (dependent_scope_p (scope)) { if (is_template) - expr = build_min_nt (TEMPLATE_ID_EXPR, expr, template_args); + expr = build_min_nt_loc (UNKNOWN_LOCATION, TEMPLATE_ID_EXPR, + expr, template_args); return build_qualified_name (NULL_TREE, scope, expr, QUALIFIED_NAME_IS_TEMPLATE (qualified_id)); } @@ -12672,7 +12673,8 @@ tsubst_omp_for_iterator (tree t, int i, tree declv cond = RECUR (TREE_VEC_ELT (OMP_FOR_COND (t), i)); incr = TREE_VEC_ELT (OMP_FOR_INCR (t), i); if (TREE_CODE (incr) == MODIFY_EXPR) - incr = build_x_modify_expr (RECUR (TREE_OPERAND (incr, 0)), NOP_EXPR, + incr = build_x_modify_expr (EXPR_LOC_OR_HERE (incr), + RECUR (TREE_OPERAND (incr, 0)), NOP_EXPR, RECUR (TREE_OPERAND (incr, 1)), complain); else @@ -13638,7 +13640,8 @@ tsubst_copy_and_build (tree t, case ARRAY_REF: op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), args, complain, in_decl); - return build_x_array_ref (op1, RECUR (TREE_OPERAND (t, 1)), complain); + return build_x_array_ref (EXPR_LOCATION (t), op1, + RECUR (TREE_OPERAND (t, 1)), complain); case SIZEOF_EXPR: if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))) @@ -13699,7 +13702,8 @@ tsubst_copy_and_build (tree t, case MODOP_EXPR: { tree r = build_x_modify_expr - (RECUR (TREE_OPERAND (t, 0)), + (EXPR_LOC_OR_HERE (t), + RECUR (TREE_OPERAND (t, 0)), TREE_CODE (TREE_OPERAND (t, 1)), RECUR (TREE_OPERAND (t, 2)), complain); @@ -13783,7 +13787,8 @@ tsubst_copy_and_build (tree t, complain); case COMPOUND_EXPR: - return build_x_compound_expr (RECUR (TREE_OPERAND (t, 0)), + return build_x_compound_expr (EXPR_LOCATION (t), + RECUR (TREE_OPERAND (t, 0)), RECUR (TREE_OPERAND (t, 1)), complain); @@ -14023,7 +14028,8 @@ tsubst_copy_and_build (tree t, exp2 = RECUR (TREE_OPERAND (t, 2)); } - return build_x_conditional_expr (cond, exp1, exp2, complain); + return build_x_conditional_expr (EXPR_LOCATION (t), + cond, exp1, exp2, complain); } case PSEUDO_DTOR_EXPR: Index: gcc/cp/semantics.c =================================================================== --- gcc/cp/semantics.c (revision 187559) +++ gcc/cp/semantics.c (working copy) @@ -1498,7 +1498,8 @@ finish_mem_initializers (tree mem_inits) TREE_VALUE (mem) = error_mark_node; } - add_stmt (build_min_nt (CTOR_INITIALIZER, mem_inits)); + add_stmt (build_min_nt_loc (UNKNOWN_LOCATION, + CTOR_INITIALIZER, mem_inits)); } else emit_mem_initializers (mem_inits); @@ -4456,7 +4457,8 @@ handle_omp_for_class_iterator (int i, location_t l cond = error_mark_node; else { - tree tem = build_x_binary_op (input_location, TREE_CODE (cond), + tree tem = build_x_binary_op (EXPR_LOCATION (cond), + TREE_CODE (cond), iter, ERROR_MARK, TREE_OPERAND (cond, 1), ERROR_MARK, NULL, tf_warning_or_error); @@ -4473,7 +4475,7 @@ handle_omp_for_class_iterator (int i, location_t l error_at (elocus, "invalid controlling predicate"); return true; } - diff = build_x_binary_op (input_location, MINUS_EXPR, TREE_OPERAND (cond, 1), + diff = build_x_binary_op (elocus, MINUS_EXPR, TREE_OPERAND (cond, 1), ERROR_MARK, iter, ERROR_MARK, NULL, tf_warning_or_error); if (error_operand_p (diff)) @@ -4496,7 +4498,8 @@ handle_omp_for_class_iterator (int i, location_t l incr = error_mark_node; break; } - iter_incr = build_x_unary_op (input_location, TREE_CODE (incr), iter, + iter_incr = build_x_unary_op (EXPR_LOCATION (incr), + TREE_CODE (incr), iter, tf_warning_or_error); if (error_operand_p (iter_incr)) return true; @@ -4520,7 +4523,8 @@ handle_omp_for_class_iterator (int i, location_t l incr = error_mark_node; else { - iter_incr = build_x_modify_expr (iter, TREE_CODE (rhs), + iter_incr = build_x_modify_expr (EXPR_LOC_OR_HERE (rhs), + iter, TREE_CODE (rhs), TREE_OPERAND (rhs, 1), tf_warning_or_error); if (error_operand_p (iter_incr)) @@ -4546,14 +4550,16 @@ handle_omp_for_class_iterator (int i, location_t l incr = error_mark_node; else { - iter_incr = build_x_binary_op (input_location, PLUS_EXPR, + iter_incr = build_x_binary_op (EXPR_LOC_OR_HERE (rhs), + PLUS_EXPR, TREE_OPERAND (rhs, 0), ERROR_MARK, iter, ERROR_MARK, NULL, tf_warning_or_error); if (error_operand_p (iter_incr)) return true; - iter_incr = build_x_modify_expr (iter, NOP_EXPR, + iter_incr = build_x_modify_expr (EXPR_LOC_OR_HERE (rhs), + iter, NOP_EXPR, iter_incr, tf_warning_or_error); if (error_operand_p (iter_incr)) @@ -4604,18 +4610,22 @@ handle_omp_for_class_iterator (int i, location_t l if (orig_pre_body) add_stmt (orig_pre_body); if (init != NULL) - finish_expr_stmt (build_x_modify_expr (iter, NOP_EXPR, init, + finish_expr_stmt (build_x_modify_expr (elocus, + iter, NOP_EXPR, init, tf_warning_or_error)); init = build_int_cst (TREE_TYPE (diff), 0); if (c && iter_incr == NULL) { - finish_expr_stmt (build_x_modify_expr (incr_var, NOP_EXPR, + finish_expr_stmt (build_x_modify_expr (elocus, + incr_var, NOP_EXPR, incr, tf_warning_or_error)); incr = incr_var; - iter_incr = build_x_modify_expr (iter, PLUS_EXPR, incr, + iter_incr = build_x_modify_expr (elocus, + iter, PLUS_EXPR, incr, tf_warning_or_error); } - finish_expr_stmt (build_x_modify_expr (last, NOP_EXPR, init, + finish_expr_stmt (build_x_modify_expr (elocus, + last, NOP_EXPR, init, tf_warning_or_error)); *pre_body = pop_stmt_list (*pre_body); @@ -4628,11 +4638,13 @@ handle_omp_for_class_iterator (int i, location_t l orig_body = *body; *body = push_stmt_list (); iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), decl, last); - iter_init = build_x_modify_expr (iter, PLUS_EXPR, iter_init, + iter_init = build_x_modify_expr (elocus, + iter, PLUS_EXPR, iter_init, tf_warning_or_error); iter_init = build1 (NOP_EXPR, void_type_node, iter_init); finish_expr_stmt (iter_init); - finish_expr_stmt (build_x_modify_expr (last, NOP_EXPR, decl, + finish_expr_stmt (build_x_modify_expr (elocus, + last, NOP_EXPR, decl, tf_warning_or_error)); add_stmt (orig_body); *body = pop_stmt_list (*body); @@ -4939,7 +4951,8 @@ finish_omp_atomic (enum tree_code code, enum tree_ { if (code == OMP_ATOMIC_READ) { - stmt = build_min_nt (OMP_ATOMIC_READ, orig_lhs); + stmt = build_min_nt_loc (EXPR_LOCATION (orig_lhs), + OMP_ATOMIC_READ, orig_lhs); stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt); } else @@ -4949,10 +4962,12 @@ finish_omp_atomic (enum tree_code code, enum tree_ else stmt = build2 (opcode, void_type_node, orig_lhs, orig_rhs); if (orig_rhs1) - stmt = build_min_nt (COMPOUND_EXPR, orig_rhs1, stmt); + stmt = build_min_nt_loc (EXPR_LOCATION (orig_rhs1), + COMPOUND_EXPR, orig_rhs1, stmt); if (code != OMP_ATOMIC) { - stmt = build_min_nt (code, orig_lhs1, stmt); + stmt = build_min_nt_loc (EXPR_LOCATION (orig_lhs1), + code, orig_lhs1, stmt); stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt); } } Index: gcc/cp/decl2.c =================================================================== --- gcc/cp/decl2.c (revision 187559) +++ gcc/cp/decl2.c (working copy) @@ -350,8 +350,8 @@ grok_array_decl (location_t loc, tree array_expr, { if (type_dependent_expression_p (array_expr) || type_dependent_expression_p (index_exp)) - return build_min_nt (ARRAY_REF, array_expr, index_exp, - NULL_TREE, NULL_TREE); + return build_min_nt_loc (loc, ARRAY_REF, array_expr, index_exp, + NULL_TREE, NULL_TREE); array_expr = build_non_dependent_expr (array_expr); index_exp = build_non_dependent_expr (index_exp); } @@ -1370,8 +1370,8 @@ build_anon_union_vars (tree type, tree object) permerror (input_location, "protected member %q+#D in anonymous union", field); if (processing_template_decl) - ref = build_min_nt (COMPONENT_REF, object, - DECL_NAME (field), NULL_TREE); + ref = build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF, object, + DECL_NAME (field), NULL_TREE); else ref = build_class_member_access_expr (object, field, NULL_TREE, false, tf_warning_or_error); Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 187559) +++ gcc/cp/parser.c (working copy) @@ -7438,6 +7438,7 @@ cp_parser_question_colon_clause (cp_parser* parser tree expr; tree assignment_expr; struct cp_token *token; + location_t loc = cp_lexer_peek_token (parser->lexer)->location; /* Consume the `?' token. */ cp_lexer_consume_token (parser->lexer); @@ -7472,7 +7473,7 @@ cp_parser_question_colon_clause (cp_parser* parser c_inhibit_evaluation_warnings -= logical_or_expr == truthvalue_true_node; /* Build the conditional-expression. */ - return build_x_conditional_expr (logical_or_expr, + return build_x_conditional_expr (loc, logical_or_expr, expr, assignment_expr, tf_warning_or_error); @@ -7512,11 +7513,11 @@ cp_parser_assignment_expression (cp_parser* parser return cp_parser_question_colon_clause (parser, expr); else { - enum tree_code assignment_operator; + location_t loc = cp_lexer_peek_token (parser->lexer)->location; /* If it's an assignment-operator, we're using the second production. */ - assignment_operator + enum tree_code assignment_operator = cp_parser_assignment_operator_opt (parser); if (assignment_operator != ERROR_MARK) { @@ -7534,7 +7535,7 @@ cp_parser_assignment_expression (cp_parser* parser NIC_ASSIGNMENT)) return error_mark_node; /* Build the assignment expression. */ - expr = build_x_modify_expr (expr, + expr = build_x_modify_expr (loc, expr, assignment_operator, rhs, tf_warning_or_error); @@ -7643,6 +7644,7 @@ static tree cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk) { tree expression = NULL_TREE; + location_t loc = UNKNOWN_LOCATION; while (true) { @@ -7656,7 +7658,7 @@ cp_parser_expression (cp_parser* parser, bool cast if (!expression) expression = assignment_expression; else - expression = build_x_compound_expr (expression, + expression = build_x_compound_expr (loc, expression, assignment_expression, tf_warning_or_error); /* If the next token is not a comma, then we are done with the @@ -7664,6 +7666,7 @@ cp_parser_expression (cp_parser* parser, bool cast if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) break; /* Consume the `,'. */ + loc = cp_lexer_peek_token (parser->lexer)->location; cp_lexer_consume_token (parser->lexer); /* A comma operator cannot appear in a constant-expression. */ if (cp_parser_non_integral_constant_expression (parser, NIC_COMMA)) @@ -12499,7 +12502,9 @@ cp_parser_template_id (cp_parser *parser, /* Build a representation of the specialization. */ if (TREE_CODE (templ) == IDENTIFIER_NODE) - template_id = build_min_nt (TEMPLATE_ID_EXPR, templ, arguments); + template_id = build_min_nt_loc (next_token->location, + TEMPLATE_ID_EXPR, + templ, arguments); else if (DECL_TYPE_TEMPLATE_P (templ) || DECL_TEMPLATE_TEMPLATE_PARM_P (templ)) { @@ -26350,7 +26355,8 @@ cp_parser_omp_for_loop (cp_parser *parser, tree cl cp_parser_parse_definitely (parser); cp_parser_require (parser, CPP_EQ, RT_EQ); rhs = cp_parser_assignment_expression (parser, false, NULL); - finish_expr_stmt (build_x_modify_expr (decl, NOP_EXPR, + finish_expr_stmt (build_x_modify_expr (EXPR_LOC_OR_HERE (rhs), + decl, NOP_EXPR, rhs, tf_warning_or_error)); add_private_clause = true; Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 187559) +++ gcc/cp/cp-tree.h (working copy) @@ -5685,6 +5685,8 @@ extern bool xvalue_p (cons extern bool builtin_valid_in_constant_expr_p (const_tree); extern tree build_min (enum tree_code, tree, ...); extern tree build_min_nt (enum tree_code, ...); +extern tree build_min_nt_loc (location_t, enum tree_code, + ...); extern tree build_min_non_dep (enum tree_code, tree, ...); extern tree build_min_non_dep_call_vec (tree, tree, VEC(tree,gc) *); extern tree build_cplus_new (tree, tree, tsubst_flags_t); @@ -5813,7 +5815,8 @@ extern tree build_x_binary_op (location_t, enum tree_code, tree, enum tree_code, tree *, tsubst_flags_t); -extern tree build_x_array_ref (tree, tree, tsubst_flags_t); +extern tree build_x_array_ref (location_t, tree, tree, + tsubst_flags_t); extern tree build_x_unary_op (location_t, enum tree_code, tree, tsubst_flags_t); @@ -5822,12 +5825,13 @@ extern tree cp_build_addr_expr_strict (tree, tsub extern tree cp_build_unary_op (enum tree_code, tree, int, tsubst_flags_t); extern tree unary_complex_lvalue (enum tree_code, tree); -extern tree build_x_conditional_expr (tree, tree, tree, +extern tree build_x_conditional_expr (location_t, tree, tree, tree, tsubst_flags_t); extern tree build_x_compound_expr_from_list (tree, expr_list_kind, tsubst_flags_t); extern tree build_x_compound_expr_from_vec (VEC(tree,gc) *, const char *); -extern tree build_x_compound_expr (tree, tree, tsubst_flags_t); +extern tree build_x_compound_expr (location_t, tree, tree, + tsubst_flags_t); extern tree build_compound_expr (location_t, tree, tree); extern tree cp_build_compound_expr (tree, tree, tsubst_flags_t); extern tree build_static_cast (tree, tree, tsubst_flags_t); @@ -5835,7 +5839,8 @@ extern tree build_reinterpret_cast (tree, tree, t extern tree build_const_cast (tree, tree, tsubst_flags_t); extern tree build_c_cast (location_t, tree, tree); extern tree cp_build_c_cast (tree, tree, tsubst_flags_t); -extern tree build_x_modify_expr (tree, enum tree_code, tree, +extern tree build_x_modify_expr (location_t, tree, + enum tree_code, tree, tsubst_flags_t); extern tree cp_build_modify_expr (tree, enum tree_code, tree, tsubst_flags_t);