scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit d897f1e478283d1fc1a71ac9637056c190a2da3f
parent fed5b85cc2ccff56e815e8d964f4fb80f694c5d0
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 18 Jul 2015 10:06:21 +0200

Naive implementation of constexpr()

Constexpr() parses a constant expression, an expression
which can be evaluated at compile time. This is a naive
and incorrect implementation, because it marks as constant
expressions where no variables are used, but it is wrong.
For example:

	- static int a; -> &a is a constant expression.
	- static int v[10]; -> &v[3] is a constant expression
	- int f(void); -> f is a constant expression.
But
	- &v[a] is not a constant expression.
	- &v[f()] is not a constant expression.

Diffstat:
cc1/cc1.h | 2+-
cc1/code.c | 12+++++++++---
cc1/expr.c | 11+++++++++++
3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -316,7 +316,7 @@ extern Node *sizeofnode(Type *tp); extern void freetree(Node *np); /* expr.c */ -extern Node *expr(void), *negate(Node *np); +extern Node *expr(void), *negate(Node *np), *constexpr(void); /* cpp.c */ extern void icpp(void); diff --git a/cc1/code.c b/cc1/code.c @@ -313,7 +313,7 @@ emitfield(unsigned op, void *arg) } Node * -node(unsigned op, Type *tp, Node *left, Node *right) +node(unsigned op, Type *tp, Node *lp, Node *rp) { Node *np; @@ -322,8 +322,14 @@ node(unsigned op, Type *tp, Node *left, Node *right) np->type = tp; np->sym = NULL; np->constant = np->symbol = np->lvalue = 0; - np->left = left; - np->right = right; + np->left = lp; + np->right = rp; + + if (lp) + np->constant |= lp->constant; + if (rp) + np->constant |= rp->constant; + return np; } diff --git a/cc1/expr.c b/cc1/expr.c @@ -845,6 +845,17 @@ assign(void) } Node * +constexpr(void) +{ + Node *np; + + np = ternary(); + if (!np->constant) + error("constant expression required"); + return np; +} + +Node * expr(void) { Node *lp, *rp;