aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/compiler/const_file.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-11-26 11:36:41 +0100
committerDmitry Vyukov <dvyukov@google.com>2024-11-26 11:32:06 +0000
commit7de7a5ecf43a5c41b5170d0cb70cb744fdf9de9f (patch)
tree56ad68cab4305fe256e4cb4ad3133018a14176f1 /pkg/compiler/const_file.go
parent6cf3ac235c99d92976346acbdc153d68fbb2c841 (diff)
pkg/compiler: allow manual consts to override auto-extracted consts
Currently if const values in 2 .const files have different value, the compiler produces an error. This is problematic for auto-extacted consts since we extract them for only 1 arch now. So if a const has different values for different arches, auto-extacted consts may not reflect that, and we can get a mismatch with manual descriptions that has correct values for all arches. So if both manual and auto-extacted consts have different values, silently prefer the manual ones. I've tried to do some whitelisting of consts during auto-extaction, but the list is large and changing over time. This solution is not perfect since the manual descriptions may have a bug, and the mismatch is actually pointing to that bug. Maybe in future we could extract for all arches separately, or do something else. But let's do this for now.
Diffstat (limited to 'pkg/compiler/const_file.go')
-rw-r--r--pkg/compiler/const_file.go37
1 files changed, 25 insertions, 12 deletions
diff --git a/pkg/compiler/const_file.go b/pkg/compiler/const_file.go
index 1968092a4..0220da555 100644
--- a/pkg/compiler/const_file.go
+++ b/pkg/compiler/const_file.go
@@ -26,6 +26,10 @@ type ConstFile struct {
type constVal struct {
name string
vals map[string]uint64 // arch -> value
+ // Set if the value for the arch is weak (come from auto.txt).
+ // Weak values are replaced on mismatch, instead of producing
+ // an error about mismatching values.
+ weak map[string]bool
}
const undefined = "???"
@@ -40,30 +44,38 @@ func NewConstFile() *ConstFile {
func (cf *ConstFile) AddArch(arch string, consts map[string]uint64, undeclared map[string]bool) error {
cf.arches[arch] = true
for name, val := range consts {
- if err := cf.addConst(arch, name, val, true); err != nil {
+ if err := cf.addConst(arch, name, val, true, false); err != nil {
return err
}
}
for name := range undeclared {
- if err := cf.addConst(arch, name, 0, false); err != nil {
+ if err := cf.addConst(arch, name, 0, false, false); err != nil {
return err
}
}
return nil
}
-func (cf *ConstFile) addConst(arch, name string, val uint64, declared bool) error {
+func (cf *ConstFile) addConst(arch, name string, val uint64, declared, weak bool) error {
cv := cf.m[name]
if cv.vals == nil {
cv.name = name
cv.vals = make(map[string]uint64)
- }
- if val0, declared0 := cv.vals[arch]; declared && declared0 && val != val0 {
- return fmt.Errorf("const=%v arch=%v has different values: %v[%v] vs %v[%v]",
- name, arch, val, declared, val0, declared0)
+ cv.weak = make(map[string]bool)
}
if declared {
+ val0, declared0 := cv.vals[arch]
+ if declared0 {
+ if weak {
+ return nil
+ }
+ if !cv.weak[arch] && val != val0 {
+ return fmt.Errorf("const=%v arch=%v has different values: %v[%v] vs %v[%v]",
+ name, arch, val, declared, val0, declared0)
+ }
+ }
cv.vals[arch] = val
+ cv.weak[arch] = weak
}
cf.m[name] = cv
return nil
@@ -196,6 +208,7 @@ func (cf *ConstFile) deserializeFile(data []byte, file, arch string, eh ast.Erro
eh(pos, fmt.Sprintf(msg, args...))
return false
}
+ weak := file == "auto.txt.const"
s := bufio.NewScanner(bytes.NewReader(data))
var arches []string
for ; s.Scan(); pos.Line++ {
@@ -224,7 +237,7 @@ func (cf *ConstFile) deserializeFile(data []byte, file, arch string, eh ast.Erro
}
continue
}
- if !cf.parseConst(arches, name, val, errf) {
+ if !cf.parseConst(arches, name, val, weak, errf) {
return false
}
}
@@ -236,7 +249,7 @@ func (cf *ConstFile) deserializeFile(data []byte, file, arch string, eh ast.Erro
type errft func(msg string, args ...interface{}) bool
-func (cf *ConstFile) parseConst(arches []string, name, line string, errf errft) bool {
+func (cf *ConstFile) parseConst(arches []string, name, line string, weak bool, errf errft) bool {
var dflt map[string]uint64
for _, pair := range strings.Split(line, ",") {
fields := strings.Split(pair, ":")
@@ -274,13 +287,13 @@ func (cf *ConstFile) parseConst(arches []string, name, line string, errf errft)
for _, arch := range fields[:len(fields)-1] {
arch = strings.TrimSpace(arch)
delete(dflt, arch)
- if err := cf.addConst(arch, name, val, defined); err != nil {
+ if err := cf.addConst(arch, name, val, defined, weak); err != nil {
return errf("%v", err)
}
}
}
for arch, val := range dflt {
- if err := cf.addConst(arch, name, val, true); err != nil {
+ if err := cf.addConst(arch, name, val, true, weak); err != nil {
return errf("%v", err)
}
}
@@ -292,7 +305,7 @@ func (cf *ConstFile) parseOldConst(arch, name, line string, errf errft) bool {
if err != nil {
return errf("failed to parse int: %v", err)
}
- if err := cf.addConst(arch, name, val, true); err != nil {
+ if err := cf.addConst(arch, name, val, true, false); err != nil {
return errf("%v", err)
}
return true