[master] cf3963845 vcc: Allow global symbols to be defined after use

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Tue Jun 1 13:50:07 UTC 2021


commit cf396384595ef47cc66f1eedcf0b6730d5b1b659
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Wed May 12 19:50:46 2021 +0200

    vcc: Allow global symbols to be defined after use
    
    A side effect is slightly more accurate error messages.
    
    Closes #3555

diff --git a/bin/varnishtest/tests/r00916.vtc b/bin/varnishtest/tests/r00916.vtc
index e73ef10cd..92900c5b9 100644
--- a/bin/varnishtest/tests/r00916.vtc
+++ b/bin/varnishtest/tests/r00916.vtc
@@ -5,7 +5,7 @@ server s1 {
 	txresp -body "FOO"
 } -start
 
-varnish v1 -errvcl {Symbol not found: 's-1'} {
+varnish v1 -errvcl {Undefined backend s-1, first reference:} {
 	backend b { .host = "${localhost}"; }
 	sub s1 {
 	}
diff --git a/bin/varnishtest/tests/v00016.vtc b/bin/varnishtest/tests/v00016.vtc
index f5145bf37..d26295fdc 100644
--- a/bin/varnishtest/tests/v00016.vtc
+++ b/bin/varnishtest/tests/v00016.vtc
@@ -66,7 +66,7 @@ varnish v1 -errvcl {Cannot be set in subroutine 'vcl_pipe'.} {
 	}
 }
 
-varnish v1 -errvcl {Symbol not found: 'c'} {
+varnish v1 -errvcl {Undefined backend c, first reference:} {
 	backend b { .host = "${localhost}"; }
 	sub vcl_backend_response {
 		if (beresp.backend == c) {
diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc
index e29e4ff4f..47b899585 100644
--- a/bin/varnishtest/tests/v00020.vtc
+++ b/bin/varnishtest/tests/v00020.vtc
@@ -69,6 +69,10 @@ varnish v1 -errvcl {Operator % only possible on INT} {
 }
 
 varnish v1 -vcl {
+	sub vcl_recv {
+		# 3555 (define after use)
+		set req.backend_hint = b;
+	}
 	backend b { .host = "${localhost}"; }
 	sub vcl_recv {
 		set req.http.foo = "foo" + "bar";
@@ -220,6 +224,27 @@ varnish v1 -errvcl {Name of subroutine, 'foo.bar', contains illegal character '.
 	}
 }
 
+# 3555 (define after use)
+varnish v1 -vcl {
+	import debug;
+	backend be none;
+	sub caller {
+		debug.call(foo);
+	}
+	sub foo { }
+	sub vcl_recv {
+		call caller;
+		call foo;
+	}
+}
+
+# 3555 (don't launder partial symbols)
+varnish v1 -errvcl {Symbol not found: 'foo.bar'} {
+	sub vcl_recv {
+		set req.backend_hint = foo.bar;
+	}
+}
+
 varnish v1 -errvcl {The names 'vcl_*' are reserved for subroutines.} {
 	sub vcl_bar {
 	}
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index 4a5728bf6..55d311ea8 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -719,7 +719,7 @@ vcc_expr5(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 {
 	struct expr *e1, *e2;
 	const char *ip, *sign;
-	struct token *t;
+	struct token *t, *t1;
 	struct symbol *sym;
 
 	sign = "";
@@ -738,8 +738,19 @@ vcc_expr5(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 	switch (tl->t->tok) {
 	case ID:
 		t = tl->t;
-		sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_PARTIAL,
-		    XREF_REF);
+		t1 = vcc_PeekToken(tl);
+		ERRCHK(tl);
+		sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
+		    SYMTAB_PARTIAL_NOERR, XREF_REF);
+		if (sym == NULL && fmt->global_pfx != NULL && t1->tok != '.') {
+			sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
+			    SYMTAB_CREATE, XREF_REF);
+			AN(sym);
+			VCC_GlobalSymbol(sym, fmt);
+		}
+		if (sym == NULL)
+			AZ(VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE,
+			    SYMTAB_PARTIAL, XREF_REF));
 		ERRCHK(tl);
 		AN(sym);
 		if (sym->kind == SYM_INSTANCE) {


More information about the varnish-commit mailing list