Skip to content

Commit a9a01a3

Browse files
committed
cmd/compile: remove now-unneeded SetHasTParam() for cached ptr element
We had code in NewPtr() to set the HasTParam/HasShape flag as needed for the cached ptr element if it wasn't set correctly based on its Elem. This was causing the race mentioned in the issue. But that setting code is no longer needed, as long as we call SetRParams() soon after calling NewIncompleteNamedType(), before creating/translating the underlying type (which we do). The HasTParam/HasShape attribute can only come from setting of rparams or a direct typeparam/shape somewhere in the underlying type, both of which don't depend on recursion, etc. (as long as the rparams are set early). Added a check that HasTParam/HasShape are set correctly for the cached pointer/slice elems in NewPtr() and NewSlice(). Fixes #48191 Change-Id: Ide7d82efb77ae97901e75b2e6c65bd1bfc25e0ee Reviewed-on: https://go-review.googlesource.com/c/go/+/348089 Trust: Dan Scales <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
1 parent dcf3545 commit a9a01a3

File tree

3 files changed

+278
-9
lines changed

3 files changed

+278
-9
lines changed

src/cmd/compile/internal/typecheck/iimport.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1757,7 +1757,10 @@ func builtinCall(pos src.XPos, op ir.Op) *ir.CallExpr {
17571757
}
17581758

17591759
// NewIncompleteNamedType returns a TFORW type t with name specified by sym, such
1760-
// that t.nod and sym.Def are set correctly.
1760+
// that t.nod and sym.Def are set correctly. If there are any RParams for the type,
1761+
// they should be set soon after creating the TFORW type, before creating the
1762+
// underlying type. That ensures that the HasTParam and HasShape flags will be set
1763+
// properly, in case this type is part of some mutually recursive type.
17611764
func NewIncompleteNamedType(pos src.XPos, sym *types.Sym) *types.Type {
17621765
name := ir.NewDeclNameAt(pos, ir.OTYPE, sym)
17631766
forw := types.NewNamed(name)

src/cmd/compile/internal/types/type.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,9 @@ func NewSlice(elem *Type) *Type {
643643
if t.Elem() != elem {
644644
base.Fatalf("elem mismatch")
645645
}
646+
if elem.HasTParam() != t.HasTParam() || elem.HasShape() != t.HasShape() {
647+
base.Fatalf("Incorrect HasTParam/HasShape flag for cached slice type")
648+
}
646649
return t
647650
}
648651

@@ -735,14 +738,8 @@ func NewPtr(elem *Type) *Type {
735738
if t.Elem() != elem {
736739
base.Fatalf("NewPtr: elem mismatch")
737740
}
738-
if elem.HasTParam() {
739-
// Extra check when reusing the cache, since the elem
740-
// might have still been undetermined (i.e. a TFORW type)
741-
// when this entry was cached.
742-
t.SetHasTParam(true)
743-
}
744-
if elem.HasShape() {
745-
t.SetHasShape(true)
741+
if elem.HasTParam() != t.HasTParam() || elem.HasShape() != t.HasShape() {
742+
base.Fatalf("Incorrect HasTParam/HasShape flag for cached pointer type")
746743
}
747744
return t
748745
}

test/typeparam/issue48191.go

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
// compile -c=2 -G=3
2+
3+
// Copyright 2021 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package main
8+
9+
type I1 interface {
10+
int8 | int16 | int32 | int64 | int | uint
11+
}
12+
type I2 interface{ float32 | float64 }
13+
type I3 interface{ string }
14+
15+
func F[G1 I1, G2 I2, G3 I3]() {
16+
var m0 map[G2]rune
17+
var ch0, ch1 chan bool
18+
var ast0, ast1 []struct{ s0 G3 }
19+
var ai64_2 []int64
20+
var m1, m2, m3 map[bool]map[int]struct {
21+
m0 map[G2]byte
22+
s1 G3
23+
}
24+
var i8_0, i8_1 G1
25+
var i16_0 int16
26+
var am3, am4 []map[float64]map[G2]*func(*byte, map[uint]int64, G3, struct{}) G2
27+
var pi64_0, pi64_1 *int64
28+
var i, i1, i2 int
29+
var as5, as6, as7 []G3
30+
var ch2, ch3, ch4 chan uint
31+
var m4, m5, m6 map[G1]chan bool
32+
33+
if func(G2, int32) byte {
34+
return m1[false][30].m0[G2(28.6)] * m3[func(bool, uint) bool {
35+
return false
36+
}(false, uint(94))][31].m0[G2(185.0)] * m1[(true || true) && (false && false)][51-i2].m0[G2(278.6)]
37+
}(G2(672.5), int32(35)) < m3[<-m5[func(int64, int64) G1 {
38+
return i8_1
39+
}(*pi64_0, int64(50))]][15&i1^i2^i2].m0[G2(895.3)] || (func(int64, uint) uint {
40+
return uint(94)
41+
}(int64(30), uint(95))&^<-ch2^<-ch4)&<-ch2^<-ch4 == <-ch2 {
42+
var f0 float64
43+
var pf2 *float64
44+
var ch5, ch6 chan int16
45+
var fnc0 func(*int64, G2, struct {
46+
i8_0 G1
47+
m1 map[float64]bool
48+
i64_2 int64
49+
}, map[byte]func(G2, float64, *uint, float64) struct{}) complex128 = func(p0 *int64, p1 G2, p2 struct {
50+
i8_0 G1
51+
m1 map[float64]bool
52+
i64_2 int64
53+
}, p3 map[byte]func(G2, float64, *uint, float64) struct{}) complex128 {
54+
p0 = pi64_1
55+
m5 = map[G1]chan bool{(p2.i8_0 + i8_1 + i8_1 ^ i8_1) * p2.i8_0 / p2.i8_0: m4[p2.i8_0>><-ch2]}
56+
return (2.65i - 31.18i) * func(byte, byte) complex128 {
57+
return 13.12i - 32.90i + (44.15i - 70.53i - (87.16i*92.67i + (24.18i - 9.13i))) + (func(G1, int16) complex128 {
58+
return 55.80i
59+
}(G1(30), int16(80)) + 8.48i*79.18i + (37.30i*73.81i + (21.01i - 76.30i)) + func(G3, G2) complex128 {
60+
return 35.58i
61+
}(G3("2JYizeFiEMvXLkUR"), p1)*(81.59i-21.76i))
62+
}(m1[<-m5[G1(37)*i8_1<<i8_1%p2.i8_0]][i2].m0[p1], m1[<-ch0][55&i2/i2^i].m0[func(G3, float64) G2 {
63+
return G2(619.2)
64+
}(G3(""), 954.0)])
65+
}
66+
var m7 map[G2]int64
67+
var ch7 chan byte
68+
var fnc1 func(bool, func(chan G2, struct {
69+
h0 G2
70+
}, int64) **rune, int) map[complex128]int32 = func(p0 bool, p1 func(chan G2, struct {
71+
h0 G2
72+
}, int64) **rune, p2 int) map[complex128]int32 {
73+
pf2 = pf2
74+
as7 = as7
75+
return map[complex128]int32{(94.02i - 22.19i) * (fnc0(pi64_0, G2(554.1)*G2(i1), struct {
76+
i8_0 G1
77+
m1 map[float64]bool
78+
i64_2 int64
79+
}{G1(68)*i8_0 ^ i8_0, map[float64]bool{f0: <-m6[G1(33)]}, (int64(40) ^ ai64_2[77]) % *pi64_1}, map[byte]func(G2, float64, *uint, float64) struct {
80+
}{func(float64, float64) byte {
81+
return byte(32)
82+
}(878.2, 984.4) + m3[true][12].m0[G2(594.0)]: nil}) - (fnc0(pi64_0, G2(241.1)+G2(i2), struct {
83+
i8_0 G1
84+
m1 map[float64]bool
85+
i64_2 int64
86+
}{i8_0, map[float64]bool{904.1: false}, int64(83) + m7[G2(357.7)]}, map[byte]func(G2, float64, *uint, float64) struct {
87+
}{byte(85) | m1[true][99].m0[G2(372.7)]: nil}) - (fnc0(pi64_0, G2(239.9), struct {
88+
i8_0 G1
89+
m1 map[float64]bool
90+
i64_2 int64
91+
}{G1(68), map[float64]bool{555.6: false}, int64(0)}, map[byte]func(G2, float64, *uint, float64) struct {
92+
}{byte(18) & <-ch7: nil}) + (88.17i - 0.55i)))): int32(73) % int32(i)}
93+
}
94+
as5[54] = as6[(len(func(bool, G2) G3 {
95+
return G3("")
96+
}(false, G2(190.8)))|i1^i1)%i1-i1] + m2[68 != i || 'M'&'\xf4'|'H'&'\u1311' >= '4'&'\uab3e'>>uint(83) && (<-m6[G1(24)%i8_0] && <-ch1)][i].s1
97+
i = len([]G3{ast1[2].s0})
98+
i16_0 = <-ch6 / i16_0 & <-ch6
99+
i = (i1^i|i2|i2)/i + i
100+
m6 = m4
101+
am3 = am3
102+
m1[G2(869.6) == G2(i2)] = m2[func(float64, rune) byte {
103+
return func(G3, byte) byte {
104+
return byte(42)
105+
}(G3("8iDnlygG194xl"), byte(89))
106+
}(*pf2, '\u9cf4')/m1[func(G3, float64) bool {
107+
return false
108+
}(G3("6MbwBSHYzr9t0zD"), 774.4)][76].m0[G2(508.0)]/m2[<-m4[i8_0]][92&^i2].m0[G2(807.0)] > m3[(int32(39)|int32(i2))&^int32(i2) < int32(i2)][89*i1&i2].m0[G2(327.5)]]
109+
m2[<-m4[func(G1, complex128) G1 {
110+
return i8_1
111+
}(i8_0, 35.01i)] && <-m4[func(int, G1) G1 {
112+
return G1(0)
113+
}(10, G1(70))*i8_1&i8_1>><-ch2] || fnc0(pi64_0, G2(689.5), struct {
114+
i8_0 G1
115+
m1 map[float64]bool
116+
i64_2 int64
117+
}{(G1(78)*i8_1 - i8_1) / i8_1, map[float64]bool{499.2: <-m6[G1(88)^i8_0]}, int64(83) &^ ai64_2[33] & *pi64_1 * ai64_2[i1]}, map[byte]func(G2, float64, *uint, float64) struct {
118+
}{m1[len(G3("bNIJZq")+G3("Fri5pn1MsZzYtsaV7b")) >= i][i^i1].m0[G2(691.7)]: nil}) != 71.77i-34.84i] = map[int]struct {
119+
m0 map[G2]byte
120+
s1 G3
121+
}{((18+i2)&^i2%i2 ^ i) / i: m3[(G2(267.1)*G2(i1) > G2(i2) || (false || true || (true || false))) && func(int32, int64) bool {
122+
return <-ch0
123+
}(int32(63), ai64_2[61&^i1&i2])][i|i^i1]}
124+
i2 = 90 - i1
125+
_, _, _, _, _, _, _, _ = f0, pf2, ch5, ch6, fnc0, m7, ch7, fnc1
126+
} else {
127+
var m7 map[G1]chan uint
128+
var ch5, ch6, ch7 chan G3
129+
var i32_0, i32_1 int32
130+
var m8, m9, m10 map[bool]struct {
131+
}
132+
pi64_1 = pi64_0
133+
m6[func(G3, G2) G1 {
134+
return (G1(35) | i8_0) << i8_1 / i8_1 &^ i8_1 / i8_1
135+
}(G3("YBiKg"), G2(122.6))] = make(chan bool)
136+
ast0 = ast0
137+
i8_1 = (((G1(10)+i8_1)&i8_0+i8_0)&i8_0&i8_1 ^ i8_1) & i8_1
138+
am4 = am3
139+
i32_1 = int32(10) &^ i32_0
140+
m8[func(float64, G3) bool {
141+
return func(rune, int16) bool {
142+
return (G2(267.0)*G2(i2) == G2(i) || func(G2, G3) bool {
143+
return <-ch0
144+
}(G2(53.3), <-ch5)) && func(G2, G1) int32 {
145+
return int32(63)
146+
}(G2(804.8), G1(2))-i32_0 < i32_1
147+
}('\xbd', i16_0)
148+
}(370.9, ast0[len([]complex128{})+i-i2].s0) && (G2(245.0)-G2(i1) == G2(i1) || byte(17)&m2[false][26].m0[G2(628.5)] > m3[false][55].m0[G2(608.8)] || func(G1, G1) bool {
149+
return true
150+
}(G1(24), G1(2)) || (<-m5[G1(38)] || <-ch1) && func(int32, int) bool {
151+
return false && true
152+
}(int32(6), i1) && '\x26'&'\x27'|func(G2, G3) rune {
153+
return '\x13'
154+
}(G2(229.6), G3("ys1msVeg61uSImCDkRG3C")) <= 'V'>>uint(88)-('\xbe'+'\uafd4')) == (53.04i == 37.22i)] = m8[func(byte, int64) bool {
155+
return <-ch1
156+
}(m3[false && false][96].m0[G2(147.6)], *pi64_0) && 643.5 > float64(i1) && (<-ch0 && <-ch1)]
157+
i8_1 = func(byte, uint) G1 {
158+
return G1(68)
159+
}(m2[<-ch1 || <-m5[G1(96)+i8_0] || func(bool, int32) bool {
160+
return func(int, byte) bool {
161+
return m1[true][89].s1 <= G3("2ZMnHGOMQnyHSbJ")
162+
}(i2, m2[<-m6[G1(47)]][94].m0[G2(981.3)])
163+
}(<-m4[G1(0)&^i8_0&i8_0], i32_0)][i2%i&^i].m0[func(complex128, rune) G2 {
164+
return G2(93.1) * G2(i2)
165+
}(4.63i, m0[G2(975.8)])], uint(21))
166+
_, _, _, _, _, _, _, _, _ = m7, ch5, ch6, ch7, i32_0, i32_1, m8, m9, m10
167+
}
168+
169+
if *pi64_0>><-ch3 <= *pi64_0 || func(bool, int32) int32 {
170+
return (int32(69)&^int32(i2) + int32(i2)) * int32(i2)
171+
}(true, int32(49))^int32(i2) >= int32(i) {
172+
var ai8_8, ai8_9 []G1
173+
var pi2, pi3, pi4 *int
174+
var pi8_5, pi8_6 *G1
175+
var i64_0, i64_1 int64
176+
m1[754.8*float64(i2) != float64(i) && 6.26i == 69.99i] = map[int]struct {
177+
m0 map[G2]byte
178+
s1 G3
179+
}{len([]G2{G2(935.9) / G2(i2), func(int64, G2) G2 {
180+
return G2(720.5)
181+
}(int64(36), G2(349.7))})&*pi2 + i2 - i1: m1[(uint(29) >= <-ch4 || int64(45)+ai64_2[18] >= *pi64_1) == (func(G2, G2) bool {
182+
return <-m5[G1(25)]
183+
}(G2(447.2), G2(946.6)) || func(int, int16) bool {
184+
return true
185+
}(40, int16(41)) && byte(51) >= m2[true][13].m0[G2(6.6)])][*pi3]}
186+
am4 = []map[float64]map[G2]*func(*byte, map[uint]int64, G3, struct {
187+
}) G2{am4[i2%*pi3]}
188+
pi2 = &i2
189+
pi64_0 = pi64_1
190+
ai8_8[*pi3] = *pi8_5&ai8_9[(*pi4+*pi3)%*pi3] ^ ai8_8[90+i2|*pi4]
191+
ai64_2 = []int64{}
192+
m4 = m4
193+
pi2 = &i1
194+
pi3 = &i2
195+
_, _, _, _, _, _, _, _, _ = ai8_8, ai8_9, pi2, pi3, pi4, pi8_5, pi8_6, i64_0, i64_1
196+
}
197+
198+
if (true || false || int32(68) > int32(i1) || <-m5[G1(11)-i8_0] && true) && func(int, float64) bool {
199+
return <-m5[(G1(83)-i8_1)&^i8_1]
200+
}(i1, 886.6) || func(byte, int) bool {
201+
return 401.0/float64(i1)/float64(i1)-float64(i) == float64(i2)
202+
}(m1[(G1(85)^i8_1)&^i8_1 <= i8_1][72].m0[G2(617.4)], i1) || (<-m6[(G1(3)|i8_0)>><-ch2%i8_0|i8_0] || <-ch0) {
203+
var ch5 chan map[byte]complex128
204+
var fnc0 func(int32, *map[rune]complex128) complex128
205+
var c0 complex128
206+
var st0, st1, st2 struct {
207+
}
208+
var au8 []uint
209+
var st3, st4, st5 struct {
210+
ph0 *G2
211+
st1 struct {
212+
m0 map[rune]complex128
213+
pch1 *chan int64
214+
m2 map[bool]byte
215+
st3 struct {
216+
ch0 chan func(map[G1]*struct {
217+
pm0 *map[bool]int64
218+
h1 G2
219+
}, struct {
220+
u0 uint
221+
}, uint, float64) *struct {
222+
ch0 chan map[int16]G2
223+
}
224+
i1 int
225+
ch2 chan complex128
226+
}
227+
}
228+
pm2 *map[int64]struct {
229+
s0 G3
230+
pi1 *int
231+
st2 struct {
232+
m0 map[int]map[rune]int64
233+
r1 rune
234+
}
235+
}
236+
}
237+
var am9, am10, am11 []map[uint]int64
238+
m1[G3("E")+(*st4.pm2)[*pi64_0+<-*st3.st1.pch1].s0 < (*st4.pm2)[int64(46)].s0+(G3("4Jsp3pv0x")+G3("MTKt98c")+(G3("E6Nxqpl70")+G3("eXhhxb")))+(G3("siISQNeBXoQIHwGB")+G3("CzocwLRWIUD")+(G3("cDWy3E3qpeJOmw1wP9wZ")+G3("S3ZRONdtB7K1LBC"))+func(G1, uint) G3 {
239+
return m2[false][74].s1
240+
}(G1(9), uint(26)))+func(G2, int) G3 {
241+
return G3("WzncXvaqK4zPn")
242+
}(G2(291.6), i)+(ast1[(40^i1+i1)&^st4.st1.st3.i1].s0+func(byte, int64) G3 {
243+
return m2[207.7 == float64(i2) && (false || false)][i2].s1
244+
}(byte(34), am11[25][func(int32, float64) uint {
245+
return uint(77)
246+
}(int32(29), 403.1)]))] = map[int]struct {
247+
m0 map[G2]byte
248+
s1 G3
249+
}{st3.st1.st3.i1: m2[<-m4[i8_1]][st5.st1.st3.i1-st3.st1.st3.i1-i2]}
250+
st1 = struct {
251+
}{}
252+
pi64_0 = pi64_1
253+
m4 = m6
254+
as7 = as7
255+
m6[(i8_0+i8_0)&^i8_1&^i8_1] = m5[G1(96)^i8_1]
256+
st2 = struct {
257+
}{}
258+
st1 = struct {
259+
}{}
260+
am10 = []map[uint]int64{am9[len((*st4.pm2)[int64(65)].s0)+i], am11[st4.st1.st3.i1%st4.st1.st3.i1^i1]}
261+
i2 = st5.st1.st3.i1*i - st5.st1.st3.i1
262+
_, _, _, _, _, _, _, _, _, _, _, _, _ = ch5, fnc0, c0, st0, st1, st2, au8, st3, st4, st5, am9, am10, am11
263+
}
264+
265+
}
266+
267+
func main() {
268+
F[int16, float32, string]()
269+
}

0 commit comments

Comments
 (0)