From 16865eaaa8898e0ea0e87e8516a17d5f95ab471b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 16 Jun 2004 16:05:37 -0700 Subject: [PATCH] c-parse.in (if_stmt_locus): Remove. * c-parse.in (if_stmt_locus): Remove. (if_prefix): Increment stmt_count; pass it to c_finish_if_cond. (select_or_iter_stmt): Move empty if warnings to c-typeck.c. * c-typeck.c (if_elt): Sort by expected size. Rename locus to empty_locus. Add stmt_count, saw_else. (c_begin_if_stmt): Push if_stack here. (c_finish_if_cond): Rename from c_expand_end_cond. Record stmt_count. (c_finish_then, c_finish_else): Record empty_locus. (c_begin_else): Rename from c_expand_start_else. Record stmt_count. (c_finish_if_stmt): Rename from c_expand_end_cond. Warn for empty if or else body. * c-tree.h: Update prototypes. testsuite/ * gcc.dg/20001116-1.c: Move expected warning line. From-SVN: r83274 --- gcc/ChangeLog | 15 +++++ gcc/c-parse.in | 62 ++++++--------------- gcc/c-tree.h | 8 +-- gcc/c-typeck.c | 92 ++++++++++++++++++------------- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/20001116-1.c | 4 +- 6 files changed, 96 insertions(+), 89 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7745ee927eb..50bfa931162 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2004-06-16 Richard Henderson + + * c-parse.in (if_stmt_locus): Remove. + (if_prefix): Increment stmt_count; pass it to c_finish_if_cond. + (select_or_iter_stmt): Move empty if warnings to c-typeck.c. + * c-typeck.c (if_elt): Sort by expected size. Rename locus to + empty_locus. Add stmt_count, saw_else. + (c_begin_if_stmt): Push if_stack here. + (c_finish_if_cond): Rename from c_expand_end_cond. Record stmt_count. + (c_finish_then, c_finish_else): Record empty_locus. + (c_begin_else): Rename from c_expand_start_else. Record stmt_count. + (c_finish_if_stmt): Rename from c_expand_end_cond. Warn for empty + if or else body. + * c-tree.h: Update prototypes. + 2004-06-16 Steven Bosscher * tree.h (PHI_CHAIN): New. diff --git a/gcc/c-parse.in b/gcc/c-parse.in index 147dbc009f4..8b8f6db86e3 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -259,11 +259,6 @@ do { \ static int stmt_count; static int compstmt_count; -/* Input location of the end of the body of last simple_if; - used by the stmt-rule immediately after simple_if returns. */ -static location_t if_stmt_locus; - - /* List of types and structure classes of the current declaration. */ static GTY(()) tree current_declspecs; static GTY(()) tree prefix_attributes; @@ -2068,34 +2063,25 @@ compstmt: compstmt_start compstmt_nostart $$ = NULL_TREE; } ; -/* Value is number of statements counted as of the closeparen. */ -simple_if: - if_prefix c99_block_lineno_labeled_stmt - { c_finish_then ($2); } -/* Make sure c_expand_end_cond is run once - for each call to c_expand_start_cond. - Otherwise a crash is likely. */ - | if_prefix error - ; - if_prefix: - /* We must build the IF_STMT node before parsing its - condition so that EXPR_LOCUS refers to the line - containing the "if", and not the line containing - the close-parenthesis. - - c_begin_if_stmt returns the IF_STMT node, which - we later pass to c_expand_start_cond to fill - in the condition and other tidbits. */ + /* We must build the if statement node before parsing its + condition so that we get its location pointing to the + line containing the "if", and not the line containing + the close-parenthesis. */ IF { $$ = c_begin_if_stmt (); } '(' expr ')' - { c_expand_start_cond (lang_hooks.truthvalue_conversion ($4), - compstmt_count,$2); - $$ = stmt_count; - if_stmt_locus = $-1; } + { c_finish_if_cond ($4, compstmt_count, ++stmt_count); } ; +simple_if: + if_prefix c99_block_lineno_labeled_stmt + { c_finish_then ($2); } + /* Make sure c_finish_if_stmt is run for each call to + c_begin_if_stmt. Otherwise a crash is likely. */ + | if_prefix error + ; + /* This is a subroutine of stmt. It is used twice, once for valid DO statements and once for catching errors in parsing the end test. */ @@ -2172,27 +2158,13 @@ lineno_label: select_or_iter_stmt: simple_if ELSE - { c_expand_start_else (); - $1 = stmt_count; } + { c_begin_else (stmt_count); } c99_block_lineno_labeled_stmt - { c_finish_else ($4); - c_expand_end_cond (); - if (extra_warnings && stmt_count == $1) - warning ("empty body in an else-statement"); } + { c_finish_else ($4); c_finish_if_stmt (stmt_count); } | simple_if %prec IF - { c_expand_end_cond (); - /* This warning is here instead of in simple_if, because we - do not want a warning if an empty if is followed by an - else statement. Increment stmt_count so we don't - give a second error if this is a nested `if'. */ - if (extra_warnings && stmt_count++ == $1) - warning ("%Hempty body in an if-statement", - &if_stmt_locus); } -/* Make sure c_expand_end_cond is run once - for each call to c_expand_start_cond. - Otherwise a crash is likely. */ + { c_finish_if_stmt (stmt_count); } | simple_if ELSE error - { c_expand_end_cond (); } + { c_finish_if_stmt (stmt_count + 1); } /* We must build the WHILE_STMT node before parsing its condition so that EXPR_LOCUS refers to the line containing the "while", and not the line containing diff --git a/gcc/c-tree.h b/gcc/c-tree.h index b311bb3e205..031883e95fb 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -256,12 +256,12 @@ extern tree c_convert_parm_for_inlining (tree, tree, tree, int); extern int c_types_compatible_p (tree, tree); extern tree c_begin_compound_stmt (bool); extern tree c_end_compound_stmt (tree, bool); -extern void c_expand_start_cond (tree, int, tree); +extern tree c_begin_if_stmt (void); +extern void c_finish_if_cond (tree, int, int); extern void c_finish_then (tree); -extern void c_expand_start_else (void); +extern void c_begin_else (int); extern void c_finish_else (tree); -extern void c_expand_end_cond (void); -extern tree c_begin_if_stmt (void); +extern void c_finish_if_stmt (int); extern tree c_begin_while_stmt (void); extern void c_finish_while_stmt_cond (tree, tree); extern void c_finish_while_stmt (tree, tree); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 32bf24a4193..7433c51a62e 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -6467,10 +6467,12 @@ c_finish_case (tree body) the enclosing if statement does not have an else branch. */ typedef struct { - int compstmt_count; - location_t locus; - int needs_warning; tree if_stmt; + location_t empty_locus; + int compstmt_count; + int stmt_count; + unsigned int needs_warning : 1; + unsigned int saw_else : 1; } if_elt; static if_elt *if_stack; @@ -6488,22 +6490,8 @@ tree c_begin_if_stmt (void) { tree r; - r = add_stmt (build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE)); - return r; -} - -/* Record the start of an if-then, and record the start of it - for ambiguous else detection. - - COND is the condition for the if-then statement. + if_elt *elt; - IF_STMT is the statement node that has already been created for - this if-then statement. It is created before parsing the - condition to keep line number information accurate. */ - -void -c_expand_start_cond (tree cond, int compstmt_count, tree if_stmt) -{ /* Make sure there is enough space on the stack. */ if (if_stack_space == 0) { @@ -6516,42 +6504,47 @@ c_expand_start_cond (tree cond, int compstmt_count, tree if_stmt) if_stack = xrealloc (if_stack, if_stack_space * sizeof (if_elt)); } - IF_COND (if_stmt) = cond; + r = add_stmt (build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE)); /* Record this if statement. */ - if_stack[if_stack_pointer].compstmt_count = compstmt_count; - if_stack[if_stack_pointer].locus = input_location; - if_stack[if_stack_pointer].needs_warning = 0; - if_stack[if_stack_pointer].if_stmt = if_stmt; - if_stack_pointer++; + elt = &if_stack[if_stack_pointer++]; + memset (elt, 0, sizeof (*elt)); + elt->if_stmt = r; } -/* Called after the then-clause for an if-statement is processed. */ +/* Record the start of an if-then, and record the start of it + for ambiguous else detection. + + COND is the condition for the if-then statement. + + IF_STMT is the statement node that has already been created for + this if-then statement. It is created before parsing the + condition to keep line number information accurate. */ void -c_finish_then (tree then_stmt) +c_finish_if_cond (tree cond, int compstmt_count, int stmt_count) { - tree if_stmt = if_stack[if_stack_pointer - 1].if_stmt; - THEN_CLAUSE (if_stmt) = then_stmt; + if_elt *elt = &if_stack[if_stack_pointer - 1]; + elt->compstmt_count = compstmt_count; + elt->stmt_count = stmt_count; + IF_COND (elt->if_stmt) = lang_hooks.truthvalue_conversion (cond); } -/* Record the end of an if-then. Optionally warn if a nested - if statement had an ambiguous else clause. */ +/* Called after the then-clause for an if-statement is processed. */ void -c_expand_end_cond (void) +c_finish_then (tree then_stmt) { - if_stack_pointer--; - if (if_stack[if_stack_pointer].needs_warning) - warning ("%Hsuggest explicit braces to avoid ambiguous `else'", - &if_stack[if_stack_pointer].locus); + if_elt *elt = &if_stack[if_stack_pointer - 1]; + THEN_CLAUSE (elt->if_stmt) = then_stmt; + elt->empty_locus = input_location; } /* Called between the then-clause and the else-clause of an if-then-else. */ void -c_expand_start_else (void) +c_begin_else (int stmt_count) { /* An ambiguous else warning must be generated for the enclosing if statement, unless we see an else branch for that one, too. */ @@ -6566,6 +6559,7 @@ c_expand_start_else (void) case. Also don't warn for any if statements nested in this else. */ if_stack[if_stack_pointer - 1].needs_warning = 0; if_stack[if_stack_pointer - 1].compstmt_count--; + if_stack[if_stack_pointer - 1].saw_else = 1; } /* Called after the else-clause for an if-statement is processed. */ @@ -6573,8 +6567,30 @@ c_expand_start_else (void) void c_finish_else (tree else_stmt) { - tree if_stmt = if_stack[if_stack_pointer - 1].if_stmt; - ELSE_CLAUSE (if_stmt) = else_stmt; + if_elt *elt = &if_stack[if_stack_pointer - 1]; + ELSE_CLAUSE (elt->if_stmt) = else_stmt; + elt->empty_locus = input_location; +} + +/* Record the end of an if-then. Optionally warn if a nested + if statement had an ambiguous else clause. */ + +void +c_finish_if_stmt (int stmt_count) +{ + if_elt *elt = &if_stack[--if_stack_pointer]; + + if (elt->needs_warning) + warning ("%Hsuggest explicit braces to avoid ambiguous `else'", + EXPR_LOCUS (elt->if_stmt)); + + if (extra_warnings && stmt_count == elt->stmt_count) + { + if (elt->saw_else) + warning ("%Hempty body in an else-statement", &elt->empty_locus); + else + warning ("%Hempty body in an if-statement", &elt->empty_locus); + } } /* Begin a while statement. Returns a newly created WHILE_STMT if diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bee3c1ed0d6..286cbb60575 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-06-15 Richard Henderson + + * gcc.dg/20001116-1.c: Move expected warning line. + 2004-06-15 Richard Henderson * gcc.dg/i386-ssetype-1.c: Remove XFAIL. diff --git a/gcc/testsuite/gcc.dg/20001116-1.c b/gcc/testsuite/gcc.dg/20001116-1.c index 5833dd8b161..155cfe63962 100644 --- a/gcc/testsuite/gcc.dg/20001116-1.c +++ b/gcc/testsuite/gcc.dg/20001116-1.c @@ -6,6 +6,6 @@ void foo (int x) { - if (x) /* { dg-warning "empty body in an if-statement" } */ - ; + if (x) + ; /* { dg-warning "empty body in an if-statement" } */ } -- 2.30.2