1
2
3
4
5 package typecheck
6
7 import (
8 "fmt"
9 "go/constant"
10 "go/token"
11 "math"
12 "math/big"
13 "unicode"
14
15 "cmd/compile/internal/base"
16 "cmd/compile/internal/ir"
17 "cmd/compile/internal/types"
18 )
19
20 func roundFloat(v constant.Value, sz int64) constant.Value {
21 switch sz {
22 case 4:
23 f, _ := constant.Float32Val(v)
24 return makeFloat64(float64(f))
25 case 8:
26 f, _ := constant.Float64Val(v)
27 return makeFloat64(f)
28 }
29 base.Fatalf("unexpected size: %v", sz)
30 panic("unreachable")
31 }
32
33
34
35 func truncfltlit(v constant.Value, t *types.Type) constant.Value {
36 if t.IsUntyped() {
37 return v
38 }
39
40 return roundFloat(v, t.Size())
41 }
42
43
44
45
46 func trunccmplxlit(v constant.Value, t *types.Type) constant.Value {
47 if t.IsUntyped() {
48 return v
49 }
50
51 fsz := t.Size() / 2
52 return makeComplex(roundFloat(constant.Real(v), fsz), roundFloat(constant.Imag(v), fsz))
53 }
54
55
56 func convlit(n ir.Node, t *types.Type) ir.Node { return convlit1(n, t, false, nil) }
57 func DefaultLit(n ir.Node, t *types.Type) ir.Node { return convlit1(n, t, false, nil) }
58
59
60
61
62
63
64
65
66
67
68
69
70 func convlit1(n ir.Node, t *types.Type, explicit bool, context func() string) ir.Node {
71 if explicit && t == nil {
72 base.Fatalf("explicit conversion missing type")
73 }
74 if t != nil && t.IsUntyped() {
75 base.Fatalf("bad conversion to untyped: %v", t)
76 }
77
78 if n == nil || n.Type() == nil {
79
80 return n
81 }
82 if !n.Type().IsUntyped() {
83
84 return n
85 }
86
87
88 if n.Type().Kind() == types.TNIL {
89 if n.Op() != ir.ONIL {
90 base.Fatalf("unexpected op: %v (%v)", n, n.Op())
91 }
92 n = ir.Copy(n)
93 if t == nil {
94 base.Fatalf("use of untyped nil")
95 }
96
97 if !t.HasNil() {
98
99 return n
100 }
101
102 n.SetType(t)
103 return n
104 }
105
106 if t == nil || !ir.OKForConst[t.Kind()] {
107 t = defaultType(n.Type())
108 }
109
110 switch n.Op() {
111 default:
112 base.Fatalf("unexpected untyped expression: %v", n)
113
114 case ir.OLITERAL:
115 v := ConvertVal(n.Val(), t, explicit)
116 if v.Kind() == constant.Unknown {
117 n = ir.NewConstExpr(n.Val(), n)
118 break
119 }
120 n = ir.NewConstExpr(v, n)
121 n.SetType(t)
122 return n
123
124 case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.OREAL, ir.OIMAG:
125 ot := operandType(n.Op(), t)
126 if ot == nil {
127 n = DefaultLit(n, nil)
128 break
129 }
130
131 n := n.(*ir.UnaryExpr)
132 n.X = convlit(n.X, ot)
133 if n.X.Type() == nil {
134 n.SetType(nil)
135 return n
136 }
137 n.SetType(t)
138 return n
139
140 case ir.OADD, ir.OSUB, ir.OMUL, ir.ODIV, ir.OMOD, ir.OOR, ir.OXOR, ir.OAND, ir.OANDNOT, ir.OOROR, ir.OANDAND, ir.OCOMPLEX:
141 ot := operandType(n.Op(), t)
142 if ot == nil {
143 n = DefaultLit(n, nil)
144 break
145 }
146
147 var l, r ir.Node
148 switch n := n.(type) {
149 case *ir.BinaryExpr:
150 n.X = convlit(n.X, ot)
151 n.Y = convlit(n.Y, ot)
152 l, r = n.X, n.Y
153 case *ir.LogicalExpr:
154 n.X = convlit(n.X, ot)
155 n.Y = convlit(n.Y, ot)
156 l, r = n.X, n.Y
157 }
158
159 if l.Type() == nil || r.Type() == nil {
160 n.SetType(nil)
161 return n
162 }
163 if !types.Identical(l.Type(), r.Type()) {
164 base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type(), r.Type())
165 n.SetType(nil)
166 return n
167 }
168
169 n.SetType(t)
170 return n
171
172 case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
173 n := n.(*ir.BinaryExpr)
174 if !t.IsBoolean() {
175 break
176 }
177 n.SetType(t)
178 return n
179
180 case ir.OLSH, ir.ORSH:
181 n := n.(*ir.BinaryExpr)
182 n.X = convlit1(n.X, t, explicit, nil)
183 n.SetType(n.X.Type())
184 if n.Type() != nil && !n.Type().IsInteger() {
185 base.Errorf("invalid operation: %v (shift of type %v)", n, n.Type())
186 n.SetType(nil)
187 }
188 return n
189 }
190
191 if explicit {
192 base.Fatalf("cannot convert %L to type %v", n, t)
193 } else if context != nil {
194 base.Fatalf("cannot use %L as type %v in %s", n, t, context())
195 } else {
196 base.Fatalf("cannot use %L as type %v", n, t)
197 }
198
199 n.SetType(nil)
200 return n
201 }
202
203 func operandType(op ir.Op, t *types.Type) *types.Type {
204 switch op {
205 case ir.OCOMPLEX:
206 if t.IsComplex() {
207 return types.FloatForComplex(t)
208 }
209 case ir.OREAL, ir.OIMAG:
210 if t.IsFloat() {
211 return types.ComplexForFloat(t)
212 }
213 default:
214 if okfor[op][t.Kind()] {
215 return t
216 }
217 }
218 return nil
219 }
220
221
222
223
224
225
226
227 func ConvertVal(v constant.Value, t *types.Type, explicit bool) constant.Value {
228 switch ct := v.Kind(); ct {
229 case constant.Bool:
230 if t.IsBoolean() {
231 return v
232 }
233
234 case constant.String:
235 if t.IsString() {
236 return v
237 }
238
239 case constant.Int:
240 if explicit && t.IsString() {
241 return tostr(v)
242 }
243 fallthrough
244 case constant.Float, constant.Complex:
245 switch {
246 case t.IsInteger():
247 v = toint(v)
248 return v
249 case t.IsFloat():
250 v = toflt(v)
251 v = truncfltlit(v, t)
252 return v
253 case t.IsComplex():
254 v = tocplx(v)
255 v = trunccmplxlit(v, t)
256 return v
257 }
258 }
259
260 return constant.MakeUnknown()
261 }
262
263 func tocplx(v constant.Value) constant.Value {
264 return constant.ToComplex(v)
265 }
266
267 func toflt(v constant.Value) constant.Value {
268 if v.Kind() == constant.Complex {
269 v = constant.Real(v)
270 }
271
272 return constant.ToFloat(v)
273 }
274
275 func toint(v constant.Value) constant.Value {
276 if v.Kind() == constant.Complex {
277 v = constant.Real(v)
278 }
279
280 if v := constant.ToInt(v); v.Kind() == constant.Int {
281 return v
282 }
283
284
285
286
287
288
289
290
291
292
293 f := ir.BigFloat(v)
294 if f.MantExp(nil) > 2*ir.ConstPrec {
295 base.Errorf("integer too large")
296 } else {
297 var t big.Float
298 t.Parse(fmt.Sprint(v), 0)
299 if t.IsInt() {
300 base.Errorf("constant truncated to integer")
301 } else {
302 base.Errorf("constant %v truncated to integer", v)
303 }
304 }
305
306
307 return constant.MakeUnknown()
308 }
309
310 func tostr(v constant.Value) constant.Value {
311 if v.Kind() == constant.Int {
312 r := unicode.ReplacementChar
313 if x, ok := constant.Uint64Val(v); ok && x <= unicode.MaxRune {
314 r = rune(x)
315 }
316 v = constant.MakeString(string(r))
317 }
318 return v
319 }
320
321 func makeFloat64(f float64) constant.Value {
322 if math.IsInf(f, 0) {
323 base.Fatalf("infinity is not a valid constant")
324 }
325 return constant.MakeFloat64(f)
326 }
327
328 func makeComplex(real, imag constant.Value) constant.Value {
329 return constant.BinaryOp(constant.ToFloat(real), token.ADD, constant.MakeImag(constant.ToFloat(imag)))
330 }
331
332
333
334
335
336
337
338
339 func defaultlit2(l ir.Node, r ir.Node, force bool) (ir.Node, ir.Node) {
340 if l.Type() == nil || r.Type() == nil {
341 return l, r
342 }
343
344 if !l.Type().IsInterface() && !r.Type().IsInterface() {
345
346 if l.Type().IsBoolean() != r.Type().IsBoolean() {
347 return l, r
348 }
349 if l.Type().IsString() != r.Type().IsString() {
350 return l, r
351 }
352 }
353
354 if !l.Type().IsUntyped() {
355 r = convlit(r, l.Type())
356 return l, r
357 }
358
359 if !r.Type().IsUntyped() {
360 l = convlit(l, r.Type())
361 return l, r
362 }
363
364 if !force {
365 return l, r
366 }
367
368
369 if ir.IsNil(l) || ir.IsNil(r) {
370 return l, r
371 }
372 t := defaultType(mixUntyped(l.Type(), r.Type()))
373 l = convlit(l, t)
374 r = convlit(r, t)
375 return l, r
376 }
377
378 func mixUntyped(t1, t2 *types.Type) *types.Type {
379 if t1 == t2 {
380 return t1
381 }
382
383 rank := func(t *types.Type) int {
384 switch t {
385 case types.UntypedInt:
386 return 0
387 case types.UntypedRune:
388 return 1
389 case types.UntypedFloat:
390 return 2
391 case types.UntypedComplex:
392 return 3
393 }
394 base.Fatalf("bad type %v", t)
395 panic("unreachable")
396 }
397
398 if rank(t2) > rank(t1) {
399 return t2
400 }
401 return t1
402 }
403
404 func defaultType(t *types.Type) *types.Type {
405 if !t.IsUntyped() || t.Kind() == types.TNIL {
406 return t
407 }
408
409 switch t {
410 case types.UntypedBool:
411 return types.Types[types.TBOOL]
412 case types.UntypedString:
413 return types.Types[types.TSTRING]
414 case types.UntypedInt:
415 return types.Types[types.TINT]
416 case types.UntypedRune:
417 return types.RuneType
418 case types.UntypedFloat:
419 return types.Types[types.TFLOAT64]
420 case types.UntypedComplex:
421 return types.Types[types.TCOMPLEX128]
422 }
423
424 base.Fatalf("bad type %v", t)
425 return nil
426 }
427
428
429 func IndexConst(n ir.Node) int64 {
430 return ir.IntVal(types.Types[types.TINT], toint(n.Val()))
431 }
432
433
434 func callOrChan(n ir.Node) bool {
435 switch n.Op() {
436 case ir.OAPPEND,
437 ir.OCALL,
438 ir.OCALLFUNC,
439 ir.OCALLINTER,
440 ir.OCALLMETH,
441 ir.OCAP,
442 ir.OCLEAR,
443 ir.OCLOSE,
444 ir.OCOMPLEX,
445 ir.OCOPY,
446 ir.ODELETE,
447 ir.OIMAG,
448 ir.OLEN,
449 ir.OMAKE,
450 ir.OMAX,
451 ir.OMIN,
452 ir.ONEW,
453 ir.OPANIC,
454 ir.OPRINT,
455 ir.OPRINTLN,
456 ir.OREAL,
457 ir.ORECOVER,
458 ir.ORECOVERFP,
459 ir.ORECV,
460 ir.OUNSAFEADD,
461 ir.OUNSAFESLICE,
462 ir.OUNSAFESLICEDATA,
463 ir.OUNSAFESTRING,
464 ir.OUNSAFESTRINGDATA:
465 return true
466 }
467 return false
468 }
469
View as plain text