+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>
* tree.h (PHI_CHAIN): New.
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;
$$ = 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
{ $<ttype>$ = c_begin_if_stmt (); }
'(' expr ')'
- { c_expand_start_cond (lang_hooks.truthvalue_conversion ($4),
- compstmt_count,$<ttype>2);
- $<itype>$ = stmt_count;
- if_stmt_locus = $<location>-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. */
select_or_iter_stmt:
simple_if ELSE
- { c_expand_start_else ();
- $<itype>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 == $<itype>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++ == $<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. */
+ { 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
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);
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;
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)
{
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. */
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. */
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);
+ }
}
\f
/* Begin a while statement. Returns a newly created WHILE_STMT if
+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.
void foo (int x)
{
- if (x) /* { dg-warning "empty body in an if-statement" } */
- ;
+ if (x)
+ ; /* { dg-warning "empty body in an if-statement" } */
}