cmd/compile: fixes for non-constant Sizeof/Alignof/Offsetof

Includes Robert's suggested fix in validate.go to not fail on
non-constant alignof/offsetof/sizeof calls. Further changes to wait on
transforming these calls until stenciling time, when we can call
EvalConst() to evaluate them once all the relevant types are known.

Added a bunch of new tests for non-constant Sizeof/Alignof/Offsetof.

Fixes #47716

Change-Id: I469af888eb9ce3a853124d919eda753971009b3e
Reviewed-on: https://go-review.googlesource.com/c/go/+/344250
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Trust: Dan Scales <danscales@google.com>
This commit is contained in:
Dan Scales 2021-08-22 11:50:58 -07:00
parent 8157960d7f
commit be1a693477
6 changed files with 95 additions and 5 deletions

View file

@ -138,10 +138,18 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool)
// until arg type known
// OAPPEND: transformAppend requires that the arg is a slice
// ODELETE: transformDelete requires that the arg is a map
// OALIGNOF, OSIZEOF: can be eval'ed to a constant until types known.
switch fun.BuiltinOp {
case ir.OMAKE, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.ODELETE:
case ir.OMAKE, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.ODELETE, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
hasTParam := false
for _, arg := range args {
if fun.BuiltinOp == ir.OOFFSETOF {
// It's the type of left operand of the
// selection that matters, not the type of
// the field itself (which is irrelevant for
// offsetof).
arg = arg.(*ir.SelectorExpr).X
}
if arg.Type().HasTParam() {
hasTParam = true
break