On Sat, Feb 14, 2026 at 7:55 AM David Malcolm <[email protected]> wrote:
>
> Use json-diagnostic.{h,cc} to improve the diagnostics issued
> for malformed and invalid JSON tuning inputs: report the
> file/line/column and, if possible, the JSON Pointer of the
> problematic input.
>
> Before
> ------
>
> $ ./xgcc -B. -S test.c -muser-provided-CPU=malformed.json
> cc1: error: error parsing JSON data: expected ':'; got number
>
> $ ./xgcc -B. -S test.c -muser-provided-CPU=unsigned-3.json
> cc1: warning: JSON tuning file does not contain version information;
> compatibility cannot be verified
> cc1: error: key ‘tune_params.sve_width’ value 5000000000 is out of range for
> ‘uint’ type [0, 4294967295]
> cc1: error: validation failed for the provided JSON data
>
> After
> -----
>
> $ ./xgcc -B. -S test.c -muser-provided-CPU=malformed.json
> malformed.json:3:17: error: error parsing JSON data: expected ':'; got number
> 3 | "sve_width" 128
> | ^~~
>
> $ ./xgcc -B. -S test.c -muser-provided-CPU=unsigned-3.json
> cc1: warning: JSON tuning file does not contain version information;
> compatibility cannot be verified
> unsigned-3.json: In JSON value ‘/tune_params/sve_width’
> unsigned-3.json:3:18: error: key ‘tune_params.sve_width’ value 5000000000 is
> out of range for ‘uint’ type [0, 4294967295]
> 3 | "sve_width": 5000000000
> | ^~~~~~~~~~
> cc1: error: validation failed for the provided JSON data
>
> gcc/ChangeLog:
> PR target/124094
> * config/aarch64/aarch64-generate-json-tuning-routines.py
> (generate_field_code): Add "ctxt, " arg to function call when
> operation is "parse".
> (generate_function): Add "gcc_json_context &ctxt, " param to
> function decl when operation is "parse".
> * config/aarch64/aarch64-json-tunings-parser-generated.inc:
> Regenerate, passing around a gcc_json_context &.
> * config/aarch64/aarch64-json-tunings-parser.cc: Include
> "json-diagnostic.h".
> (WARNING_OPT) New macro.
> (PARSE_INTEGER_FIELD): Add "ctxt" param and pass it around.
> (PARSE_UNSIGNED_INTEGER_FIELD): Likewise.
> (PARSE_BOOLEAN_FIELD): Likewise.
> (PARSE_STRING_FIELD): Likewise.
> (PARSE_OBJECT): Likewise.
> (PARSE_ARRAY_FIELD): Likewise.
> (PARSE_ENUM_FIELD): Likewise.
> (parse_func_type): Likewise.
> (parse_object_helper): Likewise. Use json_error rather than error.
> (inform_about_wrong_kind_of_json_value): New.
> (extract_string): Add "ctxt" param. Replace "warning" with a pair
> of calls to json_warning and
> inform_about_wrong_kind_of_json_value, tweaking wording
> accordingly.
> (extract_integer): Likewise.
> (extract_unsigned_integer): Likewise.
> (parse_enum_field): Likewise.
> (validate_and_traverse): Replace "warning" and "error" with
> "json_warning" and "json_error".
> (check_version_compatibility): Use WARNING_OPT. Add
> auto_diagnostic_group to group the error and note.
> (aarch64_load_tuning_params_from_json_string): Add "js_filename"
> param. Use gcc_json_context to capture location info. Use it
> when reporting errors to get file/line/column info. Replace check
> on root being non-null with assertion, as this is guaranteed if
> error is non-null. Replace warning with json_warning.
> (aarch64_load_tuning_params_from_json): Pass data_filename to
> aarch64_load_tuning_params_from_json_string for use when reporting
> diagnostics.
> (selftest::test_json_integers): Add a placeholder filename.
> (selftest::test_json_boolean): Likewise.
> (selftest::test_json_strings): Likewise.
> (selftest::test_json_enums): Likewise.
>
> gcc/testsuite/ChangeLog:
> PR target/124094
> * gcc.target/aarch64/aarch64-json-tunings/boolean-2.c: Add options
> -fdiagnostics-show-caret -fdiagnostics-show-line-numbers. Replace
> dg-error with a pair of dg-regexps to verify that we report the
> filename and JSON Pointer of where the error occurs, and then
> the filename and location within the JSON file. Verify that we
> quote and underline the pertinent part of the JSON file.
> * gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c: Likewise.
> * gcc.target/aarch64/aarch64-json-tunings/enum-2.c: Likewise.
> * gcc.target/aarch64/aarch64-json-tunings/integer-2.c: Likewise.
> * gcc.target/aarch64/aarch64-json-tunings/integer-3.c: Likewise.
> * gcc.target/aarch64/aarch64-json-tunings/string-2.c: Likewise.
> * gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c:
> Likewise.
> * gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c: Likewise.
> * gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c: Likewise.
> * gcc.target/aarch64/aarch64-json-tunings/malformed.c: New test,
> to verify behavior on a malformed JSON input file.
> * gcc.target/aarch64/aarch64-json-tunings/malformed.json: New
> test file. This is malformed JSON, due to a missing ':" between
> key and value.
>
> Signed-off-by: David Malcolm <[email protected]>
> ---
> .../aarch64-generate-json-tuning-routines.py | 17 +-
> .../aarch64-json-tunings-parser-generated.inc | 428 +++++++++---------
> .../aarch64/aarch64-json-tunings-parser.cc | 276 +++++++----
> .../aarch64/aarch64-json-tunings/boolean-2.c | 12 +-
> .../aarch64-json-tunings/empty-brackets.c | 9 +-
> .../aarch64/aarch64-json-tunings/enum-2.c | 19 +-
> .../aarch64/aarch64-json-tunings/integer-2.c | 14 +-
> .../aarch64/aarch64-json-tunings/integer-3.c | 13 +-
> .../aarch64/aarch64-json-tunings/malformed.c | 11 +
> .../aarch64-json-tunings/malformed.json | 5 +
> .../aarch64/aarch64-json-tunings/string-2.c | 12 +-
> .../aarch64-json-tunings/unidentified-key.c | 12 +-
> .../aarch64/aarch64-json-tunings/unsigned-2.c | 10 +-
> .../aarch64/aarch64-json-tunings/unsigned-3.c | 10 +-
> 14 files changed, 517 insertions(+), 331 deletions(-)
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json
>
> diff --git a/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py
> b/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py
> index a4f9e4ece71a3..9253cf58cdfa1 100755
> --- a/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py
> +++ b/gcc/config/aarch64/aarch64-generate-json-tuning-routines.py
> @@ -85,15 +85,20 @@ def generate_field_code(
> ) -> List[str]:
> lines = []
>
> + if operation == 'parse':
> + ctxt = 'ctxt, '
> + else:
> + ctxt = ''
What about passing around a ctxt pointer aways and then for the non
parse case just pass a null pointer?
Just in case we need a context later on for the output case and don't
need to change this part again.
Otherwise this looks ok to me.
Thanks,
Andrew Pinski
> +
> if isinstance(value, str):
> macro = get_macro(operation.upper(), value)
> if value == "enum":
> enum_mapping = f"{key}_mappings"
> lines.append(
> - f'{indent}{macro} ({obj_name}, "{key}", {struct_name}.{key},
> {enum_mapping});'
> + f'{indent}{macro} ({ctxt}{obj_name}, "{key}",
> {struct_name}.{key}, {enum_mapping});'
> )
> else:
> - lines.append(f'{indent}{macro} ({obj_name}, "{key}",
> {struct_name}.{key});')
> + lines.append(f'{indent}{macro} ({ctxt}{obj_name}, "{key}",
> {struct_name}.{key});')
>
> elif isinstance(value, dict):
> # Nested object - find function name based on current context + key
> @@ -102,7 +107,7 @@ def generate_field_code(
> func_name = function_map.get(child_path_key,
> f"{operation.lower()}_{key}")
> macro_name = f"{operation.upper()}_OBJECT"
> lines.append(
> - f'{indent}{macro_name} ({obj_name}, "{key}",
> {struct_name}.{key}, {func_name});'
> + f'{indent}{macro_name} ({ctxt}{obj_name}, "{key}",
> {struct_name}.{key}, {func_name});'
> )
>
> elif isinstance(value, list) and len(value) > 0:
> @@ -117,11 +122,11 @@ def generate_field_code(
>
> if operation.lower() == "serialize":
> lines.append(
> - f'{indent}{macro_name} ({obj_name}, "{key}",
> {struct_name}.{key}, ARRAY_SIZE ({struct_name}.{key}), {func_name});'
> + f'{indent}{macro_name} ({ctxt}{obj_name}, "{key}",
> {struct_name}.{key}, ARRAY_SIZE ({struct_name}.{key}), {func_name});'
> )
> else:
> lines.append(
> - f'{indent}{macro_name} ({obj_name}, "{key}",
> {struct_name}.{key}, {func_name});'
> + f'{indent}{macro_name} ({ctxt}{obj_name}, "{key}",
> {struct_name}.{key}, {func_name});'
> )
> else:
> raise ValueError(f"Arrays of non-object types are not yet
> supported: {key}")
> @@ -175,7 +180,7 @@ def generate_function(
>
> if operation.lower() == "parse":
> lines.append("static void")
> - lines.append(f"parse_{full_name} (const json::object *jo, T
> &{local_name})")
> + lines.append(f"parse_{full_name} (gcc_json_context &ctxt, const
> json::object &jo, T &{local_name})")
> lines.append("{")
>
> for key, value in schema.items():
> diff --git a/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc
> b/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc
> index 882d8f799755a..3908a4f1a3114 100644
> --- a/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc
> +++ b/gcc/config/aarch64/aarch64-json-tunings-parser-generated.inc
> @@ -38,319 +38,319 @@ static const enum_mapping<aarch64_ldp_stp_policy>
> stp_policy_model_mappings[] =
>
> template <typename T>
> static void
> -parse_insn_extra_cost_alu (const json::object *jo, T &alu)
> +parse_insn_extra_cost_alu (gcc_json_context &ctxt, const json::object &jo, T
> &alu)
> {
> - PARSE_INTEGER_FIELD (jo, "arith", alu.arith);
> - PARSE_INTEGER_FIELD (jo, "logical", alu.logical);
> - PARSE_INTEGER_FIELD (jo, "shift", alu.shift);
> - PARSE_INTEGER_FIELD (jo, "shift_reg", alu.shift_reg);
> - PARSE_INTEGER_FIELD (jo, "arith_shift", alu.arith_shift);
> - PARSE_INTEGER_FIELD (jo, "arith_shift_reg", alu.arith_shift_reg);
> - PARSE_INTEGER_FIELD (jo, "log_shift", alu.log_shift);
> - PARSE_INTEGER_FIELD (jo, "log_shift_reg", alu.log_shift_reg);
> - PARSE_INTEGER_FIELD (jo, "extend", alu.extend);
> - PARSE_INTEGER_FIELD (jo, "extend_arith", alu.extend_arith);
> - PARSE_INTEGER_FIELD (jo, "bfi", alu.bfi);
> - PARSE_INTEGER_FIELD (jo, "bfx", alu.bfx);
> - PARSE_INTEGER_FIELD (jo, "clz", alu.clz);
> - PARSE_INTEGER_FIELD (jo, "rev", alu.rev);
> - PARSE_INTEGER_FIELD (jo, "non_exec", alu.non_exec);
> - PARSE_BOOLEAN_FIELD (jo, "non_exec_costs_exec", alu.non_exec_costs_exec);
> + PARSE_INTEGER_FIELD (ctxt, jo, "arith", alu.arith);
> + PARSE_INTEGER_FIELD (ctxt, jo, "logical", alu.logical);
> + PARSE_INTEGER_FIELD (ctxt, jo, "shift", alu.shift);
> + PARSE_INTEGER_FIELD (ctxt, jo, "shift_reg", alu.shift_reg);
> + PARSE_INTEGER_FIELD (ctxt, jo, "arith_shift", alu.arith_shift);
> + PARSE_INTEGER_FIELD (ctxt, jo, "arith_shift_reg", alu.arith_shift_reg);
> + PARSE_INTEGER_FIELD (ctxt, jo, "log_shift", alu.log_shift);
> + PARSE_INTEGER_FIELD (ctxt, jo, "log_shift_reg", alu.log_shift_reg);
> + PARSE_INTEGER_FIELD (ctxt, jo, "extend", alu.extend);
> + PARSE_INTEGER_FIELD (ctxt, jo, "extend_arith", alu.extend_arith);
> + PARSE_INTEGER_FIELD (ctxt, jo, "bfi", alu.bfi);
> + PARSE_INTEGER_FIELD (ctxt, jo, "bfx", alu.bfx);
> + PARSE_INTEGER_FIELD (ctxt, jo, "clz", alu.clz);
> + PARSE_INTEGER_FIELD (ctxt, jo, "rev", alu.rev);
> + PARSE_INTEGER_FIELD (ctxt, jo, "non_exec", alu.non_exec);
> + PARSE_BOOLEAN_FIELD (ctxt, jo, "non_exec_costs_exec",
> alu.non_exec_costs_exec);
> }
>
> template <typename T>
> static void
> -parse_insn_extra_cost_mult_element (const json::object *jo, T &mult_element)
> +parse_insn_extra_cost_mult_element (gcc_json_context &ctxt, const
> json::object &jo, T &mult_element)
> {
> - PARSE_INTEGER_FIELD (jo, "simple", mult_element.simple);
> - PARSE_INTEGER_FIELD (jo, "flag_setting", mult_element.flag_setting);
> - PARSE_INTEGER_FIELD (jo, "extend", mult_element.extend);
> - PARSE_INTEGER_FIELD (jo, "add", mult_element.add);
> - PARSE_INTEGER_FIELD (jo, "extend_add", mult_element.extend_add);
> - PARSE_INTEGER_FIELD (jo, "idiv", mult_element.idiv);
> + PARSE_INTEGER_FIELD (ctxt, jo, "simple", mult_element.simple);
> + PARSE_INTEGER_FIELD (ctxt, jo, "flag_setting", mult_element.flag_setting);
> + PARSE_INTEGER_FIELD (ctxt, jo, "extend", mult_element.extend);
> + PARSE_INTEGER_FIELD (ctxt, jo, "add", mult_element.add);
> + PARSE_INTEGER_FIELD (ctxt, jo, "extend_add", mult_element.extend_add);
> + PARSE_INTEGER_FIELD (ctxt, jo, "idiv", mult_element.idiv);
> }
>
> template <typename T>
> static void
> -parse_insn_extra_cost_ldst (const json::object *jo, T &ldst)
> +parse_insn_extra_cost_ldst (gcc_json_context &ctxt, const json::object &jo,
> T &ldst)
> {
> - PARSE_INTEGER_FIELD (jo, "load", ldst.load);
> - PARSE_INTEGER_FIELD (jo, "load_sign_extend", ldst.load_sign_extend);
> - PARSE_INTEGER_FIELD (jo, "ldrd", ldst.ldrd);
> - PARSE_INTEGER_FIELD (jo, "ldm_1st", ldst.ldm_1st);
> - PARSE_INTEGER_FIELD (jo, "ldm_regs_per_insn_1st",
> ldst.ldm_regs_per_insn_1st);
> - PARSE_INTEGER_FIELD (jo, "ldm_regs_per_insn_subsequent",
> ldst.ldm_regs_per_insn_subsequent);
> - PARSE_INTEGER_FIELD (jo, "loadf", ldst.loadf);
> - PARSE_INTEGER_FIELD (jo, "loadd", ldst.loadd);
> - PARSE_INTEGER_FIELD (jo, "load_unaligned", ldst.load_unaligned);
> - PARSE_INTEGER_FIELD (jo, "store", ldst.store);
> - PARSE_INTEGER_FIELD (jo, "strd", ldst.strd);
> - PARSE_INTEGER_FIELD (jo, "stm_1st", ldst.stm_1st);
> - PARSE_INTEGER_FIELD (jo, "stm_regs_per_insn_1st",
> ldst.stm_regs_per_insn_1st);
> - PARSE_INTEGER_FIELD (jo, "stm_regs_per_insn_subsequent",
> ldst.stm_regs_per_insn_subsequent);
> - PARSE_INTEGER_FIELD (jo, "storef", ldst.storef);
> - PARSE_INTEGER_FIELD (jo, "stored", ldst.stored);
> - PARSE_INTEGER_FIELD (jo, "store_unaligned", ldst.store_unaligned);
> - PARSE_INTEGER_FIELD (jo, "loadv", ldst.loadv);
> - PARSE_INTEGER_FIELD (jo, "storev", ldst.storev);
> + PARSE_INTEGER_FIELD (ctxt, jo, "load", ldst.load);
> + PARSE_INTEGER_FIELD (ctxt, jo, "load_sign_extend", ldst.load_sign_extend);
> + PARSE_INTEGER_FIELD (ctxt, jo, "ldrd", ldst.ldrd);
> + PARSE_INTEGER_FIELD (ctxt, jo, "ldm_1st", ldst.ldm_1st);
> + PARSE_INTEGER_FIELD (ctxt, jo, "ldm_regs_per_insn_1st",
> ldst.ldm_regs_per_insn_1st);
> + PARSE_INTEGER_FIELD (ctxt, jo, "ldm_regs_per_insn_subsequent",
> ldst.ldm_regs_per_insn_subsequent);
> + PARSE_INTEGER_FIELD (ctxt, jo, "loadf", ldst.loadf);
> + PARSE_INTEGER_FIELD (ctxt, jo, "loadd", ldst.loadd);
> + PARSE_INTEGER_FIELD (ctxt, jo, "load_unaligned", ldst.load_unaligned);
> + PARSE_INTEGER_FIELD (ctxt, jo, "store", ldst.store);
> + PARSE_INTEGER_FIELD (ctxt, jo, "strd", ldst.strd);
> + PARSE_INTEGER_FIELD (ctxt, jo, "stm_1st", ldst.stm_1st);
> + PARSE_INTEGER_FIELD (ctxt, jo, "stm_regs_per_insn_1st",
> ldst.stm_regs_per_insn_1st);
> + PARSE_INTEGER_FIELD (ctxt, jo, "stm_regs_per_insn_subsequent",
> ldst.stm_regs_per_insn_subsequent);
> + PARSE_INTEGER_FIELD (ctxt, jo, "storef", ldst.storef);
> + PARSE_INTEGER_FIELD (ctxt, jo, "stored", ldst.stored);
> + PARSE_INTEGER_FIELD (ctxt, jo, "store_unaligned", ldst.store_unaligned);
> + PARSE_INTEGER_FIELD (ctxt, jo, "loadv", ldst.loadv);
> + PARSE_INTEGER_FIELD (ctxt, jo, "storev", ldst.storev);
> }
>
> template <typename T>
> static void
> -parse_insn_extra_cost_fp_element (const json::object *jo, T &fp_element)
> +parse_insn_extra_cost_fp_element (gcc_json_context &ctxt, const json::object
> &jo, T &fp_element)
> {
> - PARSE_INTEGER_FIELD (jo, "div", fp_element.div);
> - PARSE_INTEGER_FIELD (jo, "mult", fp_element.mult);
> - PARSE_INTEGER_FIELD (jo, "mult_addsub", fp_element.mult_addsub);
> - PARSE_INTEGER_FIELD (jo, "fma", fp_element.fma);
> - PARSE_INTEGER_FIELD (jo, "addsub", fp_element.addsub);
> - PARSE_INTEGER_FIELD (jo, "fpconst", fp_element.fpconst);
> - PARSE_INTEGER_FIELD (jo, "neg", fp_element.neg);
> - PARSE_INTEGER_FIELD (jo, "compare", fp_element.compare);
> - PARSE_INTEGER_FIELD (jo, "widen", fp_element.widen);
> - PARSE_INTEGER_FIELD (jo, "narrow", fp_element.narrow);
> - PARSE_INTEGER_FIELD (jo, "toint", fp_element.toint);
> - PARSE_INTEGER_FIELD (jo, "fromint", fp_element.fromint);
> - PARSE_INTEGER_FIELD (jo, "roundint", fp_element.roundint);
> + PARSE_INTEGER_FIELD (ctxt, jo, "div", fp_element.div);
> + PARSE_INTEGER_FIELD (ctxt, jo, "mult", fp_element.mult);
> + PARSE_INTEGER_FIELD (ctxt, jo, "mult_addsub", fp_element.mult_addsub);
> + PARSE_INTEGER_FIELD (ctxt, jo, "fma", fp_element.fma);
> + PARSE_INTEGER_FIELD (ctxt, jo, "addsub", fp_element.addsub);
> + PARSE_INTEGER_FIELD (ctxt, jo, "fpconst", fp_element.fpconst);
> + PARSE_INTEGER_FIELD (ctxt, jo, "neg", fp_element.neg);
> + PARSE_INTEGER_FIELD (ctxt, jo, "compare", fp_element.compare);
> + PARSE_INTEGER_FIELD (ctxt, jo, "widen", fp_element.widen);
> + PARSE_INTEGER_FIELD (ctxt, jo, "narrow", fp_element.narrow);
> + PARSE_INTEGER_FIELD (ctxt, jo, "toint", fp_element.toint);
> + PARSE_INTEGER_FIELD (ctxt, jo, "fromint", fp_element.fromint);
> + PARSE_INTEGER_FIELD (ctxt, jo, "roundint", fp_element.roundint);
> }
>
> template <typename T>
> static void
> -parse_insn_extra_cost_vect (const json::object *jo, T &vect)
> +parse_insn_extra_cost_vect (gcc_json_context &ctxt, const json::object &jo,
> T &vect)
> {
> - PARSE_INTEGER_FIELD (jo, "alu", vect.alu);
> - PARSE_INTEGER_FIELD (jo, "mult", vect.mult);
> - PARSE_INTEGER_FIELD (jo, "movi", vect.movi);
> - PARSE_INTEGER_FIELD (jo, "dup", vect.dup);
> - PARSE_INTEGER_FIELD (jo, "extract", vect.extract);
> + PARSE_INTEGER_FIELD (ctxt, jo, "alu", vect.alu);
> + PARSE_INTEGER_FIELD (ctxt, jo, "mult", vect.mult);
> + PARSE_INTEGER_FIELD (ctxt, jo, "movi", vect.movi);
> + PARSE_INTEGER_FIELD (ctxt, jo, "dup", vect.dup);
> + PARSE_INTEGER_FIELD (ctxt, jo, "extract", vect.extract);
> }
>
> template <typename T>
> static void
> -parse_addr_cost_addr_scale_costs (const json::object *jo, T
> &addr_scale_costs)
> +parse_addr_cost_addr_scale_costs (gcc_json_context &ctxt, const json::object
> &jo, T &addr_scale_costs)
> {
> - PARSE_INTEGER_FIELD (jo, "hi", addr_scale_costs.hi);
> - PARSE_INTEGER_FIELD (jo, "si", addr_scale_costs.si);
> - PARSE_INTEGER_FIELD (jo, "di", addr_scale_costs.di);
> - PARSE_INTEGER_FIELD (jo, "ti", addr_scale_costs.ti);
> + PARSE_INTEGER_FIELD (ctxt, jo, "hi", addr_scale_costs.hi);
> + PARSE_INTEGER_FIELD (ctxt, jo, "si", addr_scale_costs.si);
> + PARSE_INTEGER_FIELD (ctxt, jo, "di", addr_scale_costs.di);
> + PARSE_INTEGER_FIELD (ctxt, jo, "ti", addr_scale_costs.ti);
> }
>
> template <typename T>
> static void
> -parse_regmove_cost (const json::object *jo, T ®move_cost)
> +parse_regmove_cost (gcc_json_context &ctxt, const json::object &jo, T
> ®move_cost)
> {
> - PARSE_INTEGER_FIELD (jo, "GP2GP", regmove_cost.GP2GP);
> - PARSE_INTEGER_FIELD (jo, "GP2FP", regmove_cost.GP2FP);
> - PARSE_INTEGER_FIELD (jo, "FP2GP", regmove_cost.FP2GP);
> - PARSE_INTEGER_FIELD (jo, "FP2FP", regmove_cost.FP2FP);
> + PARSE_INTEGER_FIELD (ctxt, jo, "GP2GP", regmove_cost.GP2GP);
> + PARSE_INTEGER_FIELD (ctxt, jo, "GP2FP", regmove_cost.GP2FP);
> + PARSE_INTEGER_FIELD (ctxt, jo, "FP2GP", regmove_cost.FP2GP);
> + PARSE_INTEGER_FIELD (ctxt, jo, "FP2FP", regmove_cost.FP2FP);
> }
>
> template <typename T>
> static void
> -parse_vec_costs_advsimd (const json::object *jo, T &advsimd)
> +parse_vec_costs_advsimd (gcc_json_context &ctxt, const json::object &jo, T
> &advsimd)
> {
> - PARSE_INTEGER_FIELD (jo, "int_stmt_cost", advsimd.int_stmt_cost);
> - PARSE_INTEGER_FIELD (jo, "fp_stmt_cost", advsimd.fp_stmt_cost);
> - PARSE_INTEGER_FIELD (jo, "ld2_st2_permute_cost",
> advsimd.ld2_st2_permute_cost);
> - PARSE_INTEGER_FIELD (jo, "ld3_st3_permute_cost",
> advsimd.ld3_st3_permute_cost);
> - PARSE_INTEGER_FIELD (jo, "ld4_st4_permute_cost",
> advsimd.ld4_st4_permute_cost);
> - PARSE_INTEGER_FIELD (jo, "permute_cost", advsimd.permute_cost);
> - PARSE_INTEGER_FIELD (jo, "reduc_i8_cost", advsimd.reduc_i8_cost);
> - PARSE_INTEGER_FIELD (jo, "reduc_i16_cost", advsimd.reduc_i16_cost);
> - PARSE_INTEGER_FIELD (jo, "reduc_i32_cost", advsimd.reduc_i32_cost);
> - PARSE_INTEGER_FIELD (jo, "reduc_i64_cost", advsimd.reduc_i64_cost);
> - PARSE_INTEGER_FIELD (jo, "reduc_f16_cost", advsimd.reduc_f16_cost);
> - PARSE_INTEGER_FIELD (jo, "reduc_f32_cost", advsimd.reduc_f32_cost);
> - PARSE_INTEGER_FIELD (jo, "reduc_f64_cost", advsimd.reduc_f64_cost);
> - PARSE_INTEGER_FIELD (jo, "store_elt_extra_cost",
> advsimd.store_elt_extra_cost);
> - PARSE_INTEGER_FIELD (jo, "vec_to_scalar_cost", advsimd.vec_to_scalar_cost);
> - PARSE_INTEGER_FIELD (jo, "scalar_to_vec_cost", advsimd.scalar_to_vec_cost);
> - PARSE_INTEGER_FIELD (jo, "align_load_cost", advsimd.align_load_cost);
> - PARSE_INTEGER_FIELD (jo, "unalign_load_cost", advsimd.unalign_load_cost);
> - PARSE_INTEGER_FIELD (jo, "unalign_store_cost", advsimd.unalign_store_cost);
> - PARSE_INTEGER_FIELD (jo, "store_cost", advsimd.store_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "int_stmt_cost", advsimd.int_stmt_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "fp_stmt_cost", advsimd.fp_stmt_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "ld2_st2_permute_cost",
> advsimd.ld2_st2_permute_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "ld3_st3_permute_cost",
> advsimd.ld3_st3_permute_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "ld4_st4_permute_cost",
> advsimd.ld4_st4_permute_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "permute_cost", advsimd.permute_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_i8_cost", advsimd.reduc_i8_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_i16_cost", advsimd.reduc_i16_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_i32_cost", advsimd.reduc_i32_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_i64_cost", advsimd.reduc_i64_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_f16_cost", advsimd.reduc_f16_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_f32_cost", advsimd.reduc_f32_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "reduc_f64_cost", advsimd.reduc_f64_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "store_elt_extra_cost",
> advsimd.store_elt_extra_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "vec_to_scalar_cost",
> advsimd.vec_to_scalar_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "scalar_to_vec_cost",
> advsimd.scalar_to_vec_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "align_load_cost", advsimd.align_load_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "unalign_load_cost",
> advsimd.unalign_load_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "unalign_store_cost",
> advsimd.unalign_store_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "store_cost", advsimd.store_cost);
> }
>
> template <typename T>
> static void
> -parse_vec_costs_sve (const json::object *jo, T &sve)
> +parse_vec_costs_sve (gcc_json_context &ctxt, const json::object &jo, T &sve)
> {
> - PARSE_INTEGER_FIELD (jo, "clast_cost", sve.clast_cost);
> - PARSE_INTEGER_FIELD (jo, "fadda_f16_cost", sve.fadda_f16_cost);
> - PARSE_INTEGER_FIELD (jo, "fadda_f32_cost", sve.fadda_f32_cost);
> - PARSE_INTEGER_FIELD (jo, "fadda_f64_cost", sve.fadda_f64_cost);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "gather_load_x32_cost",
> sve.gather_load_x32_cost);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "gather_load_x64_cost",
> sve.gather_load_x64_cost);
> - PARSE_INTEGER_FIELD (jo, "gather_load_x32_init_cost",
> sve.gather_load_x32_init_cost);
> - PARSE_INTEGER_FIELD (jo, "gather_load_x64_init_cost",
> sve.gather_load_x64_init_cost);
> - PARSE_INTEGER_FIELD (jo, "scatter_store_elt_cost",
> sve.scatter_store_elt_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "clast_cost", sve.clast_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "fadda_f16_cost", sve.fadda_f16_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "fadda_f32_cost", sve.fadda_f32_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "fadda_f64_cost", sve.fadda_f64_cost);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "gather_load_x32_cost",
> sve.gather_load_x32_cost);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "gather_load_x64_cost",
> sve.gather_load_x64_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "gather_load_x32_init_cost",
> sve.gather_load_x32_init_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "gather_load_x64_init_cost",
> sve.gather_load_x64_init_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "scatter_store_elt_cost",
> sve.scatter_store_elt_cost);
> }
>
> template <typename T>
> static void
> -parse_vec_costs_issue_info_scalar (const json::object *jo, T &scalar)
> +parse_vec_costs_issue_info_scalar (gcc_json_context &ctxt, const
> json::object &jo, T &scalar)
> {
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "loads_stores_per_cycle",
> scalar.loads_stores_per_cycle);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "stores_per_cycle",
> scalar.stores_per_cycle);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "general_ops_per_cycle",
> scalar.general_ops_per_cycle);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_load_general_ops",
> scalar.fp_simd_load_general_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_store_general_ops",
> scalar.fp_simd_store_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "loads_stores_per_cycle",
> scalar.loads_stores_per_cycle);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "stores_per_cycle",
> scalar.stores_per_cycle);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "general_ops_per_cycle",
> scalar.general_ops_per_cycle);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_load_general_ops",
> scalar.fp_simd_load_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_store_general_ops",
> scalar.fp_simd_store_general_ops);
> }
>
> template <typename T>
> static void
> -parse_vec_costs_issue_info_advsimd (const json::object *jo, T &advsimd)
> +parse_vec_costs_issue_info_advsimd (gcc_json_context &ctxt, const
> json::object &jo, T &advsimd)
> {
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "loads_stores_per_cycle",
> advsimd.loads_stores_per_cycle);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "stores_per_cycle",
> advsimd.stores_per_cycle);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "general_ops_per_cycle",
> advsimd.general_ops_per_cycle);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_load_general_ops",
> advsimd.fp_simd_load_general_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_store_general_ops",
> advsimd.fp_simd_store_general_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld2_st2_general_ops",
> advsimd.ld2_st2_general_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld3_st3_general_ops",
> advsimd.ld3_st3_general_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld4_st4_general_ops",
> advsimd.ld4_st4_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "loads_stores_per_cycle",
> advsimd.loads_stores_per_cycle);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "stores_per_cycle",
> advsimd.stores_per_cycle);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "general_ops_per_cycle",
> advsimd.general_ops_per_cycle);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_load_general_ops",
> advsimd.fp_simd_load_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_store_general_ops",
> advsimd.fp_simd_store_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld2_st2_general_ops",
> advsimd.ld2_st2_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld3_st3_general_ops",
> advsimd.ld3_st3_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld4_st4_general_ops",
> advsimd.ld4_st4_general_ops);
> }
>
> template <typename T>
> static void
> -parse_vec_costs_issue_info_sve (const json::object *jo, T &sve)
> +parse_vec_costs_issue_info_sve (gcc_json_context &ctxt, const json::object
> &jo, T &sve)
> {
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "loads_stores_per_cycle",
> sve.loads_stores_per_cycle);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "stores_per_cycle",
> sve.stores_per_cycle);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "general_ops_per_cycle",
> sve.general_ops_per_cycle);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_load_general_ops",
> sve.fp_simd_load_general_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_simd_store_general_ops",
> sve.fp_simd_store_general_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld2_st2_general_ops",
> sve.ld2_st2_general_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld3_st3_general_ops",
> sve.ld3_st3_general_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "ld4_st4_general_ops",
> sve.ld4_st4_general_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "pred_ops_per_cycle",
> sve.pred_ops_per_cycle);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "while_pred_ops", sve.while_pred_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "int_cmp_pred_ops",
> sve.int_cmp_pred_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fp_cmp_pred_ops", sve.fp_cmp_pred_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "gather_scatter_pair_general_ops",
> sve.gather_scatter_pair_general_ops);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "gather_scatter_pair_pred_ops",
> sve.gather_scatter_pair_pred_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "loads_stores_per_cycle",
> sve.loads_stores_per_cycle);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "stores_per_cycle",
> sve.stores_per_cycle);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "general_ops_per_cycle",
> sve.general_ops_per_cycle);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_load_general_ops",
> sve.fp_simd_load_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_simd_store_general_ops",
> sve.fp_simd_store_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld2_st2_general_ops",
> sve.ld2_st2_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld3_st3_general_ops",
> sve.ld3_st3_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "ld4_st4_general_ops",
> sve.ld4_st4_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "pred_ops_per_cycle",
> sve.pred_ops_per_cycle);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "while_pred_ops",
> sve.while_pred_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "int_cmp_pred_ops",
> sve.int_cmp_pred_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fp_cmp_pred_ops",
> sve.fp_cmp_pred_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "gather_scatter_pair_general_ops",
> sve.gather_scatter_pair_general_ops);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "gather_scatter_pair_pred_ops",
> sve.gather_scatter_pair_pred_ops);
> }
>
> template <typename T>
> static void
> -parse_branch_costs (const json::object *jo, T &branch_costs)
> +parse_branch_costs (gcc_json_context &ctxt, const json::object &jo, T
> &branch_costs)
> {
> - PARSE_INTEGER_FIELD (jo, "predictable", branch_costs.predictable);
> - PARSE_INTEGER_FIELD (jo, "unpredictable", branch_costs.unpredictable);
> - PARSE_INTEGER_FIELD (jo, "br_mispredict_factor",
> branch_costs.br_mispredict_factor);
> + PARSE_INTEGER_FIELD (ctxt, jo, "predictable", branch_costs.predictable);
> + PARSE_INTEGER_FIELD (ctxt, jo, "unpredictable",
> branch_costs.unpredictable);
> + PARSE_INTEGER_FIELD (ctxt, jo, "br_mispredict_factor",
> branch_costs.br_mispredict_factor);
> }
>
> template <typename T>
> static void
> -parse_approx_modes (const json::object *jo, T &approx_modes)
> +parse_approx_modes (gcc_json_context &ctxt, const json::object &jo, T
> &approx_modes)
> {
> - PARSE_INTEGER_FIELD (jo, "division", approx_modes.division);
> - PARSE_INTEGER_FIELD (jo, "sqrt", approx_modes.sqrt);
> - PARSE_INTEGER_FIELD (jo, "recip_sqrt", approx_modes.recip_sqrt);
> + PARSE_INTEGER_FIELD (ctxt, jo, "division", approx_modes.division);
> + PARSE_INTEGER_FIELD (ctxt, jo, "sqrt", approx_modes.sqrt);
> + PARSE_INTEGER_FIELD (ctxt, jo, "recip_sqrt", approx_modes.recip_sqrt);
> }
>
> template <typename T>
> static void
> -parse_memmov_cost (const json::object *jo, T &memmov_cost)
> +parse_memmov_cost (gcc_json_context &ctxt, const json::object &jo, T
> &memmov_cost)
> {
> - PARSE_INTEGER_FIELD (jo, "load_int", memmov_cost.load_int);
> - PARSE_INTEGER_FIELD (jo, "store_int", memmov_cost.store_int);
> - PARSE_INTEGER_FIELD (jo, "load_fp", memmov_cost.load_fp);
> - PARSE_INTEGER_FIELD (jo, "store_fp", memmov_cost.store_fp);
> - PARSE_INTEGER_FIELD (jo, "load_pred", memmov_cost.load_pred);
> - PARSE_INTEGER_FIELD (jo, "store_pred", memmov_cost.store_pred);
> + PARSE_INTEGER_FIELD (ctxt, jo, "load_int", memmov_cost.load_int);
> + PARSE_INTEGER_FIELD (ctxt, jo, "store_int", memmov_cost.store_int);
> + PARSE_INTEGER_FIELD (ctxt, jo, "load_fp", memmov_cost.load_fp);
> + PARSE_INTEGER_FIELD (ctxt, jo, "store_fp", memmov_cost.store_fp);
> + PARSE_INTEGER_FIELD (ctxt, jo, "load_pred", memmov_cost.load_pred);
> + PARSE_INTEGER_FIELD (ctxt, jo, "store_pred", memmov_cost.store_pred);
> }
>
> template <typename T>
> static void
> -parse_prefetch (const json::object *jo, T &prefetch)
> +parse_prefetch (gcc_json_context &ctxt, const json::object &jo, T &prefetch)
> {
> - PARSE_INTEGER_FIELD (jo, "num_slots", prefetch.num_slots);
> - PARSE_INTEGER_FIELD (jo, "l1_cache_size", prefetch.l1_cache_size);
> - PARSE_INTEGER_FIELD (jo, "l1_cache_line_size",
> prefetch.l1_cache_line_size);
> - PARSE_INTEGER_FIELD (jo, "l2_cache_size", prefetch.l2_cache_size);
> - PARSE_BOOLEAN_FIELD (jo, "prefetch_dynamic_strides",
> prefetch.prefetch_dynamic_strides);
> - PARSE_INTEGER_FIELD (jo, "minimum_stride", prefetch.minimum_stride);
> - PARSE_INTEGER_FIELD (jo, "default_opt_level", prefetch.default_opt_level);
> + PARSE_INTEGER_FIELD (ctxt, jo, "num_slots", prefetch.num_slots);
> + PARSE_INTEGER_FIELD (ctxt, jo, "l1_cache_size", prefetch.l1_cache_size);
> + PARSE_INTEGER_FIELD (ctxt, jo, "l1_cache_line_size",
> prefetch.l1_cache_line_size);
> + PARSE_INTEGER_FIELD (ctxt, jo, "l2_cache_size", prefetch.l2_cache_size);
> + PARSE_BOOLEAN_FIELD (ctxt, jo, "prefetch_dynamic_strides",
> prefetch.prefetch_dynamic_strides);
> + PARSE_INTEGER_FIELD (ctxt, jo, "minimum_stride", prefetch.minimum_stride);
> + PARSE_INTEGER_FIELD (ctxt, jo, "default_opt_level",
> prefetch.default_opt_level);
> }
>
> template <typename T>
> static void
> -parse_insn_extra_cost (const json::object *jo, T &insn_extra_cost)
> +parse_insn_extra_cost (gcc_json_context &ctxt, const json::object &jo, T
> &insn_extra_cost)
> {
> - PARSE_OBJECT (jo, "alu", insn_extra_cost.alu, parse_insn_extra_cost_alu);
> - PARSE_ARRAY_FIELD (jo, "mult", insn_extra_cost.mult,
> parse_insn_extra_cost_mult_element);
> - PARSE_OBJECT (jo, "ldst", insn_extra_cost.ldst,
> parse_insn_extra_cost_ldst);
> - PARSE_ARRAY_FIELD (jo, "fp", insn_extra_cost.fp,
> parse_insn_extra_cost_fp_element);
> - PARSE_OBJECT (jo, "vect", insn_extra_cost.vect,
> parse_insn_extra_cost_vect);
> + PARSE_OBJECT (ctxt, jo, "alu", insn_extra_cost.alu,
> parse_insn_extra_cost_alu);
> + PARSE_ARRAY_FIELD (ctxt, jo, "mult", insn_extra_cost.mult,
> parse_insn_extra_cost_mult_element);
> + PARSE_OBJECT (ctxt, jo, "ldst", insn_extra_cost.ldst,
> parse_insn_extra_cost_ldst);
> + PARSE_ARRAY_FIELD (ctxt, jo, "fp", insn_extra_cost.fp,
> parse_insn_extra_cost_fp_element);
> + PARSE_OBJECT (ctxt, jo, "vect", insn_extra_cost.vect,
> parse_insn_extra_cost_vect);
> }
>
> template <typename T>
> static void
> -parse_addr_cost (const json::object *jo, T &addr_cost)
> +parse_addr_cost (gcc_json_context &ctxt, const json::object &jo, T
> &addr_cost)
> {
> - PARSE_OBJECT (jo, "addr_scale_costs", addr_cost.addr_scale_costs,
> parse_addr_cost_addr_scale_costs);
> - PARSE_INTEGER_FIELD (jo, "pre_modify", addr_cost.pre_modify);
> - PARSE_INTEGER_FIELD (jo, "post_modify", addr_cost.post_modify);
> - PARSE_INTEGER_FIELD (jo, "post_modify_ld3_st3",
> addr_cost.post_modify_ld3_st3);
> - PARSE_INTEGER_FIELD (jo, "post_modify_ld4_st4",
> addr_cost.post_modify_ld4_st4);
> - PARSE_INTEGER_FIELD (jo, "register_offset", addr_cost.register_offset);
> - PARSE_INTEGER_FIELD (jo, "register_sextend", addr_cost.register_sextend);
> - PARSE_INTEGER_FIELD (jo, "register_zextend", addr_cost.register_zextend);
> - PARSE_INTEGER_FIELD (jo, "imm_offset", addr_cost.imm_offset);
> + PARSE_OBJECT (ctxt, jo, "addr_scale_costs", addr_cost.addr_scale_costs,
> parse_addr_cost_addr_scale_costs);
> + PARSE_INTEGER_FIELD (ctxt, jo, "pre_modify", addr_cost.pre_modify);
> + PARSE_INTEGER_FIELD (ctxt, jo, "post_modify", addr_cost.post_modify);
> + PARSE_INTEGER_FIELD (ctxt, jo, "post_modify_ld3_st3",
> addr_cost.post_modify_ld3_st3);
> + PARSE_INTEGER_FIELD (ctxt, jo, "post_modify_ld4_st4",
> addr_cost.post_modify_ld4_st4);
> + PARSE_INTEGER_FIELD (ctxt, jo, "register_offset",
> addr_cost.register_offset);
> + PARSE_INTEGER_FIELD (ctxt, jo, "register_sextend",
> addr_cost.register_sextend);
> + PARSE_INTEGER_FIELD (ctxt, jo, "register_zextend",
> addr_cost.register_zextend);
> + PARSE_INTEGER_FIELD (ctxt, jo, "imm_offset", addr_cost.imm_offset);
> }
>
> template <typename T>
> static void
> -parse_vec_costs_issue_info (const json::object *jo, T &issue_info)
> +parse_vec_costs_issue_info (gcc_json_context &ctxt, const json::object &jo,
> T &issue_info)
> {
> - PARSE_OBJECT (jo, "scalar", issue_info.scalar,
> parse_vec_costs_issue_info_scalar);
> - PARSE_OBJECT (jo, "advsimd", issue_info.advsimd,
> parse_vec_costs_issue_info_advsimd);
> - PARSE_OBJECT (jo, "sve", issue_info.sve, parse_vec_costs_issue_info_sve);
> + PARSE_OBJECT (ctxt, jo, "scalar", issue_info.scalar,
> parse_vec_costs_issue_info_scalar);
> + PARSE_OBJECT (ctxt, jo, "advsimd", issue_info.advsimd,
> parse_vec_costs_issue_info_advsimd);
> + PARSE_OBJECT (ctxt, jo, "sve", issue_info.sve,
> parse_vec_costs_issue_info_sve);
> }
>
> template <typename T>
> static void
> -parse_vec_costs (const json::object *jo, T &vec_costs)
> +parse_vec_costs (gcc_json_context &ctxt, const json::object &jo, T
> &vec_costs)
> {
> - PARSE_INTEGER_FIELD (jo, "scalar_int_stmt_cost",
> vec_costs.scalar_int_stmt_cost);
> - PARSE_INTEGER_FIELD (jo, "scalar_fp_stmt_cost",
> vec_costs.scalar_fp_stmt_cost);
> - PARSE_INTEGER_FIELD (jo, "scalar_load_cost", vec_costs.scalar_load_cost);
> - PARSE_INTEGER_FIELD (jo, "scalar_store_cost", vec_costs.scalar_store_cost);
> - PARSE_INTEGER_FIELD (jo, "cond_taken_branch_cost",
> vec_costs.cond_taken_branch_cost);
> - PARSE_INTEGER_FIELD (jo, "cond_not_taken_branch_cost",
> vec_costs.cond_not_taken_branch_cost);
> - PARSE_OBJECT (jo, "advsimd", vec_costs.advsimd, parse_vec_costs_advsimd);
> - PARSE_OBJECT (jo, "sve", vec_costs.sve, parse_vec_costs_sve);
> - PARSE_OBJECT (jo, "issue_info", vec_costs.issue_info,
> parse_vec_costs_issue_info);
> + PARSE_INTEGER_FIELD (ctxt, jo, "scalar_int_stmt_cost",
> vec_costs.scalar_int_stmt_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "scalar_fp_stmt_cost",
> vec_costs.scalar_fp_stmt_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "scalar_load_cost",
> vec_costs.scalar_load_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "scalar_store_cost",
> vec_costs.scalar_store_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "cond_taken_branch_cost",
> vec_costs.cond_taken_branch_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "cond_not_taken_branch_cost",
> vec_costs.cond_not_taken_branch_cost);
> + PARSE_OBJECT (ctxt, jo, "advsimd", vec_costs.advsimd,
> parse_vec_costs_advsimd);
> + PARSE_OBJECT (ctxt, jo, "sve", vec_costs.sve, parse_vec_costs_sve);
> + PARSE_OBJECT (ctxt, jo, "issue_info", vec_costs.issue_info,
> parse_vec_costs_issue_info);
> }
>
> template <typename T>
> static void
> -parse_tunings (const json::object *jo, T &tunings)
> +parse_tunings (gcc_json_context &ctxt, const json::object &jo, T &tunings)
> {
> - PARSE_OBJECT (jo, "insn_extra_cost", tunings.insn_extra_cost,
> parse_insn_extra_cost);
> - PARSE_OBJECT (jo, "addr_cost", tunings.addr_cost, parse_addr_cost);
> - PARSE_OBJECT (jo, "regmove_cost", tunings.regmove_cost,
> parse_regmove_cost);
> - PARSE_OBJECT (jo, "vec_costs", tunings.vec_costs, parse_vec_costs);
> - PARSE_OBJECT (jo, "branch_costs", tunings.branch_costs,
> parse_branch_costs);
> - PARSE_OBJECT (jo, "approx_modes", tunings.approx_modes,
> parse_approx_modes);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "sve_width", tunings.sve_width);
> - PARSE_OBJECT (jo, "memmov_cost", tunings.memmov_cost, parse_memmov_cost);
> - PARSE_INTEGER_FIELD (jo, "issue_rate", tunings.issue_rate);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "fusible_ops", tunings.fusible_ops);
> - PARSE_STRING_FIELD (jo, "function_align", tunings.function_align);
> - PARSE_STRING_FIELD (jo, "jump_align", tunings.jump_align);
> - PARSE_STRING_FIELD (jo, "loop_align", tunings.loop_align);
> - PARSE_INTEGER_FIELD (jo, "int_reassoc_width", tunings.int_reassoc_width);
> - PARSE_INTEGER_FIELD (jo, "fp_reassoc_width", tunings.fp_reassoc_width);
> - PARSE_INTEGER_FIELD (jo, "fma_reassoc_width", tunings.fma_reassoc_width);
> - PARSE_INTEGER_FIELD (jo, "vec_reassoc_width", tunings.vec_reassoc_width);
> - PARSE_INTEGER_FIELD (jo, "min_div_recip_mul_sf",
> tunings.min_div_recip_mul_sf);
> - PARSE_INTEGER_FIELD (jo, "min_div_recip_mul_df",
> tunings.min_div_recip_mul_df);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "max_case_values",
> tunings.max_case_values);
> - PARSE_ENUM_FIELD (jo, "autoprefetcher_model",
> tunings.autoprefetcher_model, autoprefetcher_model_mappings);
> - PARSE_UNSIGNED_INTEGER_FIELD (jo, "extra_tuning_flags",
> tunings.extra_tuning_flags);
> - PARSE_OBJECT (jo, "prefetch", tunings.prefetch, parse_prefetch);
> - PARSE_ENUM_FIELD (jo, "ldp_policy_model", tunings.ldp_policy_model,
> ldp_policy_model_mappings);
> - PARSE_ENUM_FIELD (jo, "stp_policy_model", tunings.stp_policy_model,
> stp_policy_model_mappings);
> + PARSE_OBJECT (ctxt, jo, "insn_extra_cost", tunings.insn_extra_cost,
> parse_insn_extra_cost);
> + PARSE_OBJECT (ctxt, jo, "addr_cost", tunings.addr_cost, parse_addr_cost);
> + PARSE_OBJECT (ctxt, jo, "regmove_cost", tunings.regmove_cost,
> parse_regmove_cost);
> + PARSE_OBJECT (ctxt, jo, "vec_costs", tunings.vec_costs, parse_vec_costs);
> + PARSE_OBJECT (ctxt, jo, "branch_costs", tunings.branch_costs,
> parse_branch_costs);
> + PARSE_OBJECT (ctxt, jo, "approx_modes", tunings.approx_modes,
> parse_approx_modes);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "sve_width", tunings.sve_width);
> + PARSE_OBJECT (ctxt, jo, "memmov_cost", tunings.memmov_cost,
> parse_memmov_cost);
> + PARSE_INTEGER_FIELD (ctxt, jo, "issue_rate", tunings.issue_rate);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "fusible_ops",
> tunings.fusible_ops);
> + PARSE_STRING_FIELD (ctxt, jo, "function_align", tunings.function_align);
> + PARSE_STRING_FIELD (ctxt, jo, "jump_align", tunings.jump_align);
> + PARSE_STRING_FIELD (ctxt, jo, "loop_align", tunings.loop_align);
> + PARSE_INTEGER_FIELD (ctxt, jo, "int_reassoc_width",
> tunings.int_reassoc_width);
> + PARSE_INTEGER_FIELD (ctxt, jo, "fp_reassoc_width",
> tunings.fp_reassoc_width);
> + PARSE_INTEGER_FIELD (ctxt, jo, "fma_reassoc_width",
> tunings.fma_reassoc_width);
> + PARSE_INTEGER_FIELD (ctxt, jo, "vec_reassoc_width",
> tunings.vec_reassoc_width);
> + PARSE_INTEGER_FIELD (ctxt, jo, "min_div_recip_mul_sf",
> tunings.min_div_recip_mul_sf);
> + PARSE_INTEGER_FIELD (ctxt, jo, "min_div_recip_mul_df",
> tunings.min_div_recip_mul_df);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "max_case_values",
> tunings.max_case_values);
> + PARSE_ENUM_FIELD (ctxt, jo, "autoprefetcher_model",
> tunings.autoprefetcher_model, autoprefetcher_model_mappings);
> + PARSE_UNSIGNED_INTEGER_FIELD (ctxt, jo, "extra_tuning_flags",
> tunings.extra_tuning_flags);
> + PARSE_OBJECT (ctxt, jo, "prefetch", tunings.prefetch, parse_prefetch);
> + PARSE_ENUM_FIELD (ctxt, jo, "ldp_policy_model", tunings.ldp_policy_model,
> ldp_policy_model_mappings);
> + PARSE_ENUM_FIELD (ctxt, jo, "stp_policy_model", tunings.stp_policy_model,
> stp_policy_model_mappings);
> }
> \ No newline at end of file
> diff --git a/gcc/config/aarch64/aarch64-json-tunings-parser.cc
> b/gcc/config/aarch64/aarch64-json-tunings-parser.cc
> index 326d52e02d1ce..40a1cbb41cd71 100644
> --- a/gcc/config/aarch64/aarch64-json-tunings-parser.cc
> +++ b/gcc/config/aarch64/aarch64-json-tunings-parser.cc
> @@ -27,6 +27,7 @@
> #include "tm.h"
> #include "diagnostic-core.h"
> #include "json-parsing.h"
> +#include "json-diagnostic.h"
> #include "aarch64-json-schema.h"
> #include "aarch64-json-tunings-parser.h"
> #include "aarch64-protos.h"
> @@ -34,45 +35,47 @@
> #include "selftest.h"
> #include "version.h"
>
> -#define PARSE_INTEGER_FIELD(obj, key, member)
> \
> +#define WARNING_OPT (0)
> +
> +#define PARSE_INTEGER_FIELD(ctxt, obj, key, member)
> \
> {
> \
> - const json::value *val = obj->get (key);
> \
> + const json::value *val = obj.get (key);
> \
> if (val)
> \
> - member = extract_integer (val);
> \
> + member = extract_integer (ctxt, *val, WARNING_OPT);
> \
> }
>
> -#define PARSE_UNSIGNED_INTEGER_FIELD(obj, key, member)
> \
> +#define PARSE_UNSIGNED_INTEGER_FIELD(ctxt, obj, key, member)
> \
> {
> \
> - const json::value *val = obj->get (key);
> \
> + const json::value *val = obj.get (key);
> \
> if (val)
> \
> - member = extract_unsigned_integer (val);
> \
> + member = extract_unsigned_integer (ctxt, *val, WARNING_OPT);
> \
> }
>
> -#define PARSE_BOOLEAN_FIELD(obj, key, member)
> \
> +#define PARSE_BOOLEAN_FIELD(ctxt, obj, key, member)
> \
> {
> \
> - const json::value *val = obj->get (key);
> \
> + const json::value *val = obj.get (key);
> \
> if (val)
> \
> - member = extract_boolean (val);
> \
> + member = extract_boolean (ctxt, *val, WARNING_OPT);
> \
> }
>
> -#define PARSE_STRING_FIELD(obj, key, member)
> \
> +#define PARSE_STRING_FIELD(ctxt, obj, key, member)
> \
> {
> \
> - const json::value *val = obj->get (key);
> \
> + const json::value *val = obj.get (key);
> \
> if (val)
> \
> - member = extract_string (val);
> \
> + member = extract_string (ctxt, *val, WARNING_OPT);
> \
> }
>
> -#define PARSE_OBJECT(obj, key, member, parse_func)
> \
> +#define PARSE_OBJECT(ctxt, obj, key, member, parse_func)
> \
> {
> \
> - const json::value *field_value = obj->get (key);
> \
> + const json::value *field_value = obj.get (key);
> \
> if (field_value)
> \
> if (auto *field_obj = dyn_cast<const json::object *> (field_value))
> \
> - parse_object_helper (field_obj, (member), (parse_func));
> \
> + parse_object_helper (ctxt, *field_obj, (member), (parse_func));
> \
> }
>
> -#define PARSE_ARRAY_FIELD(obj, key, member, parse_func)
> \
> +#define PARSE_ARRAY_FIELD(ctxt, obj, key, member, parse_func)
> \
> {
> \
> - const json::value *field_value = obj->get (key);
> \
> + const json::value *field_value = obj.get (key);
> \
> if (field_value)
> \
> if (auto *field_array = dyn_cast<const json::array *> (field_value))
> \
> for (size_t i = 0; i < field_array->size (); ++i)
> \
> @@ -80,34 +83,37 @@
> const json::value *elem = field_array->get (i);
> \
> if (elem)
> \
> if (auto *array_obj = dyn_cast<const json::object *> (elem))
> \
> - parse_func (array_obj, member[i]);
> \
> + parse_func (ctxt, *array_obj, member[i]);
> \
> }
> \
> }
>
> -#define PARSE_ENUM_FIELD(obj, key, member, mappings)
> \
> - parse_enum_field (obj, key, member, mappings,
> \
> - sizeof (mappings) / sizeof (mappings[0]))
> +#define PARSE_ENUM_FIELD(ctxt, obj, key, member, mappings)
> \
> + parse_enum_field (ctxt, obj, key, member, mappings,
> \
> + sizeof (mappings) / sizeof (mappings[0]), WARNING_OPT)
>
> /* Type alias for parse function pointer. */
> template <typename T>
> using parse_func_type
> - = void (*) (const json::object *,
> + = void (*) (gcc_json_context &,
> + const json::object &,
> std::remove_const_t<std::remove_pointer_t<T>> &);
>
> /* Parse JSON object into non-pointer member type. */
> template <typename T>
> static std::enable_if_t<!std::is_pointer<T>::value>
> -parse_object_helper (const json::object *field_obj, T &member,
> +parse_object_helper (gcc_json_context &ctxt,
> + const json::object &field_obj, T &member,
> parse_func_type<T> parse_func)
> {
> - parse_func (field_obj, member);
> + parse_func (ctxt, field_obj, member);
> }
>
> /* Parse JSON object into a const pointer member by creating a temp copy. */
> template <typename T>
> static std::enable_if_t<std::is_pointer<T>::value
> && std::is_const<std::remove_pointer_t<T>>::value>
> -parse_object_helper (const json::object *field_obj, T &member,
> +parse_object_helper (gcc_json_context &ctxt,
> + const json::object &field_obj, T &member,
> parse_func_type<T> parse_func)
> {
> if (!member)
> @@ -120,67 +126,121 @@ parse_object_helper (const json::object *field_obj, T
> &member,
> static bool already_initialized = false;
> if (already_initialized)
> {
> - error ("static storage conflict - multiple pointer members of the "
> - "same type cannot be parsed");
> + json_error (ctxt, field_obj,
> + "static storage conflict - multiple pointer members of "
> + "the same type cannot be parsed");
> return;
> }
> already_initialized = true;
> using NonConstType = std::remove_const_t<std::remove_pointer_t<T>>;
> static NonConstType new_obj = *member;
> - parse_func (field_obj, new_obj);
> + parse_func (ctxt, field_obj, new_obj);
> member = &new_obj;
> }
>
> +/* Issue a note about the kind of json value we encountered. */
> +
> +static void
> +inform_about_wrong_kind_of_json_value (gcc_json_context &ctxt,
> + const json::value &val)
> +{
> + switch (val.get_kind ())
> + {
> + default:
> + gcc_unreachable ();
> + case json::JSON_OBJECT:
> + json_note (ctxt, val, "...but got an object instead");
> + break;
> + case json::JSON_ARRAY:
> + json_note (ctxt, val, "...but got an array instead");
> + break;
> + case json::JSON_INTEGER:
> + json_note (ctxt, val, "...but got an integer instead");
> + break;
> + case json::JSON_FLOAT:
> + json_note (ctxt, val, "...but got a floating-point value instead");
> + break;
> + case json::JSON_STRING:
> + json_note (ctxt, val, "...but got a string instead");
> + break;
> + case json::JSON_TRUE:
> + json_note (ctxt, val, "...but got %qs instead", "true");
> + break;
> + case json::JSON_FALSE:
> + json_note (ctxt, val, "...but got %qs instead", "false");
> + break;
> + case json::JSON_NULL:
> + json_note (ctxt, val, "...but got %qs instead", "null");
> + break;
> + }
> +}
> +
> /* Extract string value from JSON, returning allocated C string. */
> char *
> -extract_string (const json::value *val)
> +extract_string (gcc_json_context &ctxt,
> + const json::value &val,
> + diagnostics::option_id warning_opt)
> {
> - if (auto *string_val = dyn_cast<const json::string *> (val))
> + if (auto *string_val = dyn_cast<const json::string *> (&val))
> return xstrdup (string_val->get_string ());
> - warning (0, "expected a string but got something else or NULL");
> + auto_diagnostic_group d;
> + if (json_warning (ctxt, val, warning_opt, "expected a string..."))
> + inform_about_wrong_kind_of_json_value (ctxt, val);
> return nullptr;
> }
>
> /* Extract signed integer value from JSON. */
> int
> -extract_integer (const json::value *val)
> +extract_integer (gcc_json_context &ctxt,
> + const json::value &val,
> + diagnostics::option_id warning_opt)
> {
> - if (auto *int_val = dyn_cast<const json::integer_number *> (val))
> + if (auto *int_val = dyn_cast<const json::integer_number *> (&val))
> {
> long value = int_val->get ();
> gcc_assert (value >= INT_MIN && value <= INT_MAX);
> return static_cast<int> (value);
> }
> - warning (0, "expected an integer value but got something else or NULL");
> + auto_diagnostic_group d;
> + if (json_warning (ctxt, val, warning_opt, "expected an integer value..."))
> + inform_about_wrong_kind_of_json_value (ctxt, val);
> return 0;
> }
>
> /* Extract unsigned integer value from JSON. */
> unsigned int
> -extract_unsigned_integer (const json::value *val)
> +extract_unsigned_integer (gcc_json_context &ctxt,
> + const json::value &val,
> + diagnostics::option_id warning_opt)
> {
> - if (auto *int_val = dyn_cast<const json::integer_number *> (val))
> + if (auto *int_val = dyn_cast<const json::integer_number *> (&val))
> {
> long value = int_val->get ();
> gcc_assert (value >= 0 && value <= UINT_MAX);
> return static_cast<unsigned int> (value);
> }
> - warning (0,
> - "expected an unsigned integer value but got something else or
> NULL");
> + auto_diagnostic_group d;
> + if (json_warning (ctxt, val, warning_opt,
> + "expected an unsigned integer value..."))
> + inform_about_wrong_kind_of_json_value (ctxt, val);
> return 0;
> }
>
> /* Extract boolean value from JSON literal. */
> bool
> -extract_boolean (const json::value *val)
> +extract_boolean (gcc_json_context &ctxt,
> + const json::value &val,
> + diagnostics::option_id warning_opt)
> {
> - if (auto *literal_val = dyn_cast<const json::literal *> (val))
> + if (auto *literal_val = dyn_cast<const json::literal *> (&val))
> {
> json::kind kind = literal_val->get_kind ();
> if (kind == json::JSON_TRUE || kind == json::JSON_FALSE)
> return (kind == json::JSON_TRUE);
> }
> - warning (0, "expected a boolean value but got something else or NULL");
> + auto_diagnostic_group d;
> + if (json_warning (ctxt, val, warning_opt, "expected a boolean value..."))
> + inform_about_wrong_kind_of_json_value (ctxt, val);
> return false;
> }
>
> @@ -193,18 +253,21 @@ template <typename EnumType> struct enum_mapping
> /* Parse JSON string field into enum value using string-to-enum mappings. */
> template <typename EnumType>
> static void
> -parse_enum_field (const json::object *jo, const std::string &key,
> +parse_enum_field (gcc_json_context &ctxt,
> + const json::object &jo, const std::string &key,
> EnumType &enum_var, const enum_mapping<EnumType> *mappings,
> - size_t num_mappings)
> + size_t num_mappings,
> + diagnostics::option_id warning_opt)
> {
> - const json::value *field_value = jo->get (key.c_str ());
> + const json::value *field_value = jo.get (key.c_str ());
> if (!field_value)
> return;
>
> auto *string_val = dyn_cast<const json::string *> (field_value);
> if (!string_val)
> {
> - warning (0, "expected string for enum field %s", key.c_str ());
> + json_warning (ctxt, *field_value, warning_opt,
> + "expected string for enum field %s", key.c_str ());
> enum_var = mappings[0].value;
> return;
> }
> @@ -219,8 +282,9 @@ parse_enum_field (const json::object *jo, const
> std::string &key,
> }
> }
>
> - warning (0, "%s not recognized, defaulting to %qs", key.c_str (),
> - mappings[0].name);
> + json_warning (ctxt, *field_value, 0,
> + "%s not recognized, defaulting to %qs", key.c_str (),
> + mappings[0].name);
> enum_var = mappings[0].value;
> }
>
> @@ -230,7 +294,8 @@ parse_enum_field (const json::object *jo, const
> std::string &key,
> /* Validate the user provided JSON data against the present schema.
> Checks for correct types, fields, and expected format. */
> static bool
> -validate_and_traverse (const json::object *json_obj,
> +validate_and_traverse (gcc_json_context &ctxt,
> + const json::object *json_obj,
> const json::object *schema_obj,
> const std::string &parent_key = "")
> {
> @@ -244,8 +309,9 @@ validate_and_traverse (const json::object *json_obj,
> const json::value *schema_value = schema_obj->get (key.c_str ());
> if (!schema_value)
> {
> - warning (0, "key %qs is not a tuning parameter, skipping",
> - full_key.c_str ());
> + json_warning (ctxt, *json_value, WARNING_OPT,
> + "key %qs is not a tuning parameter, skipping",
> + full_key.c_str ());
> continue;
> }
>
> @@ -253,13 +319,15 @@ validate_and_traverse (const json::object *json_obj,
> {
> if (auto *sub_json_obj = dyn_cast<const json::object *>
> (json_value))
> {
> - if (!validate_and_traverse (sub_json_obj, sub_schema_obj,
> + if (!validate_and_traverse (ctxt, sub_json_obj, sub_schema_obj,
> full_key))
> return false;
> }
> else
> {
> - error ("key %qs expected to be an object", full_key.c_str ());
> + json_error (ctxt, *json_value,
> + "key %qs expected to be an object",
> + full_key.c_str ());
> return false;
> }
> }
> @@ -267,7 +335,8 @@ validate_and_traverse (const json::object *json_obj,
> {
> if (json_value->get_kind () != json::JSON_ARRAY)
> {
> - error ("key %qs expected to be an array", full_key.c_str ());
> + json_error (ctxt, *json_value,
> + "key %qs expected to be an array", full_key.c_str
> ());
> return false;
> }
> }
> @@ -280,8 +349,9 @@ validate_and_traverse (const json::object *json_obj,
> {
> if (json_value->get_kind () != json::JSON_INTEGER)
> {
> - error ("key %qs expected to be an integer",
> - full_key.c_str ());
> + json_error (ctxt, *json_value,
> + "key %qs expected to be an integer",
> + full_key.c_str ());
> return false;
> }
> // Check if the value is valid for signed integer
> @@ -291,9 +361,10 @@ validate_and_traverse (const json::object *json_obj,
> long value = int_val->get ();
> if (value > INT_MAX || value < INT_MIN)
> {
> - error ("key %qs value %ld is out of range for %<int%> "
> - "type [%d, %d]",
> - full_key.c_str (), value, INT_MIN, INT_MAX);
> + json_error (ctxt, *json_value,
> + "key %qs value %ld is out of range for "
> + "%<int%> type [%d, %d]",
> + full_key.c_str (), value, INT_MIN, INT_MAX);
> return false;
> }
> }
> @@ -302,8 +373,9 @@ validate_and_traverse (const json::object *json_obj,
> {
> if (json_value->get_kind () != json::JSON_INTEGER)
> {
> - error ("key %qs expected to be an unsigned integer",
> - full_key.c_str ());
> + json_error (ctxt, *json_value,
> + "key %qs expected to be an unsigned integer",
> + full_key.c_str ());
> return false;
> }
> // Check if the value is valid for unsigned integer
> @@ -313,9 +385,10 @@ validate_and_traverse (const json::object *json_obj,
> long value = int_val->get ();
> if (value < 0 || value > UINT_MAX)
> {
> - error ("key %qs value %ld is out of range for %<uint%> "
> - "type [0, %u]",
> - full_key.c_str (), value, UINT_MAX);
> + json_error (ctxt, *json_value,
> + "key %qs value %ld is out of range for "
> + "%<uint%> type [0, %u]",
> + full_key.c_str (), value, UINT_MAX);
> return false;
> }
> }
> @@ -324,7 +397,9 @@ validate_and_traverse (const json::object *json_obj,
> {
> if (json_value->get_kind () != json::JSON_STRING)
> {
> - error ("key %qs expected to be a string", full_key.c_str
> ());
> + json_error (ctxt, *json_value,
> + "key %qs expected to be a string",
> + full_key.c_str ());
> return false;
> }
> }
> @@ -333,8 +408,9 @@ validate_and_traverse (const json::object *json_obj,
> if (json_value->get_kind () != json::JSON_TRUE
> && json_value->get_kind () != json::JSON_FALSE)
> {
> - error ("key %qs expected to be a boolean (true/false)",
> - full_key.c_str ());
> + json_error (ctxt, *json_value,
> + "key %qs expected to be a boolean (true/false)",
> + full_key.c_str ());
> return false;
> }
> }
> @@ -342,20 +418,24 @@ validate_and_traverse (const json::object *json_obj,
> {
> if (json_value->get_kind () != json::JSON_STRING)
> {
> - error ("key %qs expected to be an enum (string)",
> - full_key.c_str ());
> + json_error (ctxt, *json_value,
> + "key %qs expected to be an enum (string)",
> + full_key.c_str ());
> return false;
> }
> }
> else
> {
> - error ("key %qs has unsupported type", full_key.c_str ());
> + json_error (ctxt, *json_value,
> + "key %qs has unsupported type", full_key.c_str ());
> return false;
> }
> }
> else
> {
> - error ("key %qs has unexpected format in schema", full_key.c_str
> ());
> + json_error (ctxt, *json_value,
> + "key %qs has unexpected format in schema",
> + full_key.c_str ());
> return false;
> }
> }
> @@ -413,13 +493,15 @@ check_version_compatibility (const json::object
> *root_obj)
>
> if (json_gcc_major_version == -1)
> {
> - warning (0, "JSON tuning file does not contain version information; "
> - "compatibility cannot be verified");
> + warning (WARNING_OPT,
> + "JSON tuning file does not contain version information; "
> + "compatibility cannot be verified");
> return true;
> }
>
> if (json_gcc_major_version != GCC_major_version)
> {
> + auto_diagnostic_group d;
> error ("JSON tuning file was created with GCC version %d "
> "but current GCC version is %d",
> json_gcc_major_version, GCC_major_version);
> @@ -433,31 +515,32 @@ check_version_compatibility (const json::object
> *root_obj)
>
> /* Main routine for setting up the parsing of JSON data. */
> static void
> -aarch64_load_tuning_params_from_json_string (const char *json_string,
> +aarch64_load_tuning_params_from_json_string (const char *js_filename,
> + const char *json_string,
> const char *schema_string,
> struct tune_params *tune)
> {
> /* Try parsing the JSON string. */
> + gcc_json_context ctxt (js_filename);
> json::parser_result_t data_result
> = json::parse_utf8_string (strlen (json_string), json_string, true,
> - nullptr);
> + &ctxt);
>
> if (auto json_err = data_result.m_err.get ())
> {
> - error ("error parsing JSON data: %s", json_err->get_msg ());
> + location_t js_loc = ctxt.make_location_for_range (json_err->get_range
> ());
> + error_at (js_loc, "error parsing JSON data: %s", json_err->get_msg ());
> return;
> }
>
> - const std::unique_ptr<json::value> &root = data_result.m_val;
> - if (!root)
> - {
> - error ("JSON parsing returned null data");
> - return;
> - }
> - auto *root_obj = dyn_cast<const json::object *> (root.get ());
> + const json::value* root = data_result.m_val.get ();
> + gcc_assert (root);
> +
> + auto *root_obj = dyn_cast<const json::object *> (root);
> if (!root_obj)
> {
> - warning (0, "no JSON object found in the provided data");
> + json_warning (ctxt, *root, WARNING_OPT,
> + "no JSON object found in the provided data");
> return;
> }
>
> @@ -479,24 +562,26 @@ aarch64_load_tuning_params_from_json_string (const char
> *json_string,
> const json::value *tune_params_value = root_obj->get ("tune_params");
> if (!tune_params_value)
> {
> - warning (0, "key %<tune_params%> not found in JSON data");
> + json_warning (ctxt, *root_obj, WARNING_OPT,
> + "key %<tune_params%> not found in JSON data");
> return;
> }
>
> auto *jo = dyn_cast<const json::object *> (tune_params_value);
> if (!jo)
> {
> - error ("key %<tune_params%> is not a JSON object");
> + json_error (ctxt, *tune_params_value,
> + "key %<tune_params%> is not a JSON object");
> return;
> }
>
> - if (!validate_and_traverse (root_obj, schema_obj))
> + if (!validate_and_traverse (ctxt, root_obj, schema_obj))
> {
> error ("validation failed for the provided JSON data");
> return;
> }
>
> - parse_tunings (jo, *tune);
> + parse_tunings (ctxt, *jo, *tune);
> return;
> }
>
> @@ -511,8 +596,9 @@ aarch64_load_tuning_params_from_json (const char
> *data_filename,
> error ("cannot read JSON data in %s", data_filename);
> return;
> }
> - aarch64_load_tuning_params_from_json_string (
> - (const char *) json_data->data (), schema_json, tune);
> + aarch64_load_tuning_params_from_json_string
> + (data_filename,
> + (const char *) json_data->data (), schema_json, tune);
> }
>
> #if CHECKING_P
> @@ -536,7 +622,8 @@ test_json_integers ()
>
> tune_params params;
>
> - aarch64_load_tuning_params_from_json_string (test_json, schema_json,
> ¶ms);
> + aarch64_load_tuning_params_from_json_string
> + ("test.json", test_json, schema_json, ¶ms);
>
> ASSERT_EQ (params.sve_width, 256);
> ASSERT_EQ (params.issue_rate, 4);
> @@ -563,7 +650,8 @@ test_json_boolean ()
> tune_params params;
> params.insn_extra_cost = &default_cost_table;
>
> - aarch64_load_tuning_params_from_json_string (test_json, schema_json,
> ¶ms);
> + aarch64_load_tuning_params_from_json_string
> + ("test.json", test_json, schema_json, ¶ms);
>
> ASSERT_EQ (params.insn_extra_cost->alu.non_exec_costs_exec, false);
> }
> @@ -584,7 +672,8 @@ test_json_strings ()
>
> tune_params params;
>
> - aarch64_load_tuning_params_from_json_string (test_json, schema_json,
> ¶ms);
> + aarch64_load_tuning_params_from_json_string
> + ("test.json", test_json, schema_json, ¶ms);
>
> ASSERT_STREQ (params.function_align, "16");
> ASSERT_STREQ (params.jump_align, "2");
> @@ -607,7 +696,8 @@ test_json_enums ()
>
> tune_params params;
>
> - aarch64_load_tuning_params_from_json_string (test_json, schema_json,
> ¶ms);
> + aarch64_load_tuning_params_from_json_string
> + ("test.json", test_json, schema_json, ¶ms);
>
> ASSERT_EQ (params.autoprefetcher_model, tune_params::AUTOPREFETCHER_OFF);
> ASSERT_EQ (params.ldp_policy_model, AARCH64_LDP_STP_POLICY_NEVER);
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c
> index aef632f1d0423..0ed8f71b775d0 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/boolean-2.c
> @@ -1,8 +1,16 @@
> /* { dg-do compile } */
> /* { dg-additional-options
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/boolean-2.json
> -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret
> -fdiagnostics-show-line-numbers" } */
>
> /* { dg-warning "JSON tuning file does not contain version information" "" {
> target *-*-* } 0 } */
> -/* { dg-error "key .* expected to be a boolean" "" { target *-*-* } 0 } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/boolean-2.json: In
> JSON value '/tune_params/insn_extra_cost/alu/non_exec_costs_exec'" } */
> +/* { dg-regexp
> ".*gcc.target/aarch64/aarch64-json-tunings/boolean-2.json:5:32: error: key .*
> expected to be a boolean \\\(true/false\\\)" } */
> +/* { dg-begin-multiline-output "" }
> + 5 | "non_exec_costs_exec": 0
> + | ^
> + { dg-end-multiline-output "" } */
> +
> /* { dg-error "validation failed for the provided JSON data" "" { target
> *-*-* } 0 } */
>
> -int main () {}
> \ No newline at end of file
> +int main () {}
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c
> index 4df72dbaf7ab4..cbbe8afe760ec 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.c
> @@ -1,7 +1,12 @@
> /* { dg-do compile } */
> /* { dg-additional-options
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/empty-brackets.json
> -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret
> -fdiagnostics-show-line-numbers" } */
>
> /* { dg-warning "JSON tuning file does not contain version information" "" {
> target *-*-* } 0 } */
> -/* { dg-warning "key 'tune_params' not found in JSON data" "" { target
> *-*-* } 0 } */
> +/* { dg-regexp
> ".*gcc.target/aarch64/aarch64-json-tunings/empty-brackets.json:1:1: warning:
> key 'tune_params' not found in JSON data" } */
> +/* { dg-begin-multiline-output "" }
> + 1 | {}
> + | ^~
> + { dg-end-multiline-output "" } */
>
> -int main () {}
> \ No newline at end of file
> +int main () {}
> diff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c
> index c53bc5292d52f..30e0fd47d7946 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/enum-2.c
> @@ -1,8 +1,21 @@
> /* { dg-do compile } */
> /* { dg-additional-options
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/enum-2.json
> -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret
> -fdiagnostics-show-line-numbers" } */
>
> /* { dg-warning "JSON tuning file does not contain version information" "" {
> target *-*-* } 0 } */
> -/* { dg-warning "autoprefetcher_model not recognized, defaulting to
> 'AUTOPREFETCHER_OFF'" "" { target *-*-* } 0 } */
> -/* { dg-warning "ldp_policy_model not recognized, defaulting to
> 'AARCH64_LDP_STP_POLICY_DEFAULT'" "" { target *-*-* } 0 } */
>
> -int main () {}
> \ No newline at end of file
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json: In
> JSON value '/tune_params/autoprefetcher_model'" } */
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json:3:29:
> warning: autoprefetcher_model not recognized, defaulting to
> 'AUTOPREFETCHER_OFF'" } */
> +/* { dg-begin-multiline-output "" }
> + 3 | "autoprefetcher_model": "null",
> + | ^~~~~~
> + { dg-end-multiline-output "" } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json: In
> JSON value '/tune_params/ldp_policy_model'" } */
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/enum-2.json:4:25:
> warning: ldp_policy_model not recognized, defaulting to
> 'AARCH64_LDP_STP_POLICY_DEFAULT'" } */
> +/* { dg-begin-multiline-output "" }
> + 4 | "ldp_policy_model": "null",
> + | ^~~~~~
> + { dg-end-multiline-output "" } */
> +
> +int main () {}
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c
> index 093c86048ce95..4e9de75a7aa7d 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-2.c
> @@ -1,8 +1,16 @@
> /* { dg-do compile } */
> -/* { dg-additional-options
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-2.json
> -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-2.json
> -fdump-tuning-model=temp.json " } */
> +/* { dg-additional-options "-fdiagnostics-show-caret
> -fdiagnostics-show-line-numbers" } */
>
> /* { dg-warning "JSON tuning file does not contain version information" "" {
> target *-*-* } 0 } */
> -/* { dg-error "key .* value .* is out of range for 'int' type" "" { target
> *-*-* } 0 } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/integer-2.json: In
> JSON value '/tune_params/int_reassoc_width'" } */
> +/* { dg-regexp
> ".*gcc.target/aarch64/aarch64-json-tunings/integer-2.json:3:26: error: key .*
> value .* is out of range for 'int' type \\\[.*, .*\\\]" } */
> +/* { dg-begin-multiline-output "" }
> + 3 | "int_reassoc_width": 12097307449014
> + | ^~~~~~~~~~~~~~
> + { dg-end-multiline-output "" } */
> +
> /* { dg-error "validation failed for the provided JSON data" "" { target
> *-*-* } 0 } */
>
> -int main () {}
> \ No newline at end of file
> +int main () {}
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c
> index 438685c6002c6..bab713b35d03f 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/integer-3.c
> @@ -1,8 +1,17 @@
> /* { dg-do compile } */
> /* { dg-additional-options
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/integer-3.json
> -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret
> -fdiagnostics-show-line-numbers" } */
>
> /* { dg-warning "JSON tuning file does not contain version information" "" {
> target *-*-* } 0 } */
> -/* { dg-error "key .* expected to be an integer" "" { target *-*-* } 0 } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/integer-3.json: In
> JSON value '/tune_params/issue_rate'" } */
> +/* { dg-regexp
> ".*gcc.target/aarch64/aarch64-json-tunings/integer-3.json:3:19: error: key .*
> expected to be an integer" } */
> +/* { dg-begin-multiline-output "" }
> + 3 | "issue_rate": "10"
> + | ^~~~
> + { dg-end-multiline-output "" } */
> +
> +
> /* { dg-error "validation failed for the provided JSON data" "" { target
> *-*-* } 0 } */
>
> -int main () {}
> \ No newline at end of file
> +int main () {}
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c
> new file mode 100644
> index 0000000000000..f4d6bc0a1376c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/malformed.json
> -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret
> -fdiagnostics-show-line-numbers" } */
> +
> +/* { dg-regexp
> ".*gcc.target/aarch64/aarch64-json-tunings/malformed.json:3:17: error: error
> parsing JSON data: expected ':'; got number" } */
> +/* { dg-begin-multiline-output "" }
> + 3 | "sve_width" 128
> + | ^~~
> + { dg-end-multiline-output "" } */
> +
> +int main () {}
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json
> new file mode 100644
> index 0000000000000..541b721faccde
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/malformed.json
> @@ -0,0 +1,5 @@
> +{
> + "tune_params": {
> + "sve_width" 128
> + }
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c
> index ad3ea1422bade..ae6e265c514ac 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/string-2.c
> @@ -1,8 +1,16 @@
> /* { dg-do compile } */
> /* { dg-additional-options
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/string-2.json
> -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret
> -fdiagnostics-show-line-numbers" } */
>
> /* { dg-warning "JSON tuning file does not contain version information" "" {
> target *-*-* } 0 } */
> -/* { dg-error "key .* expected to be a string" "" { target *-*-* } 0 } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/string-2.json: In
> JSON value '/tune_params/function_align'" } */
> +/* { dg-regexp
> ".*gcc.target/aarch64/aarch64-json-tunings/string-2.json:3:23: error: key .*
> expected to be a string" "" { target *-*-* } 0 } */
> +/* { dg-begin-multiline-output "" }
> + 3 | "function_align": 16
> + | ^~
> + { dg-end-multiline-output "" } */
> +
> /* { dg-error "validation failed for the provided JSON data" "" { target
> *-*-* } 0 } */
>
> -int main () {}
> \ No newline at end of file
> +int main () {}
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c
> index bafbda8a1ef57..27bfacc40203d 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.c
> @@ -1,7 +1,15 @@
> /* { dg-do compile } */
> /* { dg-additional-options
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json
> -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret
> -fdiagnostics-show-line-numbers" } */
>
> /* { dg-warning "JSON tuning file does not contain version information" "" {
> target *-*-* } 0 } */
> -/* { dg-warning "key .* is not a tuning parameter, skipping" "" { target
> *-*-* } 0 } */
>
> -int main () {}
> \ No newline at end of file
> +/* { dg-regexp
> ".*gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json: In JSON
> value '/tune_params/unidentified_key'" } */
> +/* { dg-regexp
> ".*gcc.target/aarch64/aarch64-json-tunings/unidentified-key.json:3:25:
> warning: key .* is not a tuning parameter, skipping" "" { target *-*-* } 0 }
> */
> +
> +/* { dg-begin-multiline-output "" }
> + 3 | "unidentified_key": "10"
> + | ^~~~
> + { dg-end-multiline-output "" } */
> +
> +int main () {}
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c
> index ce1989d8e31df..88848e406cc0a 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.c
> @@ -1,8 +1,16 @@
> /* { dg-do compile } */
> /* { dg-additional-options
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json
> -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret
> -fdiagnostics-show-line-numbers" } */
>
> /* { dg-warning "JSON tuning file does not contain version information" "" {
> target *-*-* } 0 } */
> -/* { dg-error "key .* value .* is out of range for 'uint' type" "" { target
> *-*-* } 0 } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json:
> In JSON value '/tune_params/sve_width'" } */
> +/* { dg-regexp
> ".*gcc.target/aarch64/aarch64-json-tunings/unsigned-2.json:3:18: error: key
> .* value .* is out of range for 'uint' type \\\[.*, .*\\\]" } */
> +/* { dg-begin-multiline-output "" }
> + 3 | "sve_width": -128,
> + | ^~~~
> + { dg-end-multiline-output "" } */
> +
> /* { dg-error "validation failed for the provided JSON data" "" { target
> *-*-* } 0 } */
>
> int main () {}
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c
> b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c
> index 20a661f557026..0e808009810ef 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.c
> @@ -1,8 +1,16 @@
> /* { dg-do compile } */
> /* { dg-additional-options
> "-muser-provided-CPU=${srcdir}/gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json
> -fdump-tuning-model=temp.json" } */
> +/* { dg-additional-options "-fdiagnostics-show-caret
> -fdiagnostics-show-line-numbers" } */
>
> /* { dg-warning "JSON tuning file does not contain version information" "" {
> target *-*-* } 0 } */
> -/* { dg-error "key .* value .* is out of range for 'uint' type" "" { target
> *-*-* } 0 } */
> +
> +/* { dg-regexp ".*gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json:
> In JSON value '/tune_params/sve_width'" } */
> +/* { dg-regexp
> ".*gcc.target/aarch64/aarch64-json-tunings/unsigned-3.json:3:18: error: key
> .* value .* is out of range for 'uint' type \\\[.*, .*\\\]" } */
> +/* { dg-begin-multiline-output "" }
> + 3 | "sve_width": 5000000000
> + | ^~~~~~~~~~
> + { dg-end-multiline-output "" } */
> +
> /* { dg-error "validation failed for the provided JSON data" "" { target
> *-*-* } 0 } */
>
> int main () {}
> --
> 2.26.3
>