From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12067 invoked by alias); 11 Aug 2012 03:39:04 -0000 Received: (qmail 12057 invoked by uid 22791); 11 Aug 2012 03:39:02 -0000 X-SWARE-Spam-Status: No, hits=-5.5 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,KHOP_RCVD_TRUST,KHOP_THREADED,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE,TW_TM,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail-pb0-f47.google.com (HELO mail-pb0-f47.google.com) (209.85.160.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 11 Aug 2012 03:38:49 +0000 Received: by pbcwy7 with SMTP id wy7so3637391pbc.20 for ; Fri, 10 Aug 2012 20:38:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:x-system-of-record:x-gm-message-state; bh=tmnvUrxgS3jwEFXbzgaKa1HJQhMzepCDeUnOQy7diUk=; b=WkRv+xE6G+tdwv/yRNPKE8eWKCkl26HjNNl7f2z5Uu6MljE91HIairlaUQLHJox/0F b2KYNvLsNbZ4ybVQXSIp8tFf+xpzSCAZ646dLaoqnh8JRN5hxNTTG0D59e7h0C4rmGXR 6r5bV0vzds04hz0kJXDs/JF1s0Yj0J7xjZpoY81n/cTFRc0F8hstbqW1aI4c9s0Qmi+7 T1xx6dyRHwLjhtGB2Bg2Nlh88aLIpC7km/LY5M/gklPEFf9oyhLqpDNrjcOXZ2EWa4Ua yN92vRUU2QNqTmUDlg+iprbRcYU9bHRjKvvteJ/Y3T0b5NbKHaSEwBZ8tWJ/Q5HCmpao 8riw== Received: by 10.66.75.202 with SMTP id e10mr3587271paw.55.1344656328634; Fri, 10 Aug 2012 20:38:48 -0700 (PDT) MIME-Version: 1.0 Received: by 10.66.75.202 with SMTP id e10mr3587232paw.55.1344656328378; Fri, 10 Aug 2012 20:38:48 -0700 (PDT) Received: by 10.68.189.100 with HTTP; Fri, 10 Aug 2012 20:38:48 -0700 (PDT) In-Reply-To: References: <50228C38.5080703@redhat.com> <502294A1.3060800@redhat.com> <50243480.7090803@redhat.com> <50254A50.8070208@redhat.com> <50255B35.9020705@redhat.com> <50258712.4070002@redhat.com> Date: Sat, 11 Aug 2012 03:39:00 -0000 Message-ID: Subject: Re: [PATCH] Set correct source location for deallocator calls From: Dehao Chen To: Richard Henderson Cc: Jason Merrill , Richard Guenther , gcc-patches@gcc.gnu.org, David Li Content-Type: text/plain; charset=ISO-8859-1 X-System-Of-Record: true X-Gm-Message-State: ALoCoQll5bcCqHvn8dKFChV/jKHNrzkLo5ejuq+7WugH8B66mFppSOndy81XlIaEr4+7Wc6lfK7aJQ/f6IBvsuV2oBox/hK5OOjIRGbCR/n1+qSFkO7giejaz+jsuXmKAfghXJs4ePrLy07YtDLjwkfcXpoXnCXSinXYpRYB8/MUPCXrvNU7Z0AL+LIo8hVZfk1M/301cdyl X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2012-08/txt/msg00672.txt.bz2 New patch attached. Bootstrapped and passed GCC regression tests. Ok for trunk? Thanks, Dehao gcc/ChangeLog 2012-08-07 Dehao Chen * tree-eh.c (goto_queue_node): New field. (record_in_goto_queue): New parameter. (record_in_goto_queue_label): New parameter. (lower_try_finally_dup_block): New parameter. (maybe_record_in_goto_queue): Update source location. (lower_try_finally_copy): Likewise. (honor_protect_cleanup_actions): Likewise. * gimplify.c (gimplify_expr): Reset the location to unknown. gcc/testsuite/ChangeLog 2012-08-07 Dehao Chen * g++.dg/guality/deallocator.C: New test. Index: gcc/testsuite/g++.dg/guality/deallocator.C =================================================================== *** gcc/testsuite/g++.dg/guality/deallocator.C (revision 0) --- gcc/testsuite/g++.dg/guality/deallocator.C (revision 0) *************** *** 0 **** --- 1,33 ---- + // Test that debug info generated for auto-inserted deallocator is + // correctly attributed. + // This patch scans for the lineno directly from assembly, which may + // differ between different architectures. Because it mainly tests + // FE generated debug info, without losing generality, only x86 + // assembly is scanned in this test. + // { dg-do compile { target { i?86-*-* x86_64-*-* } } } + // { dg-options "-O2 -fno-exceptions -g" } + + struct t { + t (); + ~t (); + void foo(); + void bar(); + }; + + int bar(); + + void foo(int i) + { + for (int j = 0; j < 10; j++) + { + t test; + test.foo(); + if (i + j) + { + test.bar(); + return; + } + } + return; + } + // { dg-final { scan-assembler "1 28 0" } } Index: gcc/tree-eh.c =================================================================== *** gcc/tree-eh.c (revision 190209) --- gcc/tree-eh.c (working copy) *************** static bitmap eh_region_may_contain_thro *** 321,326 **** --- 321,327 ---- struct goto_queue_node { treemple stmt; + location_t location; gimple_seq repl_stmt; gimple cont_stmt; int index; *************** static void *** 560,566 **** record_in_goto_queue (struct leh_tf_state *tf, treemple new_stmt, int index, ! bool is_label) { size_t active, size; struct goto_queue_node *q; --- 561,568 ---- record_in_goto_queue (struct leh_tf_state *tf, treemple new_stmt, int index, ! bool is_label, ! location_t location) { size_t active, size; struct goto_queue_node *q; *************** record_in_goto_queue (struct leh_tf_stat *** 583,588 **** --- 585,591 ---- memset (q, 0, sizeof (*q)); q->stmt = new_stmt; q->index = index; + q->location = location; q->is_label = is_label; } *************** record_in_goto_queue (struct leh_tf_stat *** 590,596 **** TF is not null. */ static void ! record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt, tree label) { int index; treemple temp, new_stmt; --- 593,600 ---- TF is not null. */ static void ! record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt, tree label, ! location_t location) { int index; treemple temp, new_stmt; *************** record_in_goto_queue_label (struct leh_t *** 629,635 **** since with a GIMPLE_COND we have an easy access to the then/else labels. */ new_stmt = stmt; ! record_in_goto_queue (tf, new_stmt, index, true); } /* For any GIMPLE_GOTO or GIMPLE_RETURN, decide whether it leaves a try_finally --- 633,639 ---- since with a GIMPLE_COND we have an easy access to the then/else labels. */ new_stmt = stmt; ! record_in_goto_queue (tf, new_stmt, index, true, location); } /* For any GIMPLE_GOTO or GIMPLE_RETURN, decide whether it leaves a try_finally *************** maybe_record_in_goto_queue (struct leh_s *** 649,667 **** { case GIMPLE_COND: new_stmt.tp = gimple_op_ptr (stmt, 2); ! record_in_goto_queue_label (tf, new_stmt, gimple_cond_true_label (stmt)); new_stmt.tp = gimple_op_ptr (stmt, 3); ! record_in_goto_queue_label (tf, new_stmt, gimple_cond_false_label (stmt)); break; case GIMPLE_GOTO: new_stmt.g = stmt; ! record_in_goto_queue_label (tf, new_stmt, gimple_goto_dest (stmt)); break; case GIMPLE_RETURN: tf->may_return = true; new_stmt.g = stmt; ! record_in_goto_queue (tf, new_stmt, -1, false); break; default: --- 653,674 ---- { case GIMPLE_COND: new_stmt.tp = gimple_op_ptr (stmt, 2); ! record_in_goto_queue_label (tf, new_stmt, gimple_cond_true_label (stmt), ! EXPR_LOCATION (*new_stmt.tp)); new_stmt.tp = gimple_op_ptr (stmt, 3); ! record_in_goto_queue_label (tf, new_stmt, gimple_cond_false_label (stmt), ! EXPR_LOCATION (*new_stmt.tp)); break; case GIMPLE_GOTO: new_stmt.g = stmt; ! record_in_goto_queue_label (tf, new_stmt, gimple_goto_dest (stmt), ! gimple_location (stmt)); break; case GIMPLE_RETURN: tf->may_return = true; new_stmt.g = stmt; ! record_in_goto_queue (tf, new_stmt, -1, false, gimple_location (stmt)); break; default: *************** frob_into_branch_around (gimple tp, eh_r *** 866,878 **** Make sure to record all new labels found. */ static gimple_seq ! lower_try_finally_dup_block (gimple_seq seq, struct leh_state *outer_state) { gimple region = NULL; gimple_seq new_seq; new_seq = copy_gimple_seq_and_replace_locals (seq); if (outer_state->tf) region = outer_state->tf->try_finally_expr; collect_finally_tree_1 (new_seq, region); --- 873,891 ---- Make sure to record all new labels found. */ static gimple_seq ! lower_try_finally_dup_block (gimple_seq seq, struct leh_state *outer_state, ! location_t loc) { gimple region = NULL; gimple_seq new_seq; + gimple_stmt_iterator gsi; new_seq = copy_gimple_seq_and_replace_locals (seq); + for (gsi = gsi_start (new_seq); !gsi_end_p (gsi); gsi_next (&gsi)) + if (gimple_location (gsi_stmt (gsi)) == UNKNOWN_LOCATION) + gimple_set_location (gsi_stmt (gsi), loc); + if (outer_state->tf) region = outer_state->tf->try_finally_expr; collect_finally_tree_1 (new_seq, region); *************** honor_protect_cleanup_actions (struct le *** 967,973 **** gimple_try_set_cleanup (tf->top_p, gimple_eh_else_n_body (eh_else)); } else if (this_state) ! finally = lower_try_finally_dup_block (finally, outer_state); finally_may_fallthru = gimple_seq_may_fallthru (finally); /* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP --- 980,987 ---- gimple_try_set_cleanup (tf->top_p, gimple_eh_else_n_body (eh_else)); } else if (this_state) ! finally = lower_try_finally_dup_block (finally, outer_state, ! UNKNOWN_LOCATION); finally_may_fallthru = gimple_seq_may_fallthru (finally); /* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP *************** lower_try_finally_copy (struct leh_state *** 1184,1190 **** if (tf->may_fallthru) { ! seq = lower_try_finally_dup_block (finally, state); lower_eh_constructs_1 (state, &seq); gimple_seq_add_seq (&new_stmt, seq); --- 1198,1204 ---- if (tf->may_fallthru) { ! seq = lower_try_finally_dup_block (finally, state, tf_loc); lower_eh_constructs_1 (state, &seq); gimple_seq_add_seq (&new_stmt, seq); *************** lower_try_finally_copy (struct leh_state *** 1200,1206 **** if (eh_else) seq = gimple_eh_else_e_body (eh_else); else ! seq = lower_try_finally_dup_block (finally, state); lower_eh_constructs_1 (state, &seq); emit_post_landing_pad (&eh_seq, tf->region); --- 1214,1220 ---- if (eh_else) seq = gimple_eh_else_e_body (eh_else); else ! seq = lower_try_finally_dup_block (finally, state, tf_loc); lower_eh_constructs_1 (state, &seq); emit_post_landing_pad (&eh_seq, tf->region); *************** lower_try_finally_copy (struct leh_state *** 1250,1256 **** x = gimple_build_label (lab); gimple_seq_add_stmt (&new_stmt, x); ! seq = lower_try_finally_dup_block (finally, state); lower_eh_constructs_1 (state, &seq); gimple_seq_add_seq (&new_stmt, seq); --- 1264,1270 ---- x = gimple_build_label (lab); gimple_seq_add_stmt (&new_stmt, x); ! seq = lower_try_finally_dup_block (finally, state, q->location); lower_eh_constructs_1 (state, &seq); gimple_seq_add_seq (&new_stmt, seq); Index: gcc/gimplify.c =================================================================== *** gcc/gimplify.c (revision 190209) --- gcc/gimplify.c (working copy) *************** gimplify_expr (tree *expr_p, gimple_seq *** 7434,7439 **** --- 7434,7447 ---- gimple_seq eval, cleanup; gimple try_; + /* For call expressions inside FINALL/CATCH block, if its location + is unknown, gimplify_call_expr will set it to input_location. + However, these calls are automatically generated to destructors. + And they may be cloned to many places. In this case, we will + set the location for them in tree-eh.c. But to ensure that EH + does the right job, we first need mark their location as + UNKNOWN_LOCATION. */ + input_location = UNKNOWN_LOCATION; eval = cleanup = NULL; gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval); gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);