Skip to content

Commit 0bfd9c0

Browse files
authored
Handle duplicate module names in the project file. (rems-project#1551)
* Handle duplicate module names in the project file. A missed check would result in an uncaught `Not_found` exception when the `id` for the first module was looked up after the duplicate shadowed it in the StringMap. * Complete the test script in test/project. * Add test case for duplicate module names in project file.
1 parent d641d17 commit 0bfd9c0

File tree

5 files changed

+57
-2
lines changed

5 files changed

+57
-2
lines changed

src/lib/project.ml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,21 @@ let initialize_project_structure ~variables defs =
588588
let _ = visit_defs (new order_visitor xs) defs in
589589
let names = Array.of_list (List.rev !xs) in
590590
let ids =
591-
snd (Array.fold_left (fun (n, m) name -> (n + 1, StringMap.add (fst name) n m)) (0, StringMap.empty) names)
591+
snd
592+
(Array.fold_left
593+
(fun ((n, d), m) (name, loc) ->
594+
if StringMap.mem name d then
595+
raise
596+
(Reporting.err_general (to_loc loc)
597+
("Duplicate module name '" ^ name ^ "', previously defined at\n"
598+
^ Reporting.loc_to_string (to_loc (StringMap.find name d))
599+
)
600+
);
601+
((n + 1, StringMap.add name loc d), StringMap.add name n m)
602+
)
603+
((0, StringMap.empty), StringMap.empty)
604+
names
605+
)
592606
in
593607
(* Evaluate the expressions in the project file *)
594608
let defs = visit_defs (new eval_visitor variables) defs in
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Error:
2+
failure/duplicate.sail_project:4.0-1:
3+
4 |A {
4+
 |^
5+
 | Duplicate module name 'A', previously defined at
6+
 | failure/duplicate.sail_project:1.0-1:
7+
 | 1 |A {
8+
 |  |^
9+
 |  |
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
A {
2+
}
3+
4+
A {
5+
}

test/project/run_tests.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,30 @@
1818

1919
print("Sail is {}".format(sail))
2020
print("Sail dir is {}".format(sail_dir))
21+
22+
def test_project():
23+
banner('Testing project')
24+
results = Results('project')
25+
for filenames in chunks(os.listdir('failure'), parallel()):
26+
tests = {}
27+
for filename in filenames:
28+
basename = os.path.splitext(os.path.basename(filename))[0]
29+
tests[filename] = os.fork()
30+
if tests[filename] == 0:
31+
step('\'{}\' failure/{} 2> failure/{}.error'.format(sail, filename, basename), expected_status = 1)
32+
step('diff failure/{}.expect failure/{}.error'.format(basename, basename))
33+
step('rm failure/{}.error'.format(basename))
34+
print_ok(filename)
35+
sys.exit(0)
36+
results.collect(tests)
37+
return results.finish()
38+
39+
xml = '<testsuites>\n'
40+
41+
xml += test_project()
42+
43+
xml += '</testsuites>\n'
44+
45+
output = open('tests.xml', 'w')
46+
output.write(xml)
47+
output.close()

test/sailtest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def chunks(filenames, cores):
9292
chunk = []
9393
for filename in filenames:
9494
basename = os.path.splitext(os.path.basename(filename))[0]
95-
if re.match(r'.+\.sail$', filename) and (not args.test or basename in args.test):
95+
if (re.match(r'.+\.sail$', filename) or re.match(r'.+\.sail_project$', filename)) and (not args.test or basename in args.test):
9696
chunk.append(filename)
9797
if len(chunk) >= cores:
9898
ys.append(list(chunk))

0 commit comments

Comments
 (0)