From patchwork Thu Mar 19 08:49:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2 via Gcc-patches" X-Patchwork-Id: 1258039 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=VHN/RoBK; dkim-atps=neutral Received: from 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 RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48jgZh4xN0z9sPR for ; Thu, 19 Mar 2020 19:49:46 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DA45D385F020; Thu, 19 Mar 2020 08:49:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DA45D385F020 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1584607782; bh=i0+JUXjxr7gIpVT1nNl9KXFFuLQpK57y10fAuOAOxNc=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=VHN/RoBKoWITZhzdPYhVWO3/vGdkhmz313E5XauI/gi//MLtwRUeLOg5kfgH8SDiA pkaI5lVtkPSMA3k0DIJcDKWZF8zQ4Ekw5qlOUCcSponChsug1jKrkq3zlh+mt7k3hP e1OFgH373GO9zHoGFHTGXJIyrAW7Hgc6MeyDhAME= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-74.mimecast.com (us-smtp-delivery-74.mimecast.com [216.205.24.74]) by sourceware.org (Postfix) with ESMTP id 03319385E824 for ; Thu, 19 Mar 2020 08:49:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 03319385E824 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-153-_WQJqMEuM36eMZ7swpubdQ-1; Thu, 19 Mar 2020 04:49:36 -0400 X-MC-Unique: _WQJqMEuM36eMZ7swpubdQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 75476189D6D0; Thu, 19 Mar 2020 08:49:35 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-112-22.ams2.redhat.com [10.36.112.22]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DA1D517B91; Thu, 19 Mar 2020 08:49:31 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id 02J8nPiW029189; Thu, 19 Mar 2020 09:49:25 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id 02J8nNMF029188; Thu, 19 Mar 2020 09:49:23 +0100 Date: Thu, 19 Mar 2020 09:49:23 +0100 To: "Joseph S. Myers" , Marek Polacek Subject: [PATCH] c: Fix up cfun->function_end_locus from the C FE [PR94029] Message-ID: <20200319084923.GN2156@tucnak> MIME-Version: 1.0 User-Agent: Mutt/1.11.3 (2019-02-01) X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-10.2 required=5.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: "Li, Pan2 via Gcc-patches" Reply-To: Jakub Jelinek Cc: gcc-patches@gcc.gnu.org Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi! On the following testcase we ICE because while DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus = c_parser_peek_token (parser)->location; and similarly DECL_SOURCE_LOCATION (fndecl) is set from some token's location, the end is set as: /* Store the end of the function, so that we get good line number info for the epilogue. */ cfun->function_end_locus = input_location; and the thing is that input_location is only very rarely set in the C FE (the primary spot that changes it is the cb_line_change/fe_file_change). Which means, e.g. for pretty much all C functions that are on a single line, function_start_locus column is > than function_end_locus column, and the testcase even has smaller line in function_end_locus because cb_line_change isn't performed while parsing multi-line arguments of a function-like macro. Attached are two possible fixes to achieve what the C++ FE does, in particular that cfun->function_end_locus is the locus of the closing } of the function. The first one updates input_location when we see a closing } of a compound statement (though any, not just the function body) and thus input_location in the finish_function call is what we need. The second instead propagates the location_t from the parsing of the outermost compound statement (the function body) to finish_function. Both patches successfully bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk (which one)? Jakub 2020-03-19 Jakub Jelinek PR gcov-profile/94029 * c-parser.c (c_parser_compound_statement_nostart): Set input_location to the locus of closing CPP_CLOSE_BRACE. * gcc.misc-tests/gcov-pr94029.c: New test. 2020-03-19 Jakub Jelinek PR gcov-profile/94029 * c-tree.h (finish_function): Add location_t argument defaulted to input_location. * c-parser.c (c_parser_compound_statement): Add endlocp argument and set it to the locus of closing } if non-NULL. (c_parser_compound_statement_nostart): Return locus of closing }. (c_parser_parse_rtl_body): Likewise. (c_parser_declaration_or_fndef): Propagate locus of closing } to finish_function. * c-decl.c (finish_function): Add end_loc argument, use it instead of input_location to set function_end_locus. * gcc.misc-tests/gcov-pr94029.c: New test. --- gcc/c/c-tree.h.jj 2020-03-17 22:31:56.586909614 +0100 +++ gcc/c/c-tree.h 2020-03-18 13:54:56.207538538 +0100 @@ -580,7 +580,7 @@ extern bool c_check_switch_jump_warnings location_t, location_t); extern void finish_decl (tree, location_t, tree, tree, tree); extern tree finish_enum (tree, tree, tree); -extern void finish_function (void); +extern void finish_function (location_t = input_location); extern tree finish_struct (location_t, tree, tree, tree, class c_struct_parse_info *); extern tree c_simulate_enum_decl (location_t, const char *, --- gcc/c/c-parser.c.jj 2020-03-18 13:36:22.006021310 +0100 +++ gcc/c/c-parser.c 2020-03-18 13:57:45.576034113 +0100 @@ -1487,8 +1487,8 @@ static struct c_expr c_parser_braced_ini static void c_parser_initelt (c_parser *, struct obstack *); static void c_parser_initval (c_parser *, struct c_expr *, struct obstack *); -static tree c_parser_compound_statement (c_parser *); -static void c_parser_compound_statement_nostart (c_parser *); +static tree c_parser_compound_statement (c_parser *, location_t * = NULL); +static location_t c_parser_compound_statement_nostart (c_parser *); static void c_parser_label (c_parser *); static void c_parser_statement (c_parser *, bool *, location_t * = NULL); static void c_parser_statement_after_labels (c_parser *, bool *, @@ -1583,8 +1583,7 @@ static void c_parser_objc_at_synthesize_ static void c_parser_objc_at_dynamic_declaration (c_parser *); static bool c_parser_objc_diagnose_bad_element_prefix (c_parser *, struct c_declspecs *); - -static void c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass); +static location_t c_parser_parse_rtl_body (c_parser *, char *); /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9). @@ -2472,12 +2471,13 @@ c_parser_declaration_or_fndef (c_parser c_finish_oacc_routine (oacc_routine_data, current_function_decl, true); DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus = c_parser_peek_token (parser)->location; + location_t endloc; /* If the definition was marked with __RTL, use the RTL parser now, consuming the function body. */ if (specs->declspec_il == cdil_rtl) { - c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass); + endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass); /* Normally, store_parm_decls sets next_is_function_body, anticipating a function body. We need a push_scope/pop_scope @@ -2486,7 +2486,7 @@ c_parser_declaration_or_fndef (c_parser push_scope (); pop_scope (); - finish_function (); + finish_function (endloc); return; } /* If the definition was marked with __GIMPLE then parse the @@ -2499,9 +2499,11 @@ c_parser_declaration_or_fndef (c_parser specs->declspec_il, specs->entry_bb_count); in_late_binary_op = saved; + struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl); + endloc = fun->function_start_locus; } else - fnbody = c_parser_compound_statement (parser); + fnbody = c_parser_compound_statement (parser, &endloc); tree fndecl = current_function_decl; if (nested) { @@ -2512,7 +2514,7 @@ c_parser_declaration_or_fndef (c_parser by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */ DECL_STATIC_CHAIN (decl) = 1; add_stmt (fnbody); - finish_function (); + finish_function (endloc); c_pop_function_context (); add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl)); } @@ -2520,7 +2522,7 @@ c_parser_declaration_or_fndef (c_parser { if (fnbody) add_stmt (fnbody); - finish_function (); + finish_function (endloc); } /* Get rid of the empty stmt list for GIMPLE/RTL. */ if (specs->declspec_il != cdil_none) @@ -5599,7 +5601,7 @@ c_parser_initval (c_parser *parser, stru cancellation-point-directive */ static tree -c_parser_compound_statement (c_parser *parser) +c_parser_compound_statement (c_parser *parser, location_t *endlocp) { tree stmt; location_t brace_loc; @@ -5613,7 +5615,9 @@ c_parser_compound_statement (c_parser *p return error_mark_node; } stmt = c_begin_compound_stmt (true); - c_parser_compound_statement_nostart (parser); + location_t end_loc = c_parser_compound_statement_nostart (parser); + if (endlocp) + *endlocp = end_loc; return c_end_compound_stmt (brace_loc, stmt, true); } @@ -5622,7 +5626,7 @@ c_parser_compound_statement (c_parser *p used for parsing both compound statements and statement expressions (which follow different paths to handling the opening). */ -static void +static location_t c_parser_compound_statement_nostart (c_parser *parser) { bool last_stmt = false; @@ -5631,9 +5635,10 @@ c_parser_compound_statement_nostart (c_p location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */ if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) { - add_debug_begin_stmt (c_parser_peek_token (parser)->location); + location_t endloc = c_parser_peek_token (parser)->location; + add_debug_begin_stmt (endloc); c_parser_consume_token (parser); - return; + return endloc; } mark_valid_location_for_stdc_pragma (true); if (c_parser_next_token_is_keyword (parser, RID_LABEL)) @@ -5674,8 +5679,9 @@ c_parser_compound_statement_nostart (c_p { mark_valid_location_for_stdc_pragma (save_valid_for_pragma); c_parser_error (parser, "expected declaration or statement"); + location_t endloc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); - return; + return endloc; } while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE)) { @@ -5773,7 +5779,7 @@ c_parser_compound_statement_nostart (c_p { mark_valid_location_for_stdc_pragma (save_valid_for_pragma); c_parser_error (parser, "expected declaration or statement"); - return; + return c_parser_peek_token (parser)->location; } else if (c_parser_next_token_is_keyword (parser, RID_ELSE)) { @@ -5781,7 +5787,7 @@ c_parser_compound_statement_nostart (c_p { mark_valid_location_for_stdc_pragma (save_valid_for_pragma); error_at (loc, "expected %<}%> before %"); - return; + return c_parser_peek_token (parser)->location; } else { @@ -5804,9 +5810,11 @@ c_parser_compound_statement_nostart (c_p } if (last_label) error_at (label_loc, "label at end of compound statement"); + location_t endloc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); /* Restore the value we started with. */ mark_valid_location_for_stdc_pragma (save_valid_for_pragma); + return endloc; } /* Parse all consecutive labels, possibly preceded by standard @@ -21725,13 +21733,13 @@ c_parse_file (void) Take ownership of START_WITH_PASS, if non-NULL. */ -void +location_t c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass) { if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) { free (start_with_pass); - return; + return c_parser_peek_token (parser)->location; } location_t start_loc = c_parser_peek_token (parser)->location; @@ -21753,7 +21761,7 @@ c_parser_parse_rtl_body (c_parser *parse case CPP_EOF: error_at (start_loc, "no closing brace"); free (start_with_pass); - return; + return c_parser_peek_token (parser)->location; default: break; } @@ -21771,12 +21779,13 @@ c_parser_parse_rtl_body (c_parser *parse if (!read_rtl_function_body_from_file_range (start_loc, end_loc)) { free (start_with_pass); - return; + return end_loc; } /* Run the backend on the cfun created above, transferring ownership of START_WITH_PASS. */ run_rtl_passes (start_with_pass); + return end_loc; } #include "gt-c-c-parser.h" --- gcc/c/c-decl.c.jj 2020-03-17 22:31:56.589909571 +0100 +++ gcc/c/c-decl.c 2020-03-18 13:55:22.560148860 +0100 @@ -9851,7 +9851,7 @@ temp_pop_parm_decls (void) This is called after parsing the body of the function definition. */ void -finish_function (void) +finish_function (location_t end_loc) { tree fndecl = current_function_decl; @@ -9947,7 +9947,7 @@ finish_function (void) /* Store the end of the function, so that we get good line number info for the epilogue. */ - cfun->function_end_locus = input_location; + cfun->function_end_locus = end_loc; /* Finalize the ELF visibility for the function. */ c_determine_visibility (fndecl); --- gcc/testsuite/gcc.misc-tests/gcov-pr94029.c.jj 2020-03-18 13:41:02.192871170 +0100 +++ gcc/testsuite/gcc.misc-tests/gcov-pr94029.c 2020-03-18 13:41:02.192871170 +0100 @@ -0,0 +1,14 @@ +/* PR gcov-profile/94029 */ +/* { dg-options "-ftest-coverage" } */ +/* { dg-do compile } */ + +#define impl_test(name) void test_##name() { } +impl_test(t1 +) impl_test(t2) + +int main() +{ + return 0; +} + +/* { dg-final { run-gcov remove-gcda gcov-pr94029.c } } */ --- gcc/c/c-parser.c.jj 2020-03-18 12:47:20.749483242 +0100 +++ gcc/c/c-parser.c 2020-03-18 13:12:25.182276999 +0100 @@ -5631,7 +5631,9 @@ c_parser_compound_statement_nostart (c_p location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */ if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) { - add_debug_begin_stmt (c_parser_peek_token (parser)->location); + c_token *token = c_parser_peek_token (parser); + add_debug_begin_stmt (token->location); + c_parser_set_source_position_from_token (token); c_parser_consume_token (parser); return; } @@ -5804,6 +5806,7 @@ c_parser_compound_statement_nostart (c_p } if (last_label) error_at (label_loc, "label at end of compound statement"); + c_parser_set_source_position_from_token (c_parser_peek_token (parser)); c_parser_consume_token (parser); /* Restore the value we started with. */ mark_valid_location_for_stdc_pragma (save_valid_for_pragma); --- gcc/testsuite/gcc.misc-tests/gcov-pr94029.c.jj 2020-03-18 13:20:10.371407269 +0100 +++ gcc/testsuite/gcc.misc-tests/gcov-pr94029.c 2020-03-18 13:20:46.736870237 +0100 @@ -0,0 +1,14 @@ +/* PR gcov-profile/94029 */ +/* { dg-options "-ftest-coverage" } */ +/* { dg-do compile } */ + +#define impl_test(name) void test_##name() { } +impl_test(t1 +) impl_test(t2) + +int main() +{ + return 0; +} + +/* { dg-final { run-gcov remove-gcda gcov-pr94029.c } } */