Improve handling of statement expressions ({}):
authorChristoph Mallon <christoph.mallon@gmx.de>
Wed, 10 Dec 2008 19:12:16 +0000 (19:12 +0000)
committerChristoph Mallon <christoph.mallon@gmx.de>
Wed, 10 Dec 2008 19:12:16 +0000 (19:12 +0000)
- Fix spurious warnings about reaching the end of a non-void function
- Correct reachable statemente analysis
- More pretty AST printing.

[r24499]

ast.c
ast_t.h
parser.c

diff --git a/ast.c b/ast.c
index 9bda7f1..ef626ae 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -879,7 +879,7 @@ static void print_compound_statement(const compound_statement_t *block)
        }
        --indent;
        print_indent();
-       fputs("}\n", out);
+       fputs(block->stmt_expr ? "}" : "}\n", out);
 }
 
 /**
diff --git a/ast_t.h b/ast_t.h
index 182c85a..fd6b62f 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -578,6 +578,7 @@ struct compound_statement_t {
        statement_base_t  base;
        statement_t      *statements;
        scope_t           scope;
+       bool              stmt_expr; /* The compound statement is a statement expression */
 };
 
 struct declaration_statement_t {
index e226fa7..f51826c 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -5659,6 +5659,7 @@ static int determine_truth(expression_t const* const cond)
 }
 
 static void check_reachable(statement_t *);
+static bool reaches_end;
 
 static bool expression_returns(expression_t const *const expr)
 {
@@ -5703,10 +5704,14 @@ static bool expression_returns(expression_t const *const expr)
                case EXPR_INVALID:
                        return true;
 
-               case EXPR_STATEMENT:
+               case EXPR_STATEMENT: {
+                       bool old_reaches_end = reaches_end;
+                       reaches_end = false;
                        check_reachable(expr->statement.statement);
-                       // TODO check if statement can be left
-                       return true;
+                       bool returns = reaches_end;
+                       reaches_end = old_reaches_end;
+                       return returns;
+               }
 
                case EXPR_CONDITIONAL:
                        // TODO handle constant expression
@@ -6080,6 +6085,11 @@ found_break_parent:
                                panic("invalid control flow in function");
 
                        case STATEMENT_COMPOUND:
+                               if (next->compound.stmt_expr) {
+                                       reaches_end = true;
+                                       return;
+                               }
+                               /* FALLTHROUGH */
                        case STATEMENT_IF:
                        case STATEMENT_SWITCH:
                        case STATEMENT_LABEL:
@@ -7191,6 +7201,7 @@ static expression_t *parse_statement_expression(void)
        expression_t *expression = allocate_expression_zero(EXPR_STATEMENT);
 
        statement_t *statement          = parse_compound_statement(true);
+       statement->compound.stmt_expr   = true;
        expression->statement.statement = statement;
 
        /* find last statement and use its type */