[master] 2d7f4ab Improve compiler typechecking and error reporting.

Poul-Henning Kamp phk at FreeBSD.org
Wed Jun 8 23:15:06 CEST 2016


commit 2d7f4abe57c0dd2bb0f15b05e0b362f7aac3ec76
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Jun 8 21:13:29 2016 +0000

    Improve compiler typechecking and error reporting.

diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc
index d8e4622..e041356 100644
--- a/bin/varnishtest/tests/v00020.vtc
+++ b/bin/varnishtest/tests/v00020.vtc
@@ -304,3 +304,11 @@ varnish v1 -errvcl {Name of ACL, 'foo-bar', contains illegal character '-'} {
 varnish v1 -errvcl {Expected 'from path ...'} {
 	import std to;
 }
+
+varnish v1 -errvcl {INT * BLOB not possible.} {
+	import debug;
+	backend b { .host = "127.0.0.1"; }
+	sub vcl_deliver {
+		set resp.status = 100 * debug.str2blob("a");
+	}
+}
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index f5b7391..3a6620d 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -378,23 +378,15 @@ vcc_expr_tostring(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 	AN(fmt == STRING || fmt == STRING_LIST);
 
 	p = (*e)->fmt->tostring;
-	if (p == NULL && (*e)->fmt == INT) {
-		if (vcc_isconst(*e)) {
-			p = "\"\v1\"";
-			constant = EXPR_CONST;
-		} else {
-			p = "VRT_INT_string(ctx, \v1)";
-		}
-	} else if (p == NULL && (*e)->fmt == BLOB) {
+	if (p == NULL && (*e)->fmt == BLOB) {
 		VSB_printf(tl->sb,
 		    "Wrong use of BLOB value.\n"
 		    "BLOBs can only be used as arguments to VMOD"
 		    " functions.\n");
 		vcc_ErrWhere2(tl, (*e)->t1, tl->t);
 		return;
-	} else {
-		AN(p);
 	}
+	AN(p);
 	if (*p != '\0') {
 		*e = vcc_expr_edit(fmt, p, *e, NULL);
 		(*e)->constant = constant;
@@ -912,6 +904,13 @@ vcc_expr_mul(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 		vcc_NextToken(tl);
 		vcc_expr4(tl, &e2, f2);
 		ERRCHK(tl);
+		if (e2->fmt->multype == NULL) {
+			VSB_printf(tl->sb,
+			    "%s %.*s %s not possible.\n",
+			    f2->name, PF(tk), e2->fmt->name);
+			vcc_ErrWhere(tl, tk);
+			return;
+		}
 		assert(e2->fmt == f2);
 		if (tk->tok == '*')
 			*e = vcc_expr_edit(f3, "(\v1*\v2)", *e, e2);
@@ -947,10 +946,8 @@ vcc_expr_string_add(struct vcc *tl, struct expr **e, struct expr *e2)
 			vcc_expr_mul(tl, &e2, STRING);
 		}
 		ERRCHK(tl);
-		if (e2->fmt != STRING && e2->fmt != STRING_LIST) {
+		if (e2->fmt != STRING && e2->fmt != STRING_LIST)
 			vcc_expr_tostring(tl, &e2, f2);
-			ERRCHK(tl);
-		}
 		ERRCHK(tl);
 		assert(e2->fmt == STRING || e2->fmt == STRING_LIST);
 
@@ -996,41 +993,46 @@ vcc_expr_add(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 		else
 			vcc_expr_mul(tl, &e2, f2);
 		ERRCHK(tl);
-		if (tk->tok == '-' && (*e)->fmt == TIME && e2->fmt == TIME) {
-			/* OK */
-		} else if ((*e)->fmt == TIME && e2->fmt == DURATION) {
-			f2 = TIME;
-			/* OK */
-		} else if ((*e)->fmt == BYTES && e2->fmt == BYTES) {
-			/* OK */
-		} else if ((*e)->fmt == INT && e2->fmt == INT) {
-			/* OK */
-		} else if ((*e)->fmt == REAL && e2->fmt == REAL) {
-			/* OK */
-		} else if ((*e)->fmt == DURATION && e2->fmt == DURATION) {
-			/* OK */
-		} else if (tk->tok == '+' &&
-		    (*e)->fmt == STRING && e2->fmt == STRING) {
-			vcc_expr_string_add(tl, e, e2);
-			return;
-		} else if (tk->tok == '+' &&
-		    (fmt == STRING || fmt == STRING_LIST)) {
-			/* Time to fold and add as string */
-			vcc_expr_tostring(tl, e, STRING);
-			vcc_expr_string_add(tl, e, e2);
-			return;
-		} else {
-			VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
-			    (*e)->fmt->name, PF(tk), e2->fmt->name);
-			vcc_ErrWhere2(tl, tk, tl->t);
-			return;
+
+#define ADD_OK(op, a, b, c)						  \
+		if (tk->tok == op[0] && (*e)->fmt == a && e2->fmt == b) { \
+			*e = vcc_expr_edit(c, "(\v1" op "\v2)", *e, e2);  \
+			continue;					  \
+		}							  \
+
+		ADD_OK("-", TIME,	TIME,		DURATION);
+		ADD_OK("+", TIME,	DURATION,	TIME);
+		ADD_OK("-", TIME,	DURATION,	TIME);
+		ADD_OK("+", DURATION,	DURATION,	DURATION);
+		ADD_OK("-", DURATION,	DURATION,	DURATION);
+		ADD_OK("+", BYTES,	BYTES,		BYTES);
+		ADD_OK("-", BYTES,	BYTES,		BYTES);
+		ADD_OK("+", INT,	INT,		INT);
+		ADD_OK("-", INT,	INT,		INT);
+		ADD_OK("+", REAL,	REAL,		REAL);
+		ADD_OK("-", REAL,	REAL,		REAL);
+
+#undef ADD_OK
+
+		if (tk->tok == '+') {
+			if ((*e)->fmt == STRING && e2->fmt == STRING) {
+				vcc_expr_string_add(tl, e, e2);
+				return;
+			}
+
+			if (fmt == STRING || fmt == STRING_LIST) {
+				/* Time to fold and add as string */
+				if ((*e)->fmt != fmt)
+					vcc_expr_tostring(tl, e, fmt);
+				vcc_expr_string_add(tl, e, e2);
+				return;
+			}
 		}
-		if (tk->tok == '+')
-			*e = vcc_expr_edit(f2, "(\v1+\v2)", *e, e2);
-		else if (f2 == TIME && e2->fmt == TIME)
-			*e = vcc_expr_edit(DURATION, "(\v1-\v2)", *e, e2);
-		else
-			*e = vcc_expr_edit(f2, "(\v1-\v2)", *e, e2);
+
+		VSB_printf(tl->sb, "%s %.*s %s not possible.\n",
+		    (*e)->fmt->name, PF(tk), e2->fmt->name);
+		vcc_ErrWhere2(tl, tk, tl->t);
+		return;
 	}
 }
 
@@ -1246,8 +1248,8 @@ vcc_expr_cand(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 		ERRCHK(tl);
 		if (e2->fmt != BOOL) {
 			VSB_printf(tl->sb,
-			    "'&&' must be followed by BOOL, found ");
-			VSB_printf(tl->sb, "%s.\n", e2->fmt->name);
+			    "'&&' must be followed by BOOL,"
+			    " found %s.\n", e2->fmt->name);
 			vcc_ErrWhere2(tl, tk, tl->t);
 			return;
 		}
@@ -1280,8 +1282,8 @@ vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 			ERRCHK(tl);
 			if (e2->fmt != BOOL) {
 				VSB_printf(tl->sb,
-				    "'||' must be followed by BOOL, found ");
-				VSB_printf(tl->sb, "%s.\n", e2->fmt->name);
+				    "'||' must be followed by BOOL,"
+				    " found %s.\n", e2->fmt->name);
 				vcc_ErrWhere2(tl, tk, tl->t);
 				return;
 			}
diff --git a/lib/libvcc/vcc_types.c b/lib/libvcc/vcc_types.c
index 822471d..65b7553 100644
--- a/lib/libvcc/vcc_types.c
+++ b/lib/libvcc/vcc_types.c
@@ -100,6 +100,7 @@ const struct type INT[1] = {{
 	.magic =		0xfae932d9,
 	.name =			"INT",
 	.multype =		INT,
+	.tostring =		"VRT_INT_string(ctx, \v1)",
 }};
 
 const struct type IP[1] = {{



More information about the varnish-commit mailing list