aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2003-05-31 13:19:17 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:00:47 -0700
commit32dc632cf37e8a7a9443e6b38085420ec74ac9ac (patch)
tree5bb4100f07d589786cbdee7f1b115f938172ae5b
parent9f7a0188911742338e46a70596cab830b3ef3131 (diff)
downloadsparse-32dc632cf37e8a7a9443e6b38085420ec74ac9ac.tar.gz
sparse-32dc632cf37e8a7a9443e6b38085420ec74ac9ac.tar.xz
sparse-32dc632cf37e8a7a9443e6b38085420ec74ac9ac.zip
Simplify if-statements without even evaluating the false side
for compile-time constant conditionals. This allows inline functions and macros to do "illegal" things, as long as it's compile-time deterministic that they aren't done.
-rw-r--r--evaluate.c36
-rw-r--r--parse.h1
-rw-r--r--show-parse.c1
3 files changed, 33 insertions, 5 deletions
diff --git a/evaluate.c b/evaluate.c
index 9874096..fdf5cc7 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1607,6 +1607,38 @@ struct symbol *evaluate_return_expression(struct statement *stmt)
return NULL;
}
+static void evaluate_if_statement(struct statement *stmt)
+{
+ struct expression *expr = stmt->if_conditional;
+ struct symbol *ctype;
+
+ if (!expr)
+ return;
+ if (expr->type == EXPR_ASSIGNMENT)
+ warn(expr->pos, "assignment expression in conditional");
+
+ ctype = evaluate_expression(expr);
+ if (!ctype)
+ return;
+
+ /* Simplify constant conditionals without even evaluating the false side */
+ if (expr->type == EXPR_VALUE) {
+ struct statement *simple;
+ simple = expr->value ? stmt->if_true : stmt->if_false;
+
+ /* Nothing? */
+ if (!simple) {
+ stmt->type = STMT_NONE;
+ return;
+ }
+ evaluate_statement(simple);
+ *stmt = *simple;
+ return;
+ }
+ evaluate_statement(stmt->if_true);
+ evaluate_statement(stmt->if_false);
+}
+
struct symbol *evaluate_statement(struct statement *stmt)
{
if (!stmt)
@@ -1626,9 +1658,7 @@ struct symbol *evaluate_statement(struct statement *stmt)
return type;
}
case STMT_IF:
- evaluate_expression(stmt->if_conditional);
- evaluate_statement(stmt->if_true);
- evaluate_statement(stmt->if_false);
+ evaluate_if_statement(stmt);
return NULL;
case STMT_ITERATOR:
evaluate_expression(stmt->iterator_pre_condition);
diff --git a/parse.h b/parse.h
index e47e7e0..d6e223a 100644
--- a/parse.h
+++ b/parse.h
@@ -27,7 +27,6 @@ enum statement_type {
struct statement {
enum statement_type type;
struct position pos;
- struct statement *next;
union {
struct label_arg {
struct symbol *label;
diff --git a/show-parse.c b/show-parse.c
index 31dfcfb..509403a 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -493,7 +493,6 @@ int show_statement(struct statement *stmt)
break;
}
case STMT_NONE:
- printf("\t!NONE!\n");
break;
case STMT_LABEL: