This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: diagnostic: fix PR c++/19756
- From: Dirk Mueller <dmuell at gmx dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 1 Dec 2006 04:25:53 +0100
- Subject: 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);
+ }
+}