This is the mail archive of the gcc-patches@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]
Other format: [Raw text]

PATCH: diagnostic: fix PR c++/19756


Hi, 

I don't quite understand why the implementation in the C frontend is so overly 
complicated, while the simple patch (see below) works as well. 

bootstrapped, regtested on i686-suse-linux. 

Ok for mainline?

Dirk

:ADDPATCH diagnostic:

2006-12-01  Dirk Mueller  <dmueller@suse.de>

        PR c++/19756
        * parser.c (cp_parser_selection_statement): Warn for
        ambiguous if/else constructs.

        * invoke.texi (-Wparentheses): Mark it as partially
        supported for C++.

        * g++.dg/warn/Wparentheses-5.C: New testcase.

--- parser.c	(revision 119391)
+++ parser.c	(working copy)
@@ -6531,9 +6531,13 @@ cp_parser_selection_statement (cp_parser
 
 	if (keyword == RID_IF)
 	  {
+	    bool no_then_braces = false;
 	    /* Add the condition.  */
 	    finish_if_stmt_cond (condition, statement);
 
+	    if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
+	      no_then_braces = true;
+
 	    /* Parse the then-clause.  */
 	    cp_parser_implicitly_scoped_statement (parser);
 	    finish_then_clause (statement);
@@ -6549,6 +6553,24 @@ cp_parser_selection_statement (cp_parser
 		cp_parser_implicitly_scoped_statement (parser);
 		finish_else_clause (statement);
 	      }
+	    else
+	    {
+	      tree inner_then = THEN_CLAUSE (statement);
+
+	      if (warn_parentheses && no_then_braces)
+	        {
+		  if (TREE_CODE (inner_then) == STATEMENT_LIST
+		      && STATEMENT_LIST_TAIL (inner_then))
+		    inner_then = STATEMENT_LIST_TAIL (inner_then)->stmt;
+
+		  if (TREE_CODE (inner_then) == IF_STMT
+		      && ELSE_CLAUSE (inner_then))
+		    warning (OPT_Wparentheses,
+			     "%Hsuggest explicit braces to "
+			     "avoid ambiguous %<else%>",
+			     EXPR_LOCUS (statement));
+		}
+	    }
 
 	    /* Now we're all done with the if-statement.  */
 	    finish_if_stmt (statement);
--- invoke.texi	(revision 119391)
+++ invoke.texi	(working copy)
@@ -2529,9 +2529,8 @@ Warn if a user-supplied include director
 Warn if parentheses are omitted in certain contexts, such
 as when there is an assignment in a context where a truth value
 is expected, or when operators are nested whose precedence people
-often get confused about.  Only the warning for an assignment used as
-a truth value is supported when compiling C++; the other warnings are
-only supported when compiling C@.
+often get confused about.  Some warnings are currently only supported
+when compiling C@, not when compiling C++.
 
 Also warn if a comparison like @samp{x<=y<=z} appears; this is
 equivalent to @samp{(x<=y ? 1 : 0) <= z}, which is a different
--- g++.dg/warn/Wparentheses-5.C	(revision 0)
+++ g++.dg/warn/Wparentheses-5.C	(revision 0)
@@ -0,0 +1,61 @@
+/* Test operation of -Wparentheses.  Warnings for ambiguous else.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+
+/* { dg-do compile } */
+/* { dg-options "-Wparentheses" } */
+
+int foo (int);
+
+int a, b, c;
+
+int
+bar (void)
+{
+  if (a)
+    foo (0);
+  if (b)
+    foo (1);
+  else
+    foo (2);
+  if (c) /* { dg-warning "ambiguous" "correct warning" } */
+    if (a)
+      foo (3);
+    else
+      foo (4);
+  if (a)
+    if (c)
+      foo (5);
+  if (a)
+    if (b) /* { dg-warning "ambiguous" "correct warning" } */
+      if (c)
+	foo (6);
+      else
+	foo (7);
+  if (a) /* { dg-warning "ambiguous" "correct warning" } */
+    if (b)
+      if (c)
+	foo (8);
+      else
+	foo (9);
+    else
+      foo (10);
+  if (a)
+    if (b)
+      if (c)
+	foo (11);
+      else
+	foo (12);
+    else
+      foo (13);
+  else
+    foo (14);
+  if (a) {
+    if (b)
+      if (c)
+	foo (15);
+      else
+	foo (16);
+    else
+      foo (17);
+  }
+}


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