This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: egcs-980129, fixed ambiguous `else' warnings in the gcc/f/ dir.


> 
> 	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 ();
  }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]