Skip to content

Commit 6d7fe40

Browse files
authored
Merge pull request #29 from zeldovich/master
avoid generating unreachable code in MaxSize functions
2 parents a646e1d + 34828ec commit 6d7fe40

File tree

1 file changed

+41
-20
lines changed

1 file changed

+41
-20
lines changed

gen/maxsize.go

+41-20
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,11 @@ func maxSizes(w io.Writer, topics *Topics) *maxSizeGen {
3838

3939
type maxSizeGen struct {
4040
passes
41-
p printer
42-
state maxSizeState
43-
ctx *Context
44-
topics *Topics
41+
p printer
42+
state maxSizeState
43+
ctx *Context
44+
topics *Topics
45+
panicked bool
4546
}
4647

4748
func (s *maxSizeGen) Method() Method { return MaxSize }
@@ -53,7 +54,7 @@ func (s *maxSizeGen) Apply(dirs []string) error {
5354
// this lets us chain together addition
5455
// operations where possible
5556
func (s *maxSizeGen) addConstant(sz string) {
56-
if !s.p.ok() {
57+
if !s.p.ok() || s.panicked {
5758
return
5859
}
5960

@@ -82,6 +83,7 @@ func (s *maxSizeGen) Execute(p Elem) ([]string, error) {
8283
if !s.p.ok() {
8384
return nil, s.p.err
8485
}
86+
s.panicked = false
8587
p = s.applyall(p)
8688
if p == nil {
8789
return nil, nil
@@ -109,13 +111,17 @@ func (s *maxSizeGen) Execute(p Elem) ([]string, error) {
109111
s.p.printf("\nfunc %s (s int) {", getMaxSizeMethod(p.TypeName()))
110112
s.state = assignM
111113
next(s, p)
112-
s.p.nakedReturn()
114+
if s.panicked {
115+
s.p.print("\n}\n")
116+
} else {
117+
s.p.nakedReturn()
118+
}
113119
s.topics.Add(p.TypeName(), getMaxSizeMethod(p.TypeName()))
114120
return nil, s.p.err
115121
}
116122

117123
func (s *maxSizeGen) gStruct(st *Struct) {
118-
if !s.p.ok() {
124+
if !s.p.ok() || s.panicked {
119125
return
120126
}
121127

@@ -134,7 +140,7 @@ func (s *maxSizeGen) gStruct(st *Struct) {
134140
continue
135141
}
136142

137-
if !s.p.ok() {
143+
if !s.p.ok() || s.panicked {
138144
return
139145
}
140146
next(s, st.Fields[i].FieldElem)
@@ -156,19 +162,23 @@ func (s *maxSizeGen) gStruct(st *Struct) {
156162
}
157163

158164
func (s *maxSizeGen) gPtr(p *Ptr) {
165+
if s.panicked {
166+
return
167+
}
159168
s.state = addM // inner must use add
160169
next(s, p.Value)
161170
s.state = addM // closing block; reset to add
162171
}
163172

164173
func (s *maxSizeGen) gSlice(sl *Slice) {
165-
if !s.p.ok() {
174+
if !s.p.ok() || s.panicked {
166175
return
167176
}
168177
s.state = addM
169178
s.p.comment("Calculating size of slice: " + sl.Varname())
170179
if (sl.AllocBound() == "" || sl.AllocBound() == "-") && (sl.MaxTotalBytes() == "" || sl.MaxTotalBytes() == "-") {
171180
s.p.printf("\npanic(\"Slice %s is unbounded\")", sl.Varname())
181+
s.panicked = true
172182
s.state = addM // reset the add to prevent further + expressions from being added to the end the panic statement
173183
return
174184
}
@@ -194,13 +204,14 @@ func (s *maxSizeGen) gSlice(sl *Slice) {
194204
s.addConstant(fmt.Sprintf("((%s) * (%s))", topLevelAllocBound, str))
195205
} else {
196206
s.p.printf("\npanic(\"Unable to determine max size: %s\")", err)
207+
s.panicked = true
197208
}
198209
s.state = addM
199210
return
200211
}
201212

202213
func (s *maxSizeGen) gArray(a *Array) {
203-
if !s.p.ok() {
214+
if !s.p.ok() || s.panicked {
204215
return
205216
}
206217
// If this is not the first line where we define s = ... then we need to reset the state
@@ -216,19 +227,23 @@ func (s *maxSizeGen) gArray(a *Array) {
216227
s.addConstant(fmt.Sprintf("((%s) * (%s))", a.Size, str))
217228
} else {
218229
s.p.printf("\npanic(\"Unable to determine max size: %s\")", err)
219-
230+
s.panicked = true
220231
}
221232
s.state = addM
222233
return
223234
}
224235

225236
func (s *maxSizeGen) gMap(m *Map) {
237+
if s.panicked {
238+
return
239+
}
226240
vn := m.Varname()
227241
s.state = addM
228242
s.addConstant(builtinSize(mapHeader))
229243
topLevelAllocBound := m.AllocBound()
230244
if topLevelAllocBound != "" && topLevelAllocBound == "-" {
231245
s.p.printf("\npanic(\"Map %s is unbounded\")", m.Varname())
246+
s.panicked = true
232247
s.state = addM // reset the add to prevent further + expressions from being added to the end the panic statement
233248
return
234249
}
@@ -241,21 +256,25 @@ func (s *maxSizeGen) gMap(m *Map) {
241256
}
242257
}
243258

244-
s.p.comment("Adding size of map keys for " + vn)
245-
s.p.printf("\ns += %s", topLevelAllocBound)
246-
s.state = multM
247-
next(s, m.Key)
259+
if !s.panicked {
260+
s.p.comment("Adding size of map keys for " + vn)
261+
s.p.printf("\ns += %s", topLevelAllocBound)
262+
s.state = multM
263+
next(s, m.Key)
264+
}
248265

249-
s.p.comment("Adding size of map values for " + vn)
250-
s.p.printf("\ns += %s", topLevelAllocBound)
251-
s.state = multM
252-
next(s, m.Value)
266+
if !s.panicked {
267+
s.p.comment("Adding size of map values for " + vn)
268+
s.p.printf("\ns += %s", topLevelAllocBound)
269+
s.state = multM
270+
next(s, m.Value)
271+
}
253272

254273
s.state = addM
255274
}
256275

257276
func (s *maxSizeGen) gBase(b *BaseElem) {
258-
if !s.p.ok() {
277+
if !s.p.ok() || s.panicked {
259278
return
260279
}
261280
if b.MaxTotalBytes() != "" {
@@ -276,6 +295,7 @@ func (s *maxSizeGen) gBase(b *BaseElem) {
276295
value, err := baseMaxSizeExpr(b.Value, vname, b.BaseName(), b.TypeName(), b.common.AllocBound())
277296
if err != nil {
278297
s.p.printf("\npanic(\"Unable to determine max size: %s\")", err)
298+
s.panicked = true
279299
s.state = addM // reset the add to prevent further + expressions from being added to the end the panic statement
280300
return
281301
}
@@ -290,6 +310,7 @@ func (s *maxSizeGen) gBase(b *BaseElem) {
290310
value, err := baseMaxSizeExpr(b.Value, vname, b.BaseName(), b.TypeName(), b.common.AllocBound())
291311
if err != nil {
292312
s.p.printf("\npanic(\"Unable to determine max size: %s\")", err)
313+
s.panicked = true
293314
s.state = addM // reset the add to prevent further + expressions from being added to the end the panic statement
294315
return
295316
}

0 commit comments

Comments
 (0)