Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ checks/testdata/src/ps6133/metal_layout.h text eol=lf
checks/testdata/src/ps6133/vulkan_layout.h text eol=lf
checks/testdata/ps6137_owner_*.txt text eol=lf
checks/testdata/ps6136-owner/**/*.txt text eol=lf
checks/testdata/ps6140-owner/**/*.txt text eol=lf
checks/testdata/src/ps6140/decoder.go text eol=lf
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ jobs:
# Every platform uses two external runners. Stable name hashing keeps
# the package-qualified selections disjoint and exhaustive even if
# independently discovered test-list order differs.
# Bound each inner job to 150 discovered names so large packages run
# Bound each inner job to 100 discovered names so large packages run
# in multiple waves without increasing process concurrency or timeout.
run: go run ./internal/testparallel -race -workers ${{ runner.os == 'macOS' && 2 || 4 }} -max-tests-per-job 150 -shard-index ${{ matrix.shard }} -shard-count 2 ./...
run: go run ./internal/testparallel -race -workers ${{ runner.os == 'macOS' && 2 || 4 }} -max-tests-per-job 100 -shard-index ${{ matrix.shard }} -shard-count 2 ./...

quality:
runs-on: ubuntu-latest
Expand Down
8 changes: 8 additions & 0 deletions benchmarks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,14 @@ Rules without a pair, and why:
campaigns, not a portable toy benchmark or an isolated detector speedup.
Preserve physical ToHost transfer, all native parity/errors, checked shapes
and release/publication; remeasure residency and complete public workloads.
- **PS6140** (unused concrete-projection scratch advisory): source-bound
requested float32 storage and illustrative profile ranking are not native
residency measurements. Full before/after Metal and CUDA owner replay proves
class-specific source uses, not native allocation, finalizer or stream/graph
completion. The issue #890 / GoAI PR1209 figures are attributed owner
measurements. A portable allocation toy cannot qualify deletion safety or
establish an isolated native throughput gain; retain the exact buffer-class
residency tests and alternating same-binary constructor/public-API campaigns.

PS6137 is an opt-in advisory with no automatic replacement benchmark. Its
complete owner cgo/source replay is not a native workload execution. GoAI
Expand Down
34 changes: 33 additions & 1 deletion checks/ps6125_ssa.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,34 @@ type ps6125SSAExtents struct {
// heap/receiver field invariants, effects of opaque calls, allocation lifetimes,
// hotness or runtime no-overflow. Loads and unresolved calls stay unknown.
func ps6125AnalyzeSSAExtents(function *ssa.Function, inputs map[*ssa.Parameter]ps6125Scalar, lengths map[*ssa.Parameter]ps6125Extent) *ps6125SSAExtents {
return ps6125AnalyzeSSAExtentsWithImmutableBools(function, inputs, lengths, nil)
}

// Immutable boolean loads and nil comparisons must be proved for this invocation by the
// caller's complete source effect/ownership analysis. This entry point only
// validates their SSA shape; configuration is not a source proof. All facts
// still participate in the ordinary finite-lattice solver, including joins and
// loop backedges. The original entry point supplies no memory assumptions.
func ps6125AnalyzeSSAExtentsWithImmutableBools(function *ssa.Function, inputs map[*ssa.Parameter]ps6125Scalar, lengths map[*ssa.Parameter]ps6125Extent, immutable map[ssa.Value]bool) *ps6125SSAExtents {
for value := range immutable {
if value == nil || value.Parent() != function || !types.Identical(value.Type(), types.Typ[types.Bool]) {
return nil
}
switch value := value.(type) {
case *ssa.UnOp:
if _, field := value.X.(*ssa.FieldAddr); !field || value.Op != token.MUL {
return nil
}
case *ssa.BinOp:
left, leftNil := value.X.(*ssa.Const)
right, rightNil := value.Y.(*ssa.Const)
if value.Op != token.EQL && value.Op != token.NEQ || !(leftNil && left.IsNil() || rightNil && right.IsNil()) {
return nil
}
default:
return nil
}
}
result := &ps6125SSAExtents{function: function, facts: make(map[ssa.Value]ps6125Scalar), lengths: lengths, blocks: make(map[*ssa.BasicBlock]bool), edges: make(map[ps6125SSAEdge]bool)}
if function == nil || len(function.Blocks) == 0 {
return result
Expand Down Expand Up @@ -97,7 +125,11 @@ func ps6125AnalyzeSSAExtents(function *ssa.Function, inputs map[*ssa.Parameter]p
queued[instruction] = false
if value, ok := instruction.(ssa.Value); ok {
old := result.facts[value]
joined := ps6125JoinScalars(old, result.evaluate(value))
evaluated := result.evaluate(value)
if truth, proved := immutable[value]; proved {
evaluated = ps6125Scalar{state: ps6125Boolean, truth: truth}
}
joined := ps6125JoinScalars(old, evaluated)
// A known lattice element can only stay itself or become unknown.
if joined.state != old.state {
result.facts[value] = joined
Expand Down
15 changes: 15 additions & 0 deletions checks/ps6136.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,21 @@ func ps6136SelectionPath(context *ps6125SSAContext, value ssa.Value, budget int)
if reference.context != context || reference.value != value {
return ps6136SelectionPath(reference.context, reference.value, budget-1)
}
// A constructor may translate its model config into a distinct common
// config value. Follow an exact closed field initializer before composing
// access paths: similarly named fields in the two types are not identities.
var projected ps6125SSAReference
switch source := value.(type) {
case *ssa.Field:
projected = context.structField(source.X, source.Field)
case *ssa.UnOp:
if address, ok := source.X.(*ssa.FieldAddr); ok && source.Op == token.MUL {
projected = context.loadedStructField(address.X, address.Field, source)
}
}
if projected.value != nil && projected != reference {
return ps6136SelectionPath(projected.context, projected.value, budget-1)
}
paths := ps6125AccessPaths{flow: context.flow}
path := paths.resolve(value)
if !path.known {
Expand Down
26 changes: 20 additions & 6 deletions checks/ps6136_compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ func ps6136CompileOwners(t *testing.T, revision string, metalEntry, shared bool)
// Rewrite is only for explicitly altered adversaries. Authentic replay calls
// the nil-rewrite entry above and still compiles complete original owner bodies.
func ps6136CompileOwnersRewrite(t *testing.T, revision string, metalEntry, shared bool, rewrite func(*token.FileSet, []*ast.File) []*ast.File) (*analysisOwnerFixture, error) {
return ps6136CompileOwnersRewriteImports(t, revision, metalEntry, shared, rewrite, nil)
}

// Additional fixture APIs are explicit scaffolding; existing replays use nil.
func ps6136CompileOwnersRewriteImports(t *testing.T, revision string, metalEntry, shared bool, rewrite func(*token.FileSet, []*ast.File) []*ast.File, overrides map[string]string) (*analysisOwnerFixture, error) {
t.Helper()
fs := token.NewFileSet()
data, err := os.ReadFile("testdata/ps6136-owner/" + revision + "/gpt.go.txt")
Expand Down Expand Up @@ -133,8 +138,8 @@ func sampleTopKCandidates(*nlp.Sampler,[]int32,[]float32)int{return 0}
}
}
}
imports := &ps6136FixtureImporter{fallback: importer.Default(), packages: map[string]*types.Package{}, sources: map[string]string{}}
info := &types.Info{Types: map[ast.Expr]types.TypeAndValue{}, Uses: map[*ast.Ident]types.Object{}, Defs: map[*ast.Ident]types.Object{}, Selections: map[*ast.SelectorExpr]*types.Selection{}}
imports := &ps6136FixtureImporter{fallback: importer.Default(), packages: map[string]*types.Package{}, sources: map[string]string{}, overrides: overrides}
info := &types.Info{Types: map[ast.Expr]types.TypeAndValue{}, Uses: map[*ast.Ident]types.Object{}, Defs: map[*ast.Ident]types.Object{}, Selections: map[*ast.SelectorExpr]*types.Selection{}, Implicits: map[ast.Node]types.Object{}}
files := []*ast.File{gpt, support}
if shared {
// Complete, unmodified owner files: no alternate constructor or
Expand Down Expand Up @@ -258,9 +263,10 @@ type analysisOwnerFixture struct {
}

type ps6136FixtureImporter struct {
fallback types.Importer
packages map[string]*types.Package
sources map[string]string
overrides map[string]string
fallback types.Importer
packages map[string]*types.Package
sources map[string]string
}

func (i *ps6136FixtureImporter) Import(path string) (*types.Package, error) {
Expand Down Expand Up @@ -329,7 +335,15 @@ func NewConcurrentRecorder()(*Recorder,error){return nil,nil}
func NewProfilingRecorder(int)(*Recorder,error){return nil,nil}
`
default:
return i.fallback.Import(path)
// Explicit external API overrides may introduce a provider absent from
// the older Metal-only scaffold. Without one, retain the normal importer;
// unknown packages never acquire fabricated APIs implicitly.
if i.overrides[path] == "" {
return i.fallback.Import(path)
}
}
if override := i.overrides[path]; override != "" {
source = override
}
fs := token.NewFileSet()
file, err := parser.ParseFile(fs, path+".go", source, parser.SkipObjectResolution)
Expand Down
61 changes: 61 additions & 0 deletions checks/ps6136_config_translation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package checks

import (
"go/types"
"testing"

"golang.org/x/tools/go/ssa"
)

func TestPS6136ConstructorConfigTranslation(t *testing.T) {
t.Parallel()
for _, test := range []struct {
name, body string
want bool
}{
{"literal", `cfg:=m.Config;c:=commonConfig{Max:cfg.Rows,Dim:cfg.Width};return common(c)`, true},
{"copied-config", `cfg:=m.Config;original:=commonConfig{Max:cfg.Rows,Dim:cfg.Width};c:=original;return common(c)`, true},
{"reordered-fields", `cfg:=m.Config;c:=commonConfig{Dim:cfg.Width,Max:cfg.Rows};return common(c)`, true},
{"forwarded-config", `cfg:=m.Config;c:=commonConfig{Max:cfg.Rows,Dim:cfg.Width};return forward(c)`, true},
{"wrong-field", `cfg:=m.Config;c:=commonConfig{Max:cfg.Rows,Dim:cfg.Other};return common(c)`, false},
{"constant", `cfg:=m.Config;c:=commonConfig{Max:cfg.Rows,Dim:2048};return common(c)`, false},
{"arithmetic", `cfg:=m.Config;c:=commonConfig{Max:cfg.Rows,Dim:cfg.Width+1};return common(c)`, false},
{"foreign-model", `cfg:=other.Config;c:=commonConfig{Max:cfg.Rows,Dim:cfg.Width};return common(c)`, false},
{"overwritten-field", `cfg:=m.Config;c:=commonConfig{Max:cfg.Rows,Dim:cfg.Width};c.Dim=cfg.Other;return common(c)`, false},
{"conditional-field", `cfg:=m.Config;c:=commonConfig{Max:cfg.Rows};if b{c.Dim=cfg.Width};return common(c)`, false},
{"escaped-config", `cfg:=m.Config;c:=commonConfig{Max:cfg.Rows,Dim:cfg.Width};escape(&c);return common(c)`, false},
} {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
pkg := ps6125TestSSA(t, `package extent
type sourceConfig struct{Rows,Width,Other int};type model struct{Config sourceConfig}
type commonConfig struct{Max,Dim int};type owner struct{rows,width int}
func common(c commonConfig)*owner{return &owner{rows:c.Max,width:c.Dim}}
func forward(c commonConfig)*owner{return common(c)};func escape(*commonConfig)
func build(m,other *model,b bool)*owner{`+test.body+`}`)
function := pkg.Func("build")
context := ps6125NewSSAContext(function, nil, nil, 4096)
owner := pkg.Pkg.Scope().Lookup("owner").Type().(*types.Named)
model := pkg.Pkg.Scope().Lookup("model").Type().(*types.Named)
selected := &ps6136Selection{context: context, ownerType: owner, modelType: model, model: context.reference(function.Params[0]), maximumRows: ps6136FieldVar(owner, "rows"), width: ps6136FieldVar(owner, "width"), modelConfig: ps6136FieldVar(model, "Config")}
selected.configRows = ps6136FieldVar(selected.modelConfig.Type(), "Rows")
selected.configWidth = ps6136FieldVar(selected.modelConfig.Type(), "Width")
for _, block := range function.Blocks {
for _, instruction := range block.Instrs {
if returned, ok := instruction.(*ssa.Return); ok {
selected.owner = ps6136OwnerRoot(context, returned.Results[0], owner)
}
}
}
if selected.owner.value == nil {
t.Fatal("actual fresh common constructor owner prerequisite missing")
}
if got := selected.initializationValues(4096); got != test.want {
t.Fatalf("translated config provenance=%v want=%v", got, test.want)
}
if selected.initializationValues(0) {
t.Fatal("exhausted budget admitted")
}
})
}
}
31 changes: 23 additions & 8 deletions checks/ps6136_coverage.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import (
// are supplied only after exact typed argument, extent and ownership checks;
// this routine never interprets configuration as a source proof.
func ps6136ClosedObservations(pass *analysis.Pass, owner *types.Named, workspace *types.Var, proved map[ast.Node]bool) bool {
return ps6136ClosedObservationsCheck(pass, owner, workspace, proved, nil)
}

// The optional diagnostic reports the first rejected source node; it grants no
// approval and preserves the strict observation checks used by the rule.
func ps6136ClosedObservationsCheck(pass *analysis.Pass, owner *types.Named, workspace *types.Var, proved map[ast.Node]bool, rejected func(ast.Node, string)) bool {
if owner == nil || workspace == nil {
return false
}
Expand Down Expand Up @@ -53,6 +59,15 @@ func ps6136ClosedObservations(pass *analysis.Pass, owner *types.Named, workspace
return typ != nil && types.Identical(typ, owner)
}
valid := true
reject := func(node ast.Node, reason string) {
if !valid {
return
}
valid = false
if rejected != nil {
rejected(node, reason)
}
}
for _, file := range pass.Files {
ast.Inspect(file, func(node ast.Node) bool {
if !valid {
Expand All @@ -70,7 +85,7 @@ func ps6136ClosedObservations(pass *analysis.Pass, owner *types.Named, workspace
break
}
if isOwner(pass.TypesInfo.TypeOf(selector.X)) {
valid = false
reject(n, "interior owner field address")
break
}
expression = ps2110Unparen(selector.X)
Expand All @@ -79,27 +94,27 @@ func ps6136ClosedObservations(pass *analysis.Pass, owner *types.Named, workspace
case *ast.SelectorExpr:
selection := pass.TypesInfo.Selections[n]
if selection != nil && selection.Obj() == workspace && !approved(n) {
valid = false
reject(n, "unproved workspace selector")
}
if isOwner(pass.TypesInfo.TypeOf(n)) && !approved(n) {
outer, ok := parents[n].(*ast.SelectorExpr)
if !ok || outer.X != n {
valid = false
reject(n, "whole owner selector exposure")
} else if next := pass.TypesInfo.Selections[outer]; next == nil || next.Kind() != types.FieldVal {
valid = false
reject(n, "owner selector method exposure")
}
}
case *ast.CompositeLit:
if isOwner(pass.TypesInfo.TypeOf(n)) && !approved(n) {
for _, element := range n.Elts {
keyed, ok := element.(*ast.KeyValueExpr)
if !ok {
valid = false
reject(n, "unkeyed owner literal")
break
}
identifier, ok := keyed.Key.(*ast.Ident)
if !ok || pass.TypesInfo.Uses[identifier] == workspace && !proved[keyed.Key] {
valid = false
reject(n, "unproved owner literal workspace")
break
}
}
Expand Down Expand Up @@ -128,12 +143,12 @@ func ps6136ClosedObservations(pass *analysis.Pass, owner *types.Named, workspace
}
selector, ok := parent.(*ast.SelectorExpr)
if !ok {
valid = false // aliases, captures, sends, opaque arguments, whole stores
reject(n, "whole owner identifier exposure") // aliases, captures, sends, opaque arguments, whole stores
break
}
selection := pass.TypesInfo.Selections[selector]
if selection == nil || selection.Kind() != types.FieldVal {
valid = false // implicit-address methods require their exact call proof
reject(n, "implicit owner method exposure") // implicit-address methods require their exact call proof
}
}
return valid
Expand Down
Loading