Skip to content

size: fix compile error for a fixed-size convert shim (#446) - #447

Open
youdie006 wants to merge 1 commit into
tinylib:masterfrom
youdie006:fix/446-shim-convert-msgsize
Open

size: fix compile error for a fixed-size convert shim (#446)#447
youdie006 wants to merge 1 commit into
tinylib:masterfrom
youdie006:fix/446-shim-convert-msgsize

Conversation

@youdie006

Copy link
Copy Markdown

Fixes #446.

Problem

A //msgp:shim T as:BASE using:to/from mode:convert directive makes the size generator emit a Msgsize() that declares a temporary for the converted base value and never assigns it. For a fixed-size base (int64, float64, ...) basesizeExpr returns a compile-time constant that ignores the temporary, so the generated code fails to compile:

_generated/convert_gen.go:273:6: declared and not used: zb0001

Fix

In (*sizeGen).gBase, split the mode:convert branch on fixedSize(b.Value). For a fixed-size base the wire size is a constant, so emit it directly (s.addConstant(basesizeExpr(b.Value, "", b.BaseName()))) and skip the temporary entirely.

Variable-size bases are intentionally left as-is (they compile and only under-report the size). Per the discussion on #446, computing their exact size in Msgsize would require calling the shim, which can be more expensive than the resulting under-allocation - so this PR fixes the compile error without adding shim calls to Msgsize.

Test

Added a fixed-size (int64) convert-shim fixture (ConvertIntVal / ConvertInt) to _generated/convert.go and a TestConvertInt round-trip test to _generated/convert_test.go. Red-green verified: go generate ./_generated && go test ./_generated fails to build (declared and not used) with the old generator and passes with the fixed one; ConvertInt.Msgsize() is now the constant 1 + 4 + msgp.Int64Size. gofmt and go vet ./gen are clean.

A "msgp:shim T as:BASE mode:convert" directive made the size generator
emit a Msgsize that declared a temporary for the converted base value and
never assigned it. For a fixed-size base (int64, float64, ...) the size is
a compile-time constant that ignores the temporary, so the generated code
failed to compile with "declared and not used".

For a fixed-size base, emit the constant size directly and skip the
temporary. Variable-size bases are intentionally left as-is: computing
their exact size would require calling the shim in Msgsize, which can be
more expensive than the resulting under-allocation.

Add a fixed-size (int64) convert shim fixture and a round-trip test.

Fixes tinylib#446

@klauspost klauspost left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@klauspost klauspost left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No show-stoppers, but a few easy wins.

Comment thread gen/size.go
Comment on lines +231 to +247
if fixedSize(b.Value) {
// A fixed-size base has a constant wire size, so there is no need
// for a temporary holding the converted value. Emitting an
// (unassigned) temporary left it unused, producing a "declared and
// not used" compile error in the generated Msgsize (#446).
s.addConstant(basesizeExpr(b.Value, "", b.BaseName()))
} else {
s.state = add
vname := randIdent()
s.p.printf("\nvar %s %s", vname, b.BaseType())

// ensure we don't get "unused variable" warnings from outer slice iterations
s.p.printf("\n_ = %s", b.Varname())

s.p.printf("\ns += %s", basesizeExpr(b.Value, vname, b.BaseName()))
s.state = expr
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We can easily avoid the extra indent (and lets keep out the historic stuff from the comments).

Suggested change
if fixedSize(b.Value) {
// A fixed-size base has a constant wire size, so there is no need
// for a temporary holding the converted value. Emitting an
// (unassigned) temporary left it unused, producing a "declared and
// not used" compile error in the generated Msgsize (#446).
s.addConstant(basesizeExpr(b.Value, "", b.BaseName()))
} else {
s.state = add
vname := randIdent()
s.p.printf("\nvar %s %s", vname, b.BaseType())
// ensure we don't get "unused variable" warnings from outer slice iterations
s.p.printf("\n_ = %s", b.Varname())
s.p.printf("\ns += %s", basesizeExpr(b.Value, vname, b.BaseName()))
s.state = expr
}
if fixedSize(b.Value) {
// A fixed-size base has a constant wire size, so there is no need
// for a temporary holding the converted value.
s.addConstant(basesizeExpr(b.Value, "", b.BaseName()))
return
}
s.state = add
vname := randIdent()
s.p.printf("\nvar %s %s", vname, b.BaseType())
// ensure we don't get "unused variable" warnings from outer slice iterations
s.p.printf("\n_ = %s", b.Varname())
s.p.printf("\ns += %s", basesizeExpr(b.Value, vname, b.BaseName()))
s.state = expr

Comment thread _generated/convert.go
// ConvertInt exercises a fixed-size (int64) convert shim, whose generated
// Msgsize must not declare an unused temporary (#446).
type ConvertInt struct {
Int ConvertIntVal

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is free, lets just add a few more types to roundtrip tests:

Suggested change
Int ConvertIntVal
Int ConvertIntVal
Ptr *ConvertIntVal
Map map[string]ConvertIntVal
MapP map[string]*ConvertIntVal
Arr []ConvertIntVal
ArrP []*ConvertIntVal

(needs gofmt)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

shim mode:convert generates Msgsize with an unassigned temporary: compile error on fixed-size bases, silent under-report on variable-size ones

2 participants