authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-25 11:53:39+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-30 10:00:50+02:00
logfa09276510b03292ace9b8cc72064341530a1940
tree239c99e3f53c6cac15315d0cc101779debe553b6
parent494ae149e0a52c4afd71f6741379d4a7a9afe3f3

test/link/elf: test COMDAT elimination


1 files changed, 92 insertions(+), 0 deletions(-)

test/link/elf.zig+92
......@@ -59,6 +59,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
5959 // Exercise linker with LLVM backend
6060 // musl tests
6161 elf_step.dependOn(testAbsSymbols(b, .{ .target = musl_target }));
62 elf_step.dependOn(testComdatElimination(b, .{ .target = musl_target }));
6263 elf_step.dependOn(testCommonSymbols(b, .{ .target = musl_target }));
6364 elf_step.dependOn(testCommonSymbolsInArchive(b, .{ .target = musl_target }));
6465 elf_step.dependOn(testCommentString(b, .{ .target = musl_target }));
......@@ -368,6 +369,97 @@ fn testCanonicalPlt(b: *Build, opts: Options) *Step {
368369 return test_step;
369370}
370371
372fn testComdatElimination(b: *Build, opts: Options) *Step {
373 const test_step = addTestStep(b, "comdat-elimination", opts);
374
375 const a_o = addObject(b, opts, .{
376 .name = "a",
377 .cpp_source_bytes =
378 \\#include <stdio.h>
379 \\inline void foo() {
380 \\ printf("calling foo in a\n");
381 \\}
382 \\void hello() {
383 \\ foo();
384 \\}
385 ,
386 });
387 a_o.linkLibCpp();
388
389 const main_o = addObject(b, opts, .{
390 .name = "main",
391 .cpp_source_bytes =
392 \\#include <stdio.h>
393 \\inline void foo() {
394 \\ printf("calling foo in main\n");
395 \\}
396 \\void hello();
397 \\int main() {
398 \\ foo();
399 \\ hello();
400 \\ return 0;
401 \\}
402 ,
403 });
404 main_o.linkLibCpp();
405
406 {
407 const exe = addExecutable(b, opts, .{
408 .name = "main1",
409 });
410 exe.addObject(a_o);
411 exe.addObject(main_o);
412 exe.linkLibCpp();
413
414 const run = addRunArtifact(exe);
415 run.expectStdOutEqual(
416 \\calling foo in a
417 \\calling foo in a
418 \\
419 );
420 test_step.dependOn(&run.step);
421
422 const check = exe.checkObject();
423 check.checkInSymtab();
424 // This weird looking double assertion uses the fact that once we find the symbol in
425 // the symtab, we do not reset the cursor and do subsequent checks from that point onwards.
426 // If this is the case, and COMDAT elimination works correctly we should only have one instance
427 // of foo() function.
428 check.checkContains("_Z3foov");
429 check.checkNotPresent("_Z3foov");
430 test_step.dependOn(&check.step);
431 }
432
433 {
434 const exe = addExecutable(b, opts, .{
435 .name = "main2",
436 });
437 exe.addObject(main_o);
438 exe.addObject(a_o);
439 exe.linkLibCpp();
440
441 const run = addRunArtifact(exe);
442 run.expectStdOutEqual(
443 \\calling foo in main
444 \\calling foo in main
445 \\
446 );
447 test_step.dependOn(&run.step);
448
449 const check = exe.checkObject();
450 check.checkInSymtab();
451 // This weird looking double assertion uses the fact that once we find the symbol in
452 // the symtab, we do not reset the cursor and do subsequent checks from that point onwards.
453 // If this is the case, and COMDAT elimination works correctly we should only have one instance
454 // of foo() function.
455 check.checkContains("_Z3foov");
456 check.checkNotPresent("_Z3foov");
457 test_step.dependOn(&check.step);
458 }
459
460 return test_step;
461}
462
371463fn testCommentString(b: *Build, opts: Options) *Step {
372464 const test_step = addTestStep(b, "comment-string", opts);
373465