Skip to content

Commit 818f63d

Browse files
committed
v3: verify shared vlib fallback inputs
1 parent 906c937 commit 818f63d

4 files changed

Lines changed: 84 additions & 26 deletions

File tree

vlib/v/builder/c_error_report.v

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -576,16 +576,16 @@ fn (b &Builder) matches_v3_fallback_inputs(report ExternalCErrorBugReport) bool
576576
return false
577577
}
578578
mut stable_digests := map[string]string{}
579-
vlib_root := os.real_path(os.join_path(b.pref.vroot, 'vlib')).trim_right(os.path_separator)
579+
builtin_root :=
580+
os.real_path(os.join_path(b.pref.vroot, 'vlib', 'builtin')).trim_right(os.path_separator)
580581
for file in b.parsed_files {
581582
if file.path == '' || file.source_digest == '' {
582583
continue
583584
}
584585
path := os.real_path(file.path)
585-
// Mirror macos_v3_fallback_report_sources: V1 and V3 intentionally parse
586-
// different bundled compiler-support files, so compare only caller/project and
587-
// installed-module inputs.
588-
if path == vlib_root || path.starts_with(vlib_root + os.path_separator) {
586+
// Mirror macos_v3_fallback_report_sources: only the opposite v3_backend
587+
// ownership-interface variants intentionally differ between the compilers.
588+
if v3_fallback_backend_specific_builtin_source(path, builtin_root) {
589589
continue
590590
}
591591
if previous := stable_digests[path] {
@@ -606,6 +606,11 @@ fn (b &Builder) matches_v3_fallback_inputs(report ExternalCErrorBugReport) bool
606606
return true
607607
}
608608

609+
fn v3_fallback_backend_specific_builtin_source(path string, builtin_root string) bool {
610+
return (path == builtin_root || path.starts_with(builtin_root + os.path_separator))
611+
&& os.file_name(path) in ['ownership_interface_d_v3_backend.v', 'ownership_interface_notd_v3_backend.v']
612+
}
613+
609614
fn discard_unverified_v3_fallback_report() {
610615
eprintln('note: source inputs changed before the stable compiler retry completed; the V3 fallback report was not submitted.')
611616
}

vlib/v/builder/c_error_report_test.v

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,10 @@ fn test_v3_fallback_input_verification_uses_stable_parser_digests() {
378378
vroot := os.real_path(@VEXEROOT)
379379
path := os.real_path(os.join_path(os.temp_dir(), 'v3_retry_input_main.v'))
380380
parsed_digest := sha256.hexhash('the exact stable parser bytes')
381+
shared_builtin_path := os.real_path(os.join_path(vroot, 'vlib', 'builtin', 'builtin.v'))
382+
shared_builtin_digest := sha256.hexhash('shared builtin parser bytes')
383+
shared_vlib_path := os.real_path(os.join_path(vroot, 'vlib', 'os', 'os.v'))
384+
shared_vlib_digest := sha256.hexhash('shared vlib parser bytes')
381385
b := &Builder{
382386
pref: &pref.Preferences{
383387
vroot: vroot
@@ -387,25 +391,53 @@ fn test_v3_fallback_input_verification_uses_stable_parser_digests() {
387391
path: path
388392
source_digest: parsed_digest
389393
},
390-
// Bundled vlib support files intentionally differ between V1 and V3 and are
391-
// excluded from both input sets.
392394
&ast.File{
393-
path: os.join_path(vroot, 'vlib', 'builtin', 'builtin.v')
394-
source_digest: sha256.hexhash('stable compiler builtin')
395+
path: shared_builtin_path
396+
source_digest: shared_builtin_digest
397+
},
398+
// V1 and V3 select opposite versions of this internal interface.
399+
&ast.File{
400+
path: os.join_path(vroot, 'vlib', 'builtin',
401+
'ownership_interface_notd_v3_backend.v')
402+
source_digest: sha256.hexhash('stable compiler interface')
403+
},
404+
&ast.File{
405+
path: shared_vlib_path
406+
source_digest: shared_vlib_digest
395407
},
396408
]
397409
}
398410
matching := ExternalCErrorBugReport{
399411
input_digests: {
400-
path: parsed_digest
412+
path: parsed_digest
413+
shared_builtin_path: shared_builtin_digest
414+
shared_vlib_path: shared_vlib_digest
401415
}
402416
input_digests_complete: true
403417
}
404418
assert b.matches_v3_fallback_inputs(matching)
405419
assert !b.matches_v3_fallback_inputs(ExternalCErrorBugReport{
406420
...matching
407421
input_digests: {
408-
path: sha256.hexhash('rewritten after V3')
422+
path: sha256.hexhash('rewritten after V3')
423+
shared_builtin_path: shared_builtin_digest
424+
shared_vlib_path: shared_vlib_digest
425+
}
426+
})
427+
assert !b.matches_v3_fallback_inputs(ExternalCErrorBugReport{
428+
...matching
429+
input_digests: {
430+
path: parsed_digest
431+
shared_builtin_path: sha256.hexhash('rewritten shared builtin')
432+
shared_vlib_path: shared_vlib_digest
433+
}
434+
})
435+
assert !b.matches_v3_fallback_inputs(ExternalCErrorBugReport{
436+
...matching
437+
input_digests: {
438+
path: parsed_digest
439+
shared_builtin_path: shared_builtin_digest
440+
shared_vlib_path: sha256.hexhash('rewritten shared vlib')
409441
}
410442
})
411443
assert !b.matches_v3_fallback_inputs(ExternalCErrorBugReport{

vlib/v3/driver/driver.v

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6395,16 +6395,15 @@ fn request_macos_v3_c_error_fallback_from_message(fallback_file string, report_d
63956395
fn macos_v3_fallback_report_sources(a &flat.FlatAst, vroot string) map[string]string {
63966396
mut sources := map[string]string{}
63976397
mut ambiguous := map[string]bool{}
6398-
vlib_root := os.real_path(os.join_path(vroot, 'vlib')).trim_right(os.path_separator)
6398+
builtin_root :=
6399+
os.real_path(os.join_path(vroot, 'vlib', 'builtin')).trim_right(os.path_separator)
63996400
for _, file in a.source_files {
64006401
if (file.name.ends_with('.v') || file.name.ends_with('.vv')
64016402
|| file.name.ends_with('.vsh')) && file.has_source_sha256() {
64026403
path := os.real_path(file.name)
6403-
// V1 and V3 deliberately select different compiler-support implementations
6404-
// below the bundled vlib (for example V3's preallocated builtin). They are not
6405-
// caller inputs and cannot be required to appear in both ASTs. Project and
6406-
// installed-module sources remain covered, including directory builds.
6407-
if path == vlib_root || path.starts_with(vlib_root + os.path_separator) {
6404+
// V1 and V3 select opposite v3_backend ownership-interface files. All other
6405+
// bundled vlib sources are shared inputs and remain covered by verification.
6406+
if v3_fallback_backend_specific_builtin_source(path, builtin_root) {
64086407
continue
64096408
}
64106409
source_digest := file.source_sha256()
@@ -6424,6 +6423,11 @@ fn macos_v3_fallback_report_sources(a &flat.FlatAst, vroot string) map[string]st
64246423
return sources
64256424
}
64266425

6426+
fn v3_fallback_backend_specific_builtin_source(path string, builtin_root string) bool {
6427+
return (path == builtin_root || path.starts_with(builtin_root + os.path_separator))
6428+
&& os.file_name(path) in ['ownership_interface_d_v3_backend.v', 'ownership_interface_notd_v3_backend.v']
6429+
}
6430+
64276431
fn input_uses_minimal_literal_output_builtin(input_file string, prefs &pref.Preferences, is_test_command bool, is_checker_fixture bool) bool {
64286432
if prefs.backend != 'c' || prefs.target.os != 'macos' || is_test_command || is_checker_fixture
64296433
|| !(input_file.ends_with('.v') || input_file.ends_with('.vv')) || !os.is_file(input_file)

vlib/v3/driver/environment_test.v

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,29 +99,46 @@ fn test_macos_v3_fallback_report_sources_keep_parser_digests() {
9999
os.rmdir_all(root) or {}
100100
}
101101
path := os.join_path(root, 'main.v')
102-
vlib_path := os.join_path(root, 'vlib', 'builtin', 'internal.v')
103-
os.mkdir_all(os.dir(vlib_path))!
102+
backend_builtin_path := os.join_path(root, 'vlib', 'builtin',
103+
'ownership_interface_d_v3_backend.v')
104+
shared_builtin_path := os.join_path(root, 'vlib', 'builtin', 'internal.v')
105+
shared_vlib_path := os.join_path(root, 'vlib', 'os', 'shared.v')
106+
os.mkdir_all(os.dir(backend_builtin_path))!
107+
os.mkdir_all(os.dir(shared_vlib_path))!
104108
parsed_source := 'module main\nfn main() { println(42) }\n'
109+
shared_builtin_source := 'module builtin\nfn shared_builtin_input() {}\n'
110+
shared_vlib_source := 'module os\nfn shared_input() {}\n'
105111
os.write_file(path, parsed_source)!
106-
os.write_file(vlib_path, 'module builtin\nfn internal_only() {}\n')!
112+
os.write_file(backend_builtin_path, 'module builtin\nfn v3_backend_only() {}\n')!
113+
os.write_file(shared_builtin_path, shared_builtin_source)!
114+
os.write_file(shared_vlib_path, shared_vlib_source)!
107115
prefs := pref.new_preferences()
108116
mut p := parser.Parser.new(prefs)
109117
p.parse_into(path)
110-
p.parse_into(vlib_path)
118+
p.parse_into(backend_builtin_path)
119+
p.parse_into(shared_builtin_path)
120+
p.parse_into(shared_vlib_path)
111121
assert p.diagnostics.len == 0, p.diagnostics.str()
112122
// Replacing the file after parsing must not change the staged digest.
113123
os.write_file(path, parsed_source.replace('42', 'private_value'))!
114124
sources := macos_v3_fallback_report_sources(p.a, root)
115125
real_path := os.real_path(path)
116126
assert sources[real_path] == sha256.hexhash(parsed_source)
117127
assert sources[real_path] != sha256.hexhash(os.read_file(path)!)
118-
// Bundled compiler-support sources deliberately differ between V1 and V3 and are
119-
// not caller inputs, so they do not make every exact-source verification fail.
120-
assert os.real_path(vlib_path) !in sources
128+
// Only the opposite v3_backend compiler-support variants are excluded. Shared
129+
// builtin and other bundled vlib inputs remain protected by their parser digests.
130+
assert os.real_path(backend_builtin_path) !in sources
131+
assert sources[os.real_path(shared_builtin_path)] == sha256.hexhash(shared_builtin_source)
132+
assert sources[os.real_path(shared_vlib_path)] == sha256.hexhash(shared_vlib_source)
121133
report_dir := os.join_path(root, 'report')
122134
assert stage_macos_v3_fallback_source_digests(report_dir, sources)
123-
assert os.read_file(os.join_path(report_dir, macos_v3_c_error_v_sources_file))! == real_path
124-
assert os.read_file(os.join_path(report_dir, macos_v3_c_error_v_source_digests_file))! == sha256.hexhash(parsed_source)
135+
staged_paths := os.read_file(os.join_path(report_dir, macos_v3_c_error_v_sources_file))!
136+
staged_digests :=
137+
os.read_file(os.join_path(report_dir, macos_v3_c_error_v_source_digests_file))!
138+
assert staged_paths == [real_path, os.real_path(shared_builtin_path),
139+
os.real_path(shared_vlib_path)].join('\x00')
140+
assert staged_digests == [sha256.hexhash(parsed_source), sha256.hexhash(shared_builtin_source),
141+
sha256.hexhash(shared_vlib_source)].join('\x00')
125142
}
126143

127144
fn test_parallel_cc_external_definition_precheck_uses_active_ast_directives() {

0 commit comments

Comments
 (0)