shithub: scc

Download patch

ref: d897f1e478283d1fc1a71ac9637056c190a2da3f
parent: fed5b85cc2ccff56e815e8d964f4fb80f694c5d0
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Jul 18 06:06:21 EDT 2015

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.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -316,7 +316,7 @@
 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);
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -313,7 +313,7 @@
 }
 
 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 @@
 	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;
 }
 
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -845,6 +845,17 @@
 }
 
 Node *
+constexpr(void)
+{
+	Node *np;
+
+	np = ternary();
+	if (!np->constant)
+		error("constant expression required");
+	return np;
+}
+
+Node *
 expr(void)
 {
 	Node *lp, *rp;
--