This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH PING] (PR c++/5520) Implement empty-body warning for if() statements
- From: Dirk Mueller <dmueller at suse dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 11 Jan 2006 10:01:45 +0100
- Subject: [PATCH PING] (PR c++/5520) Implement empty-body warning for if() statements
Hi,
This is a rediffed version of
http://gcc.gnu.org/ml/gcc-patches/2005-12/msg01627.html
which has also the C++ code slightly reformatted to follow suggestions made by
Nathan. The C++ part is already acknowledged, only the C Frontend changes
need to be still approved.
Ok for trunk?
:ADDPATCH
2006-01-06 Dirk Mueller <dmueller@suse.com>
PR c++/5520
cp/semantics.c (finish_if_stmt): call empty_body_warning
cp/parser.c (cp_parser_implicitly_scoped_statement):
mark empty statement with a NOP_EXPR
c-common.c (empty_body_warning): split out from..
c-typeck.c (c_finish_if_stmt): .. here
testsuite/g++.dg/warn/empty-body.C: New
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c (revision 109375)
+++ gcc/cp/semantics.c (working copy)
@@ -670,6 +670,7 @@ finish_if_stmt (tree if_stmt)
TREE_CHAIN (if_stmt) = NULL;
add_stmt (do_poplevel (scope));
finish_stmt ();
+ empty_body_warning (THEN_CLAUSE (if_stmt), ELSE_CLAUSE (if_stmt));
}
/* Begin a while-statement. Returns a newly created WHILE_STMT if
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c (revision 109375)
+++ gcc/cp/parser.c (working copy)
@@ -6825,8 +6825,17 @@ cp_parser_implicitly_scoped_statement (c
{
tree statement;
+ /* Mark if () ; with a special NOP_EXPR. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ statement = add_stmt (build_empty_stmt ());
+ }
+ /* if a compound is opened, we simply parse the statement directly. */
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ statement = cp_parser_compound_statement (parser, NULL, false);
/* If the token is not a `{', then we must take special action. */
- if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
+ else
{
/* Create a compound-statement. */
statement = begin_compound_stmt (0);
@@ -6835,9 +6844,6 @@ cp_parser_implicitly_scoped_statement (c
/* Finish the dummy compound-statement. */
finish_compound_stmt (statement);
}
- /* Otherwise, we simply parse the statement directly. */
- else
- statement = cp_parser_compound_statement (parser, NULL, false);
/* Return the statement. */
return statement;
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c (revision 109375)
+++ gcc/c-common.c (working copy)
@@ -994,6 +1029,35 @@ strict_aliasing_warning(tree otype, tree
}
}
+
+/* Print a warning about if (); or if () .. else; constructs
+ via the special empty statement node that we create.
+*/
+
+void
+empty_body_warning (tree inner_then, tree inner_else)
+{
+ if (extra_warnings)
+ {
+ if (TREE_CODE (inner_then) == STATEMENT_LIST
+ && STATEMENT_LIST_TAIL (inner_then))
+ inner_then = STATEMENT_LIST_TAIL (inner_then)->stmt;
+
+ if (inner_else && TREE_CODE (inner_else) == STATEMENT_LIST
+ && STATEMENT_LIST_TAIL (inner_else))
+ inner_else = STATEMENT_LIST_TAIL (inner_else)->stmt;
+
+ if (IS_EMPTY_STMT (inner_then) && !inner_else)
+ warning (OPT_Wextra, "%Hempty body in an if-statement",
+ EXPR_LOCUS (inner_then));
+
+ if (inner_else && IS_EMPTY_STMT (inner_else))
+ warning (OPT_Wextra, "%Hempty body in an else-statement",
+ EXPR_LOCUS (inner_else));
+ }
+}
+
+
/* Nonzero if constant C has a value that is permissible
for type TYPE (an INTEGER_TYPE). */
Index: gcc/c-common.h
===================================================================
--- gcc/c-common.h (revision 109375)
+++ gcc/c-common.h (working copy)
@@ -651,6 +651,7 @@ extern tree fix_string_type (tree);
struct varray_head_tag;
extern void constant_expression_warning (tree);
extern void strict_aliasing_warning(tree, tree, tree);
+extern void empty_body_warning (tree, tree);
extern tree convert_and_check (tree, tree);
extern void overflow_warning (tree);
extern void unsigned_conversion_warning (tree, tree);
--- c-typeck.c (revision 109375)
+++ c-typeck.c (working copy)
@@ -7170,36 +7142,7 @@ c_finish_if_stmt (location_t if_locus, t
&if_locus);
}
- /* Diagnose ";" via the special empty statement node that we create. */
- if (extra_warnings)
- {
- tree *inner_then = &then_block, *inner_else = &else_block;
-
- if (TREE_CODE (*inner_then) == STATEMENT_LIST
- && STATEMENT_LIST_TAIL (*inner_then))
- inner_then = &STATEMENT_LIST_TAIL (*inner_then)->stmt;
- if (*inner_else && TREE_CODE (*inner_else) == STATEMENT_LIST
- && STATEMENT_LIST_TAIL (*inner_else))
- inner_else = &STATEMENT_LIST_TAIL (*inner_else)->stmt;
-
- if (TREE_CODE (*inner_then) == NOP_EXPR && !TREE_TYPE (*inner_then))
- {
- if (!*inner_else)
- warning (0, "%Hempty body in an if-statement",
- EXPR_LOCUS (*inner_then));
-
- *inner_then = alloc_stmt_list ();
- }
- if (*inner_else
- && TREE_CODE (*inner_else) == NOP_EXPR
- && !TREE_TYPE (*inner_else))
- {
- warning (0, "%Hempty body in an else-statement",
- EXPR_LOCUS (*inner_else));
-
- *inner_else = alloc_stmt_list ();
- }
- }
+ empty_body_warning (then_block, else_block);
stmt = build3 (COND_EXPR, void_type_node, cond, then_block, else_block);
SET_EXPR_LOCATION (stmt, if_locus);
Index: c-parser.c
===================================================================
--- c-parser.c (revision 109375)
+++ c-parser.c (working copy)
@@ -3723,7 +3723,7 @@ c_parser_if_body (c_parser *parser, bool
c_parser_label (parser);
*if_p = c_parser_next_token_is_keyword (parser, RID_IF);
if (extra_warnings && c_parser_next_token_is (parser, CPP_SEMICOLON))
- add_stmt (build1 (NOP_EXPR, NULL_TREE, NULL_TREE));
+ add_stmt (build_empty_stmt ());
c_parser_statement_after_labels (parser);
return c_end_compound_stmt (block, flag_isoc99);
}
Index: gcc/testsuite/g++.dg/warn/empty-body.C
===================================================================
--- gcc/testsuite/g++.dg/warn/empty-body.C (revision 0)
+++ gcc/testsuite/g++.dg/warn/empty-body.C (revision 0)
@@ -0,0 +1,13 @@
+// PR c++/5520
+// { dg-options "-O2 -Wextra" }
+
+void breakme()
+{
+ if(1); // { dg-warning "empty body" }
+ if(1){} // { dg-bogus "empty body" }
+ if(1)
+ (void)0; // { dg-bogus "empty body" }
+
+ if(1) {} else; // { dg-warning "empty body" }
+ if(1) {} else (void)0; // // { dg-bogus "empty body" }
+}