Commit 16865eaa by Richard Henderson Committed by Richard Henderson

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
parent 17192884
2004-06-16 Richard Henderson <rth@redhat.com>
* 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 <stevenb@suse.de> 2004-06-16 Steven Bosscher <stevenb@suse.de>
* tree.h (PHI_CHAIN): New. * tree.h (PHI_CHAIN): New.
......
...@@ -259,11 +259,6 @@ do { \ ...@@ -259,11 +259,6 @@ do { \
static int stmt_count; static int stmt_count;
static int compstmt_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. */ /* List of types and structure classes of the current declaration. */
static GTY(()) tree current_declspecs; static GTY(()) tree current_declspecs;
static GTY(()) tree prefix_attributes; static GTY(()) tree prefix_attributes;
...@@ -2068,32 +2063,23 @@ compstmt: compstmt_start compstmt_nostart ...@@ -2068,32 +2063,23 @@ compstmt: compstmt_start compstmt_nostart
$$ = NULL_TREE; } $$ = 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: if_prefix:
/* We must build the IF_STMT node before parsing its /* We must build the if statement node before parsing its
condition so that EXPR_LOCUS refers to the line condition so that we get its location pointing to the
containing the "if", and not the line containing line containing the "if", and not the line containing
the close-parenthesis. 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. */
IF IF
{ $<ttype>$ = c_begin_if_stmt (); } { $<ttype>$ = c_begin_if_stmt (); }
'(' expr ')' '(' expr ')'
{ c_expand_start_cond (lang_hooks.truthvalue_conversion ($4), { c_finish_if_cond ($4, compstmt_count, ++stmt_count); }
compstmt_count,$<ttype>2); ;
$<itype>$ = stmt_count;
if_stmt_locus = $<location>-1; } 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. /* This is a subroutine of stmt.
...@@ -2172,27 +2158,13 @@ lineno_label: ...@@ -2172,27 +2158,13 @@ lineno_label:
select_or_iter_stmt: select_or_iter_stmt:
simple_if ELSE simple_if ELSE
{ c_expand_start_else (); { c_begin_else (stmt_count); }
$<itype>1 = stmt_count; }
c99_block_lineno_labeled_stmt c99_block_lineno_labeled_stmt
{ c_finish_else ($4); { c_finish_else ($4); c_finish_if_stmt (stmt_count); }
c_expand_end_cond ();
if (extra_warnings && stmt_count == $<itype>1)
warning ("empty body in an else-statement"); }
| simple_if %prec IF | simple_if %prec IF
{ c_expand_end_cond (); { c_finish_if_stmt (stmt_count); }
/* 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++ == $<itype>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. */
| simple_if ELSE error | 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 /* We must build the WHILE_STMT node before parsing its
condition so that EXPR_LOCUS refers to the line condition so that EXPR_LOCUS refers to the line
containing the "while", and not the line containing containing the "while", and not the line containing
......
...@@ -256,12 +256,12 @@ extern tree c_convert_parm_for_inlining (tree, tree, tree, int); ...@@ -256,12 +256,12 @@ extern tree c_convert_parm_for_inlining (tree, tree, tree, int);
extern int c_types_compatible_p (tree, tree); extern int c_types_compatible_p (tree, tree);
extern tree c_begin_compound_stmt (bool); extern tree c_begin_compound_stmt (bool);
extern tree c_end_compound_stmt (tree, 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_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_finish_else (tree);
extern void c_expand_end_cond (void); extern void c_finish_if_stmt (int);
extern tree c_begin_if_stmt (void);
extern tree c_begin_while_stmt (void); extern tree c_begin_while_stmt (void);
extern void c_finish_while_stmt_cond (tree, tree); extern void c_finish_while_stmt_cond (tree, tree);
extern void c_finish_while_stmt (tree, tree); extern void c_finish_while_stmt (tree, tree);
......
...@@ -6467,10 +6467,12 @@ c_finish_case (tree body) ...@@ -6467,10 +6467,12 @@ c_finish_case (tree body)
the enclosing if statement does not have an else branch. */ the enclosing if statement does not have an else branch. */
typedef struct typedef struct
{ {
int compstmt_count;
location_t locus;
int needs_warning;
tree if_stmt; 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; } if_elt;
static if_elt *if_stack; static if_elt *if_stack;
...@@ -6488,22 +6490,8 @@ tree ...@@ -6488,22 +6490,8 @@ tree
c_begin_if_stmt (void) c_begin_if_stmt (void)
{ {
tree r; tree r;
r = add_stmt (build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE)); if_elt *elt;
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_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. */ /* Make sure there is enough space on the stack. */
if (if_stack_space == 0) if (if_stack_space == 0)
{ {
...@@ -6516,42 +6504,47 @@ c_expand_start_cond (tree cond, int compstmt_count, tree if_stmt) ...@@ -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_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. */ /* Record this if statement. */
if_stack[if_stack_pointer].compstmt_count = compstmt_count; elt = &if_stack[if_stack_pointer++];
if_stack[if_stack_pointer].locus = input_location; memset (elt, 0, sizeof (*elt));
if_stack[if_stack_pointer].needs_warning = 0; elt->if_stmt = r;
if_stack[if_stack_pointer].if_stmt = if_stmt;
if_stack_pointer++;
} }
/* 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 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; if_elt *elt = &if_stack[if_stack_pointer - 1];
THEN_CLAUSE (if_stmt) = then_stmt; 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 /* Called after the then-clause for an if-statement is processed. */
if statement had an ambiguous else clause. */
void void
c_expand_end_cond (void) c_finish_then (tree then_stmt)
{ {
if_stack_pointer--; if_elt *elt = &if_stack[if_stack_pointer - 1];
if (if_stack[if_stack_pointer].needs_warning) THEN_CLAUSE (elt->if_stmt) = then_stmt;
warning ("%Hsuggest explicit braces to avoid ambiguous `else'", elt->empty_locus = input_location;
&if_stack[if_stack_pointer].locus);
} }
/* Called between the then-clause and the else-clause /* Called between the then-clause and the else-clause
of an if-then-else. */ of an if-then-else. */
void void
c_expand_start_else (void) c_begin_else (int stmt_count)
{ {
/* An ambiguous else warning must be generated for the enclosing if /* An ambiguous else warning must be generated for the enclosing if
statement, unless we see an else branch for that one, too. */ statement, unless we see an else branch for that one, too. */
...@@ -6566,6 +6559,7 @@ c_expand_start_else (void) ...@@ -6566,6 +6559,7 @@ c_expand_start_else (void)
case. Also don't warn for any if statements nested in this else. */ 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].needs_warning = 0;
if_stack[if_stack_pointer - 1].compstmt_count--; 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. */ /* Called after the else-clause for an if-statement is processed. */
...@@ -6573,8 +6567,30 @@ c_expand_start_else (void) ...@@ -6573,8 +6567,30 @@ c_expand_start_else (void)
void void
c_finish_else (tree else_stmt) c_finish_else (tree else_stmt)
{ {
tree if_stmt = if_stack[if_stack_pointer - 1].if_stmt; if_elt *elt = &if_stack[if_stack_pointer - 1];
ELSE_CLAUSE (if_stmt) = else_stmt; 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 /* Begin a while statement. Returns a newly created WHILE_STMT if
......
2004-06-15 Richard Henderson <rth@redhat.com> 2004-06-15 Richard Henderson <rth@redhat.com>
* gcc.dg/20001116-1.c: Move expected warning line.
2004-06-15 Richard Henderson <rth@redhat.com>
* gcc.dg/i386-ssetype-1.c: Remove XFAIL. * gcc.dg/i386-ssetype-1.c: Remove XFAIL.
* gcc.dg/i386-ssetype-3.c: Remove XFAIL. * gcc.dg/i386-ssetype-3.c: Remove XFAIL.
......
...@@ -6,6 +6,6 @@ ...@@ -6,6 +6,6 @@
void foo (int x) void foo (int x)
{ {
if (x) /* { dg-warning "empty body in an if-statement" } */ if (x)
; ; /* { dg-warning "empty body in an if-statement" } */
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment