This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: egcs-980129, fixed ambiguous `else' warnings in the gcc/f/ dir.
- To: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- Subject: Re: egcs-980129, fixed ambiguous `else' warnings in the gcc/f/ dir.
- From: Bernd Schmidt <crux at pool dot informatik dot rwth-aachen dot de>
- Date: Mon, 16 Feb 1998 13:57:25 +0100 (MET)
- cc: egcs at cygnus dot com, rth at cygnus dot com
>
> Lot's of gcc's warnings emit diagnostics about things that are
> coding style issues, not actual problems.
>
> So given that the GNU coding standards mention this particular
> case, perhaps whatever fix you decide on should simply change the
> wording but still say something even when an if-then-else tree is full.
> I recommend "Suggest braces around nested if-then-else." or something
> similar.
I'm including a patch that changes the behaviour, and a small testcase that
shows which constructs are warned about and which aren't.
Personally, I find the old behaviour more useful, but whatever solution
people agree upon is fine with me.
Bernd
-- test case
static int foo, bar, baz;
void a () {}
void b () {}
void warnings ()
{
int i;
if (foo)
if (bar)
a ();
else
b ();
if (foo)
for (i = 0; i < 10; i++)
if (bar)
a ();
else
b ();
if (foo)
while (foo)
if (bar)
a ();
else
b ();
}
void no_warnings ()
{
if (foo)
{
if (bar)
a ();
else
b ();
}
if (foo)
a ();
else if (bar)
b ();
else if (baz)
a ();
if (foo)
do
if (bar)
a ();
else
b ();
while (foo);
if (foo)
if (bar)
a ();
else
b ();
else
b ();
}
-- patch
* c-common.c (c_expand_start_cond, c_expand_end_cond,
c_expand_start_else): Don't warn about non-ambiguous else even if
braces are missing.
*** c-common.c 1998/02/05 15:47:17 1.1.3.2
--- c-common.c 1998/02/13 15:45:10
*************** static void add_attribute PROTO((enum a
*** 51,59 ****
static void init_attributes PROTO((void));
static void record_international_format PROTO((tree, tree, int));
! /* Keep a stack of if statements. The value recorded is the number of
! compound statements seen up to the if keyword. */
! static int *if_stack;
/* Amount of space in the if statement stack. */
static int if_stack_space = 0;
--- 51,70 ----
static void init_attributes PROTO((void));
static void record_international_format PROTO((tree, tree, int));
! /* Keep a stack of if statements. We record the number of compound
! statements seen up to the if keyword, as well as the line number
! and file of the if. If a potentially ambiguous else is seen, that
! fact is recorded; the warning is issued when we can be sure that
! the enclosing if statement does not have an else branch. */
! typedef struct
! {
! int compstmt_count;
! int line;
! char *file;
! int needs_warning;
! } if_elt;
!
! static if_elt *if_stack;
/* Amount of space in the if statement stack. */
static int if_stack_space = 0;
*************** static int if_stack_space = 0;
*** 61,66 ****
--- 72,80 ----
/* Stack pointer. */
static int if_stack_pointer = 0;
+ /* Generate RTL for the start of an if-then, and record the start of it
+ for ambiguous else detection. */
+
void
c_expand_start_cond (cond, exitflag, compstmt_count)
tree cond;
*************** c_expand_start_cond (cond, exitflag, com
*** 71,107 ****
if (if_stack_space == 0)
{
if_stack_space = 10;
! if_stack = (int *)xmalloc (10 * sizeof (int));
}
else if (if_stack_space == if_stack_pointer)
{
if_stack_space += 10;
! if_stack = (int *)xrealloc (if_stack, if_stack_space * sizeof (int));
}
!
/* Record this if statement. */
! if_stack[if_stack_pointer++] = compstmt_count;
expand_start_cond (cond, exitflag);
}
void
c_expand_end_cond ()
{
if_stack_pointer--;
expand_end_cond ();
}
void
c_expand_start_else ()
{
if (warn_parentheses
&& if_stack_pointer > 1
! && if_stack[if_stack_pointer - 1] == if_stack[if_stack_pointer - 2])
! warning ("suggest explicit braces to avoid ambiguous `else'");
!
! /* This if statement can no longer cause a dangling else. */
! if_stack[if_stack_pointer - 1]--;
expand_start_else ();
}
--- 85,141 ----
if (if_stack_space == 0)
{
if_stack_space = 10;
! if_stack = (if_elt *)xmalloc (10 * sizeof (if_elt));
}
else if (if_stack_space == if_stack_pointer)
{
if_stack_space += 10;
! if_stack = (if_elt *)xrealloc (if_stack, if_stack_space * sizeof (if_elt));
}
!
/* Record this if statement. */
! if_stack[if_stack_pointer].compstmt_count = compstmt_count;
! if_stack[if_stack_pointer].file = input_filename;
! if_stack[if_stack_pointer].line = lineno;
! if_stack[if_stack_pointer].needs_warning = 0;
! if_stack_pointer++;
expand_start_cond (cond, exitflag);
}
+ /* Generate RTL for the end of an if-then. Optionally warn if a nested
+ if statement had an ambiguous else clause. */
+
void
c_expand_end_cond ()
{
if_stack_pointer--;
+ if (if_stack[if_stack_pointer].needs_warning)
+ warning_with_file_and_line (if_stack[if_stack_pointer].file,
+ if_stack[if_stack_pointer].line,
+ "suggest explicit braces to avoid ambiguous `else'");
expand_end_cond ();
}
+ /* Generate RTL between the then-clause and the else-clause
+ of an if-then-else. */
+
void
c_expand_start_else ()
{
+ /* An ambiguous else warning must be generated for the enclosing if
+ statement, unless we see an else branch for that one, too. */
if (warn_parentheses
&& if_stack_pointer > 1
! && (if_stack[if_stack_pointer - 1].compstmt_count
! == if_stack[if_stack_pointer - 2].compstmt_count))
! if_stack[if_stack_pointer - 2].needs_warning = 1;
!
! /* Even if a nested if statement had an else branch, it can't be
! ambiguous if this one also has an else. So don't warn in that
! 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--;
expand_start_else ();
}