* [PR debug/67192] Fix C loops' back-jump location
@ 2015-10-12 14:04 Andreas Arnez
2015-10-13 12:37 ` Bernd Schmidt
0 siblings, 1 reply; 3+ messages in thread
From: Andreas Arnez @ 2015-10-12 14:04 UTC (permalink / raw)
To: Joseph Myers, Richard Henderson
Cc: gcc-patches, David Malcolm, Manuel López-Ibáñez,
Patrick Palka, Andreas Krebbel
Since r223098 ("Implement -Wmisleading-indentation") the backward-jump
generated for a C while- or for-loop can get the wrong line number.
This is because the check for misleading indentation peeks ahead one
token, advancing input_location to after the loop, and then
c_finish_loop() creates the back-jump and calls add_stmt(), which
assigns input_location to the statement by default.
This patch swaps the check for misleading indentation with the finishing
of the loop, such that input_location still has the right value at the
time of any invocations of add_stmt().
gcc/testsuite/ChangeLog:
PR debug/67192
* gcc.dg/guality/pr67192.c: New test.
gcc/c/ChangeLog:
PR debug/67192
* c-parser.c (c_parser_while_statement): Finish the loop before
parsing ahead for misleading indentation.
(c_parser_for_statement): Likewise.
---
gcc/c/c-parser.c | 13 +++++----
gcc/testsuite/gcc.dg/guality/pr67192.c | 50 ++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/guality/pr67192.c
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 2d24c21..8740922 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -5438,13 +5438,13 @@ c_parser_while_statement (c_parser *parser, bool ivdep)
= get_token_indent_info (c_parser_peek_token (parser));
body = c_parser_c99_block_statement (parser);
+ c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, true);
+ add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
token_indent_info next_tinfo
= get_token_indent_info (c_parser_peek_token (parser));
warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
- c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, true);
- add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
c_break_label = save_break;
c_cont_label = save_cont;
}
@@ -5728,15 +5728,16 @@ c_parser_for_statement (c_parser *parser, bool ivdep)
body = c_parser_c99_block_statement (parser);
- token_indent_info next_tinfo
- = get_token_indent_info (c_parser_peek_token (parser));
- warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
-
if (is_foreach_statement)
objc_finish_foreach_loop (loc, object_expression, collection_expression, body, c_break_label, c_cont_label);
else
c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label, true);
add_stmt (c_end_compound_stmt (loc, block, flag_isoc99 || c_dialect_objc ()));
+
+ token_indent_info next_tinfo
+ = get_token_indent_info (c_parser_peek_token (parser));
+ warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
+
c_break_label = save_break;
c_cont_label = save_cont;
}
diff --git a/gcc/testsuite/gcc.dg/guality/pr67192.c b/gcc/testsuite/gcc.dg/guality/pr67192.c
new file mode 100644
index 0000000..73d4e44
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr67192.c
@@ -0,0 +1,50 @@
+/* PR debug/67192 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+static volatile int cnt = 0;
+
+__attribute__((noinline)) int
+f1 (void)
+{
+ return ++cnt % 5 == 0;
+}
+
+__attribute__((noinline)) void
+f2 (void)
+{
+}
+
+__attribute__((noinline)) void
+f3 (int (*last) (void), void (*do_it) (void))
+{
+ for (;;)
+ {
+ if (last ())
+ break;
+ do_it ();
+ }
+ do_it (); /* { dg-final { gdb-test 27 "cnt" "5" } } */
+
+ while (1)
+ {
+ if (last ())
+ break;
+ do_it ();
+ }
+ do_it (); /* { dg-final { gdb-test 35 "cnt" "10" } } */
+}
+
+int (*volatile fnp1) (void) = f1;
+void (*volatile fnp2) (void) = f2;
+void (*volatile fnp3) (int (*) (void), void (*) (void)) = f3;
+
+int
+main (int argc, char *argv[])
+{
+ asm volatile ("" : : "r" (&fnp1) : "memory");
+ asm volatile ("" : : "r" (&fnp2) : "memory");
+ asm volatile ("" : : "r" (&fnp3) : "memory");
+ fnp3 (fnp1, fnp2);
+ return 0;
+}
--
2.3.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PR debug/67192] Fix C loops' back-jump location
2015-10-12 14:04 [PR debug/67192] Fix C loops' back-jump location Andreas Arnez
@ 2015-10-13 12:37 ` Bernd Schmidt
2015-10-23 9:10 ` Andreas Arnez
0 siblings, 1 reply; 3+ messages in thread
From: Bernd Schmidt @ 2015-10-13 12:37 UTC (permalink / raw)
To: Andreas Arnez, Joseph Myers, Richard Henderson
Cc: gcc-patches, David Malcolm, Manuel López-Ibáñez,
Patrick Palka, Andreas Krebbel
On 10/12/2015 04:04 PM, Andreas Arnez wrote:
> Since r223098 ("Implement -Wmisleading-indentation") the backward-jump
> generated for a C while- or for-loop can get the wrong line number.
> This is because the check for misleading indentation peeks ahead one
> token, advancing input_location to after the loop, and then
> c_finish_loop() creates the back-jump and calls add_stmt(), which
> assigns input_location to the statement by default.
>
> This patch swaps the check for misleading indentation with the finishing
> of the loop, such that input_location still has the right value at the
> time of any invocations of add_stmt().
One could argue that peek_token should not have an effect on
input_location, and in fact cpp_peek_token seems to take steps that this
does not happen, but it looks like c_parser_peek_token does not use that
mechanism. Still,
>
> gcc/testsuite/ChangeLog:
>
> PR debug/67192
> * gcc.dg/guality/pr67192.c: New test.
>
> gcc/c/ChangeLog:
>
> PR debug/67192
> * c-parser.c (c_parser_while_statement): Finish the loop before
> parsing ahead for misleading indentation.
> (c_parser_for_statement): Likewise.
This fix looks simple enough. Ok. (Might want to add noclone to the
testcase attributes).
Bernd
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PR debug/67192] Fix C loops' back-jump location
2015-10-13 12:37 ` Bernd Schmidt
@ 2015-10-23 9:10 ` Andreas Arnez
0 siblings, 0 replies; 3+ messages in thread
From: Andreas Arnez @ 2015-10-23 9:10 UTC (permalink / raw)
To: Bernd Schmidt
Cc: Joseph Myers, Richard Henderson, gcc-patches, David Malcolm,
Manuel López-Ibáñez, Patrick Palka,
Andreas Krebbel
On Tue, Oct 13 2015, Bernd Schmidt wrote:
> One could argue that peek_token should not have an effect on
> input_location, and in fact cpp_peek_token seems to take steps that
> this does not happen, but it looks like c_parser_peek_token does not
> use that mechanism.
Yes, the C/C++ parsers differ quite significantly in this regard. The C
parser invokes the lexer in peek_token and advances input_location upon
each newline. The C++ parser usually lexes everything in advance and
updates input_location on each *consumed* token.
By advancing input_location in peek_token upon each newline, diagnostics
emitted with warning() and friends point to the beginning of the line of
the peeked-at token. This is probably somewhat intended, so I'd rather
not touch that right now.
A different aspect is the implicit use of input_location for the
location of generated statements. This usage is what causes the problem
at hand, and IMHO it should generally be rooted out.
>> Still,
>>
>> gcc/testsuite/ChangeLog:
>>
>> PR debug/67192
>> * gcc.dg/guality/pr67192.c: New test.
>>
>> gcc/c/ChangeLog:
>>
>> PR debug/67192
>> * c-parser.c (c_parser_while_statement): Finish the loop before
>> parsing ahead for misleading indentation.
>> (c_parser_for_statement): Likewise.
>
> This fix looks simple enough. Ok. (Might want to add noclone to the
> testcase attributes).
Thanks for reviewing! Unfortunately, after investigating this some
more, I realized that my solution is incomplete. E.g., consider this:
while (1)
if (foo ())
break;
else
do_something ();
bar (); /* break here */
Interestingly, line number information for such code has been broken in
GCC for a long time.
I'll send an updated version.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-10-23 9:07 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-12 14:04 [PR debug/67192] Fix C loops' back-jump location Andreas Arnez
2015-10-13 12:37 ` Bernd Schmidt
2015-10-23 9:10 ` Andreas Arnez
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).