cmd/gc: accept ideal float as indices.

Fixes #4813.

R=golang-dev, daniel.morsing, rsc
CC=golang-dev
https://golang.org/cl/7625050
diff --git a/test/index.go b/test/index.go
index daab45f..f9360c1 100644
--- a/test/index.go
+++ b/test/index.go
@@ -36,6 +36,8 @@
 	ci64big int64 = 1<<31
 	ci64bigger int64 = 1<<32
 	chuge = 1<<100
+	cfgood = 2.0
+	cfbad = 2.1
 
 	cnj = -2
 	cni int = -3
@@ -46,6 +48,8 @@
 	cni64big int64 = -1<<31
 	cni64bigger int64 = -1<<32
 	cnhuge = -1<<100
+	cnfgood = -2.0
+	cnfbad = -2.1
 )
 
 var j int = 100020
@@ -57,6 +61,8 @@
 var i64big int64 = 1<<31
 var i64bigger int64 = 1<<32
 var huge uint64 = 1<<64 - 1
+var fgood float64 = 2.0
+var fbad float64 = 2.1
 
 var nj int = -10
 var ni int = -11
@@ -67,6 +73,8 @@
 var ni64big int64 = -1<<31
 var ni64bigger int64 = -1<<32
 var nhuge int64 = -1<<63
+var nfgood float64 = -2.0
+var nfbad float64 = -2.1
 
 var si []int = make([]int, 10)
 var ai [10]int
@@ -156,7 +164,7 @@
 	if pass == 0 {
 		fmt.Fprintf(b, "\ttest(func(){use(%s)}, %q)\n", expr, expr)
 	} else {
-		fmt.Fprintf(b, "\tuse(%s)  // ERROR \"index|overflow\"\n", expr)
+		fmt.Fprintf(b, "\tuse(%s)  // ERROR \"index|overflow|truncated\"\n", expr)
 	}
 }
 
@@ -169,15 +177,15 @@
 		fmt.Fprint(b, "// errorcheck\n\n")
 	}
 	fmt.Fprint(b, prolog)
-	
+
 	var choices = [][]string{
 		// Direct value, fetch from struct, fetch from struct pointer.
 		// The last two cases get us to oindex_const_sudo in gsubr.c.
 		[]string{"", "t.", "pt."},
-		
+
 		// Array, pointer to array, slice.
 		[]string{"a", "pa", "s"},
-		
+
 		// Element is int, element is quad (struct).
 		// This controls whether we end up in gsubr.c (i) or cgen.c (q).
 		[]string{"i", "q"},
@@ -192,9 +200,9 @@
 		[]string{"", "n"},
 
 		// Size of index.
-		[]string{"j", "i", "i8", "i16", "i32", "i64", "i64big", "i64bigger", "huge"},
+		[]string{"j", "i", "i8", "i16", "i32", "i64", "i64big", "i64bigger", "huge", "fgood", "fbad"},
 	}
-	
+
 	forall(choices, func(x []string) {
 		p, a, e, big, c, n, i := x[0], x[1], x[2], x[3], x[4], x[5], x[6]
 
@@ -206,7 +214,7 @@
 		//	negative constant
 		//	large constant
 		thisPass := 0
-		if c == "c" && (a == "a" || a == "pa" || n == "n" || i == "i64big" || i == "i64bigger" || i == "huge") {
+		if c == "c" && (a == "a" || a == "pa" || n == "n" || i == "i64big" || i == "i64bigger" || i == "huge" || i == "fbad") {
 			if i == "huge" {
 				// Due to a detail of 6g's internals,
 				// the huge constant errors happen in an
@@ -223,27 +231,50 @@
 				thisPass = 2
 			}
 		}
-		
+
+		pae := p + a + e + big
+		cni := c + n + i
+
 		// If we're using the big-len data, positive int8 and int16 cannot overflow.
 		if big == "b" && n == "" && (i == "i8" || i == "i16") {
+			if pass == 0 {
+				fmt.Fprintf(b, "\tuse(%s[%s])\n", pae, cni)
+				fmt.Fprintf(b, "\tuse(%s[0:%s])\n", pae, cni)
+				fmt.Fprintf(b, "\tuse(%s[1:%s])\n", pae, cni)
+				fmt.Fprintf(b, "\tuse(%s[%s:])\n", pae, cni)
+				fmt.Fprintf(b, "\tuse(%s[%s:%s])\n", pae, cni, cni)
+			}
+			return
+		}
+
+		// Float variables cannot be used as indices.
+		if c == "" && (i == "fgood" || i == "fbad") {
+			return
+		}
+		// Integral float constat is ok.
+		if c == "c" && n == "" && i == "fgood" {
+			if pass == 0 {
+				fmt.Fprintf(b, "\tuse(%s[%s])\n", pae, cni)
+				fmt.Fprintf(b, "\tuse(%s[0:%s])\n", pae, cni)
+				fmt.Fprintf(b, "\tuse(%s[1:%s])\n", pae, cni)
+				fmt.Fprintf(b, "\tuse(%s[%s:])\n", pae, cni)
+				fmt.Fprintf(b, "\tuse(%s[%s:%s])\n", pae, cni, cni)
+			}
 			return
 		}
 
 		// Only print the test case if it is appropriate for this pass.
 		if thisPass == pass {
-			pae := p+a+e+big
-			cni := c+n+i
-			
 			// Index operation
-			testExpr(b, pae + "[" + cni + "]")
-			
+			testExpr(b, pae+"["+cni+"]")
+
 			// Slice operation.
 			// Low index 0 is a special case in ggen.c
 			// so test both 0 and 1.
-			testExpr(b, pae + "[0:" + cni + "]")
-			testExpr(b, pae + "[1:" + cni + "]")
-			testExpr(b, pae + "[" + cni + ":]")
-			testExpr(b, pae + "[" + cni + ":" + cni + "]")
+			testExpr(b, pae+"[0:"+cni+"]")
+			testExpr(b, pae+"[1:"+cni+"]")
+			testExpr(b, pae+"["+cni+":]")
+			testExpr(b, pae+"["+cni+":"+cni+"]")
 		}
 	})
 
@@ -253,7 +284,7 @@
 
 func forall(choices [][]string, f func([]string)) {
 	x := make([]string, len(choices))
-	
+
 	var recurse func(d int)
 	recurse = func(d int) {
 		if d >= len(choices) {
@@ -261,7 +292,7 @@
 			return
 		}
 		for _, x[d] = range choices[d] {
-			recurse(d+1)
+			recurse(d + 1)
 		}
 	}
 	recurse(0)