From b60c8203eac32eb0d0b11751ba8f85b2f5eada81 Mon Sep 17 00:00:00 2001 From: acanino Date: Sat, 10 Oct 2015 21:35:22 -0400 Subject: [PATCH] cmd/compile: "invalid variable name x in type switch", where x is a name of a constant Small fix: looks like a short variable declaration with a type switch checks to make sure the variable used had valid shape (ONAME, OTYPE, or ONONAME) and rejects everything else. Then a new variable is declared. If the symbol contained in the declaration was a named OLITERAL (still a valid identifier obviously) it would be rejected, even though a new variable would have been declared. Fix adds this case to the check. Added a test case from issue12413. Fixes #12413 Change-Id: I150dadafa8ee5612c867d58031027f2dca8c6ebc Reviewed-on: https://go-review.googlesource.com/15760 Reviewed-by: Minux Ma Run-TryBot: Minux Ma TryBot-Result: Gobot Gobot --- src/cmd/compile/internal/gc/go.y | 2 +- src/cmd/compile/internal/gc/y.go | 2 +- test/fixedbugs/issue12413.go | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 test/fixedbugs/issue12413.go diff --git a/src/cmd/compile/internal/gc/go.y b/src/cmd/compile/internal/gc/go.y index 599449f8239..2bec5b65764 100644 --- a/src/cmd/compile/internal/gc/go.y +++ b/src/cmd/compile/internal/gc/go.y @@ -510,7 +510,7 @@ simple_stmt: } if $1.Next != nil { Yyerror("argument count mismatch: %d = %d", count($1), 1); - } else if ($1.N.Op != ONAME && $1.N.Op != OTYPE && $1.N.Op != ONONAME) || isblank($1.N) { + } else if ($1.N.Op != ONAME && $1.N.Op != OTYPE && $1.N.Op != ONONAME && ($1.N.Op != OLITERAL || $1.N.Name == nil)) || isblank($1.N) { Yyerror("invalid variable name %s in type switch", $1.N); } else { $$.Left = dclname($1.N.Sym); diff --git a/src/cmd/compile/internal/gc/y.go b/src/cmd/compile/internal/gc/y.go index dfb0fa4aeec..b8aff3c746c 100644 --- a/src/cmd/compile/internal/gc/y.go +++ b/src/cmd/compile/internal/gc/y.go @@ -1586,7 +1586,7 @@ yydefault: } if yyDollar[1].list.Next != nil { Yyerror("argument count mismatch: %d = %d", count(yyDollar[1].list), 1) - } else if (yyDollar[1].list.N.Op != ONAME && yyDollar[1].list.N.Op != OTYPE && yyDollar[1].list.N.Op != ONONAME) || isblank(yyDollar[1].list.N) { + } else if (yyDollar[1].list.N.Op != ONAME && yyDollar[1].list.N.Op != OTYPE && yyDollar[1].list.N.Op != ONONAME && (yyDollar[1].list.N.Op != OLITERAL || yyDollar[1].list.N.Name == nil)) || isblank(yyDollar[1].list.N) { Yyerror("invalid variable name %s in type switch", yyDollar[1].list.N) } else { yyVAL.node.Left = dclname(yyDollar[1].list.N.Sym) diff --git a/test/fixedbugs/issue12413.go b/test/fixedbugs/issue12413.go new file mode 100644 index 00000000000..a054765118b --- /dev/null +++ b/test/fixedbugs/issue12413.go @@ -0,0 +1,19 @@ +// compile + +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// issue 12413: invalid variable name x in type switch: code would fail +// to compile if the variable used in the short variable declaration was +// previously declared as a constant. + +package main + +func main() { + const x = 42 + switch x := interface{}(nil).(type) { + default: + _ = x + } +}