json: preserve key-insertion order [PR109163]
PR other/109163 notes that when we write out JSON files, we traverse
the keys within each object via hash_map iteration, and thus the
ordering is non-deterministic - it can arbitrarily vary from run to
run and from different machines, making it harder for users to compare
results and determine if anything has "really" changed.
I'm running into this issue with SARIF output, but there are several
places where we're currently emitting JSON:
* -fsave-optimization-record emits SRCFILE.opt-record.json.gz
"This option is experimental and the format of the data within
the compressed JSON file is subject to change."; see
optinfo-emit-json.{h,cc}, dumpfile.cc, etc
* -fdiagnostics-format= with the various "sarif" and "json" options
* -fdump-analyzer-json is a developer option in the analyzer
* gcov has:
"-j, --json-format: Output JSON intermediate format into
.gcov.json.gz file"
This patch adds an auto_vec to class json::object to preserve
key-insertion order, and use it when writing out objects. Potentially
this slightly slows down JSON output, but I believe that this isn't
normally a bottleneck, and that the benefits to the user of
deterministic output are worth it.
I had first attempted to use ordered_hash_map.h for this, but ran into
impenetrable template errors, so this patch uses a simpler approach of
just adding an auto_vec to json::object.
Testing showed a failure of diagnostic-format-json-5.c, which was using
a convoluted set of regexps to consume the output; I believe that this
was brittle, and was intermittently failing for some of the random
orderings of output. I rewrote these regexps to work with the expected
output order. The other such tests seem to pass with the
now-deterministic orderings.
gcc/ChangeLog:
PR other/109163
* json.cc: Update comments to indicate that we now preserve
insertion order of keys within objects.
(object::print): Traverse keys in insertion order.
(object::set): Preserve insertion order of keys.
(selftest::test_writing_objects): Add an additional key to verify
that we preserve insertion order.
* json.h (object::m_keys): New field.
gcc/testsuite/ChangeLog:
PR other/109163
* c-c++-common/diagnostic-format-json-1.c: Update comment.
* c-c++-common/diagnostic-format-json-2.c: Likewise.
* c-c++-common/diagnostic-format-json-3.c: Likewise.
* c-c++-common/diagnostic-format-json-4.c: Likewise.
* c-c++-common/diagnostic-format-json-5.c: Rewrite regexps.
* c-c++-common/diagnostic-format-json-stderr-1.c: Update comment.
Signed-off-by:
David Malcolm <dmalcolm@redhat.com>
Showing
- gcc/json.cc 26 additions, 14 deletionsgcc/json.cc
- gcc/json.h 8 additions, 2 deletionsgcc/json.h
- gcc/testsuite/c-c++-common/diagnostic-format-json-1.c 1 addition, 2 deletionsgcc/testsuite/c-c++-common/diagnostic-format-json-1.c
- gcc/testsuite/c-c++-common/diagnostic-format-json-2.c 1 addition, 2 deletionsgcc/testsuite/c-c++-common/diagnostic-format-json-2.c
- gcc/testsuite/c-c++-common/diagnostic-format-json-3.c 1 addition, 2 deletionsgcc/testsuite/c-c++-common/diagnostic-format-json-3.c
- gcc/testsuite/c-c++-common/diagnostic-format-json-4.c 1 addition, 2 deletionsgcc/testsuite/c-c++-common/diagnostic-format-json-4.c
- gcc/testsuite/c-c++-common/diagnostic-format-json-5.c 56 additions, 44 deletionsgcc/testsuite/c-c++-common/diagnostic-format-json-5.c
- gcc/testsuite/c-c++-common/diagnostic-format-json-stderr-1.c 1 addition, 2 deletionsgcc/testsuite/c-c++-common/diagnostic-format-json-stderr-1.c
Loading
Please register or sign in to comment