1
2
3
4
5
6
7 package types2
8
9 import (
10 "cmd/compile/internal/syntax"
11 . "internal/types/errors"
12 "strings"
13 )
14
15
16
17 func (check *Checker) langCompat(lit *syntax.BasicLit) {
18 s := lit.Value
19 if len(s) <= 2 || check.allowVersion(go1_13) {
20 return
21 }
22
23 if strings.Contains(s, "_") {
24 check.versionErrorf(lit, go1_13, "underscore in numeric literal")
25 return
26 }
27 if s[0] != '0' {
28 return
29 }
30 radix := s[1]
31 if radix == 'b' || radix == 'B' {
32 check.versionErrorf(lit, go1_13, "binary literal")
33 return
34 }
35 if radix == 'o' || radix == 'O' {
36 check.versionErrorf(lit, go1_13, "0o/0O-style octal literal")
37 return
38 }
39 if lit.Kind != syntax.IntLit && (radix == 'x' || radix == 'X') {
40 check.versionErrorf(lit, go1_13, "hexadecimal floating-point literal")
41 }
42 }
43
44 func (check *Checker) basicLit(x *operand, e *syntax.BasicLit) {
45 switch e.Kind {
46 case syntax.IntLit, syntax.FloatLit, syntax.ImagLit:
47 check.langCompat(e)
48
49
50
51
52
53
54
55
56
57 const limit = 10000
58 if len(e.Value) > limit {
59 check.errorf(e, InvalidConstVal, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
60 x.mode = invalid
61 return
62 }
63 }
64 x.setConst(e.Kind, e.Value)
65 if x.mode == invalid {
66
67
68
69
70 check.errorf(e, InvalidConstVal, "malformed constant: %s", e.Value)
71 x.mode = invalid
72 return
73 }
74
75 x.expr = e
76 check.overflow(x, opPos(x.expr))
77 }
78
79 func (check *Checker) funcLit(x *operand, e *syntax.FuncLit) {
80 if sig, ok := check.typ(e.Type).(*Signature); ok {
81
82
83 sig.scope.pos = e.Pos()
84 sig.scope.end = endPos(e)
85 if !check.conf.IgnoreFuncBodies && e.Body != nil {
86
87
88
89 decl := check.decl
90 iota := check.iota
91
92
93
94
95 check.later(func() {
96 check.funcBody(decl, "<function literal>", sig, e.Body, iota)
97 }).describef(e, "func literal")
98 }
99 x.mode = value
100 x.typ = sig
101 } else {
102 check.errorf(e, InvalidSyntaxTree, "invalid function literal %v", e)
103 x.mode = invalid
104 }
105 }
106
107 func (check *Checker) compositeLit(x *operand, e *syntax.CompositeLit, hint Type) {
108 var typ, base Type
109 var isElem bool
110
111 switch {
112 case e.Type != nil:
113
114
115
116 if atyp, _ := e.Type.(*syntax.ArrayType); atyp != nil && isdddArray(atyp) {
117
118
119
120 typ = &Array{len: -1, elem: check.varType(atyp.Elem)}
121 base = typ
122 break
123 }
124 typ = check.typ(e.Type)
125 base = typ
126
127 case hint != nil:
128
129 typ = hint
130 base = typ
131
132 u, _ := commonUnder(base, nil)
133 if b, ok := deref(u); ok {
134 base = b
135 }
136 isElem = true
137
138 default:
139
140 check.error(e, UntypedLit, "missing type in composite literal")
141
142 typ = Typ[Invalid]
143 base = typ
144 }
145
146 switch u, _ := commonUnder(base, nil); utyp := u.(type) {
147 case *Struct:
148
149
150 if utyp.fields == nil {
151 check.error(e, InvalidTypeCycle, "invalid recursive type")
152 x.mode = invalid
153 return
154 }
155 if len(e.ElemList) == 0 {
156 break
157 }
158
159
160
161 fields := utyp.fields
162 if _, ok := e.ElemList[0].(*syntax.KeyValueExpr); ok {
163
164 visited := make([]bool, len(fields))
165 for _, e := range e.ElemList {
166 kv, _ := e.(*syntax.KeyValueExpr)
167 if kv == nil {
168 check.error(e, MixedStructLit, "mixture of field:value and value elements in struct literal")
169 continue
170 }
171 key, _ := kv.Key.(*syntax.Name)
172
173
174 check.expr(nil, x, kv.Value)
175 if key == nil {
176 check.errorf(kv, InvalidLitField, "invalid field name %s in struct literal", kv.Key)
177 continue
178 }
179 i := fieldIndex(fields, check.pkg, key.Value, false)
180 if i < 0 {
181 var alt Object
182 if j := fieldIndex(fields, check.pkg, key.Value, true); j >= 0 {
183 alt = fields[j]
184 }
185 msg := check.lookupError(base, key.Value, alt, true)
186 check.error(kv.Key, MissingLitField, msg)
187 continue
188 }
189 fld := fields[i]
190 check.recordUse(key, fld)
191 etyp := fld.typ
192 check.assignment(x, etyp, "struct literal")
193
194 if visited[i] {
195 check.errorf(kv, DuplicateLitField, "duplicate field name %s in struct literal", key.Value)
196 continue
197 }
198 visited[i] = true
199 }
200 } else {
201
202 for i, e := range e.ElemList {
203 if kv, _ := e.(*syntax.KeyValueExpr); kv != nil {
204 check.error(kv, MixedStructLit, "mixture of field:value and value elements in struct literal")
205 continue
206 }
207 check.expr(nil, x, e)
208 if i >= len(fields) {
209 check.errorf(x, InvalidStructLit, "too many values in struct literal of type %s", base)
210 break
211 }
212
213 fld := fields[i]
214 if !fld.Exported() && fld.pkg != check.pkg {
215 check.errorf(x, UnexportedLitField, "implicit assignment to unexported field %s in struct literal of type %s", fld.name, base)
216 continue
217 }
218 etyp := fld.typ
219 check.assignment(x, etyp, "struct literal")
220 }
221 if len(e.ElemList) < len(fields) {
222 check.errorf(inNode(e, e.Rbrace), InvalidStructLit, "too few values in struct literal of type %s", base)
223
224 }
225 }
226
227 case *Array:
228
229
230
231 if utyp.elem == nil {
232 check.error(e, InvalidTypeCycle, "invalid recursive type")
233 x.mode = invalid
234 return
235 }
236 n := check.indexedElts(e.ElemList, utyp.elem, utyp.len)
237
238
239
240
241
242
243
244
245 if utyp.len < 0 {
246 utyp.len = n
247
248
249
250
251 if e.Type != nil {
252 check.recordTypeAndValue(e.Type, typexpr, utyp, nil)
253 }
254 }
255
256 case *Slice:
257
258
259 if utyp.elem == nil {
260 check.error(e, InvalidTypeCycle, "invalid recursive type")
261 x.mode = invalid
262 return
263 }
264 check.indexedElts(e.ElemList, utyp.elem, -1)
265
266 case *Map:
267
268
269 if utyp.key == nil || utyp.elem == nil {
270 check.error(e, InvalidTypeCycle, "invalid recursive type")
271 x.mode = invalid
272 return
273 }
274
275
276
277 keyIsInterface := isNonTypeParamInterface(utyp.key)
278 visited := make(map[any][]Type, len(e.ElemList))
279 for _, e := range e.ElemList {
280 kv, _ := e.(*syntax.KeyValueExpr)
281 if kv == nil {
282 check.error(e, MissingLitKey, "missing key in map literal")
283 continue
284 }
285 check.exprWithHint(x, kv.Key, utyp.key)
286 check.assignment(x, utyp.key, "map literal")
287 if x.mode == invalid {
288 continue
289 }
290 if x.mode == constant_ {
291 duplicate := false
292 xkey := keyVal(x.val)
293 if keyIsInterface {
294 for _, vtyp := range visited[xkey] {
295 if Identical(vtyp, x.typ) {
296 duplicate = true
297 break
298 }
299 }
300 visited[xkey] = append(visited[xkey], x.typ)
301 } else {
302 _, duplicate = visited[xkey]
303 visited[xkey] = nil
304 }
305 if duplicate {
306 check.errorf(x, DuplicateLitKey, "duplicate key %s in map literal", x.val)
307 continue
308 }
309 }
310 check.exprWithHint(x, kv.Value, utyp.elem)
311 check.assignment(x, utyp.elem, "map literal")
312 }
313
314 default:
315
316
317 for _, e := range e.ElemList {
318 if kv, _ := e.(*syntax.KeyValueExpr); kv != nil {
319
320
321
322 e = kv.Value
323 }
324 check.use(e)
325 }
326
327 if isValid(utyp) {
328 var qualifier string
329 if isElem {
330 qualifier = " element"
331 }
332 var cause string
333 if utyp == nil {
334 cause = " (no common underlying type)"
335 }
336 check.errorf(e, InvalidLit, "invalid composite literal%s type %s%s", qualifier, typ, cause)
337 x.mode = invalid
338 return
339 }
340 }
341
342 x.mode = value
343 x.typ = typ
344 }
345
346
347
348
349
350 func (check *Checker) indexedElts(elts []syntax.Expr, typ Type, length int64) int64 {
351 visited := make(map[int64]bool, len(elts))
352 var index, max int64
353 for _, e := range elts {
354
355 validIndex := false
356 eval := e
357 if kv, _ := e.(*syntax.KeyValueExpr); kv != nil {
358 if typ, i := check.index(kv.Key, length); isValid(typ) {
359 if i >= 0 {
360 index = i
361 validIndex = true
362 } else {
363 check.errorf(e, InvalidLitIndex, "index %s must be integer constant", kv.Key)
364 }
365 }
366 eval = kv.Value
367 } else if length >= 0 && index >= length {
368 check.errorf(e, OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
369 } else {
370 validIndex = true
371 }
372
373
374 if validIndex {
375 if visited[index] {
376 check.errorf(e, DuplicateLitKey, "duplicate index %d in array or slice literal", index)
377 }
378 visited[index] = true
379 }
380 index++
381 if index > max {
382 max = index
383 }
384
385
386 var x operand
387 check.exprWithHint(&x, eval, typ)
388 check.assignment(&x, typ, "array or slice literal")
389 }
390 return max
391 }
392
View as plain text