1 # needs-profiler-support
4 # FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
5 # properly. Since we only have GCC on the CI ignore the test for now.
7 # ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and
8 # `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw`.
9 # See ../coverage/coverage_tools.mk for more information.
11 -include ../coverage/coverage_tools.mk
13 BASEDIR=../coverage-reports-base
16 all: $(patsubst $(SOURCEDIR)/%.rs,%,$(wildcard $(SOURCEDIR)/*.rs))
18 # Ensure there are no `expected` results for tests that may have been removed or renamed
19 .PHONY: clear_expected_if_blessed
20 clear_expected_if_blessed:
21 ifdef RUSTC_BLESS_TEST
22 rm -f expected_export_coverage.*.json
23 rm -f expected_show_coverage.*.txt
26 -include clear_expected_if_blessed
29 # Compile the test program with coverage instrumentation and generate relevant MIR.
30 $(RUSTC) $(SOURCEDIR)/$@.rs \
31 -Zinstrument-coverage \
32 -Clink-dead-code=$(LINK_DEAD_CODE)
34 # Run it in order to generate some profiling data,
35 # with `LLVM_PROFILE_FILE=<profdata_file>` environment variable set to
36 # output the coverage stats for this run.
37 LLVM_PROFILE_FILE="$(TMPDIR)"/$@.profraw \
41 grep -q "^\/\/ expect-exit-status-$$status" $(SOURCEDIR)/$@.rs || \
42 ( >&2 echo "program exited with an unexpected exit status: $$status"; \
47 # Postprocess the profiling data so it can be used by the llvm-cov tool
48 "$(LLVM_BIN_DIR)"/llvm-profdata merge --sparse \
49 "$(TMPDIR)"/$@.profraw \
50 -o "$(TMPDIR)"/$@.profdata
52 # Generate a coverage report using `llvm-cov show`. The output ordering
53 # can be non-deterministic, so ignore the return status. If the test fails
54 # when comparing the JSON `export`, the `show` output may be useful when
56 "$(LLVM_BIN_DIR)"/llvm-cov show \
57 --Xdemangler="$(RUST_DEMANGLER)" \
58 --show-line-counts-or-regions \
59 --instr-profile="$(TMPDIR)"/$@.profdata \
60 $(call BIN,"$(TMPDIR)"/$@) \
61 > "$(TMPDIR)"/actual_show_coverage.$@.txt
63 ifdef RUSTC_BLESS_TEST
64 cp "$(TMPDIR)"/actual_show_coverage.$@.txt expected_show_coverage.$@.txt
66 # Compare the show coverage output (`--bless` refreshes `typical` files)
67 # Note `llvm-cov show` output for some programs can vary, but can be ignored
68 # by inserting `// ignore-llvm-cov-show-diffs` at the top of the source file.
70 $(DIFF) expected_show_coverage.$@.txt "$(TMPDIR)"/actual_show_coverage.$@.txt || \
71 ( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \
72 >&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \
74 ( >&2 echo 'diff failed, and not suppressed without `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs'; \
80 # Generate a coverage report in JSON, using `llvm-cov export`, and fail if
81 # there are differences from the expected output.
82 "$(LLVM_BIN_DIR)"/llvm-cov export \
84 --instr-profile="$(TMPDIR)"/$@.profdata \
85 $(call BIN,"$(TMPDIR)"/$@) \
86 | "$(PYTHON)" $(BASEDIR)/prettify_json.py \
87 > "$(TMPDIR)"/actual_export_coverage.$@.json
89 ifdef RUSTC_BLESS_TEST
90 cp "$(TMPDIR)"/actual_export_coverage.$@.json expected_export_coverage.$@.json
92 # Check that exported JSON coverage data matches what we expect (`--bless` refreshes `expected`)
93 $(DIFF) expected_export_coverage.$@.json "$(TMPDIR)"/actual_export_coverage.$@.json