Yeah, I am OK with this change, although riscv_subset_t may be able to do further clean up/refactor, but I don't want to block you guys since this is not super rush to do that.
Thanks :) On Thu, Aug 14, 2025 at 5:19 PM Richard Sandiford <richard.sandif...@arm.com> wrote: > > One of Alfie's FMV patches adds a hook that, in some cases, > is used to silently query a target_version (with no diagnostics > expected). In the review, I'd suggested handling this using > a location_t *, with null meaning "suppress diagnostics": > > https://gcc.gnu.org/pipermail/gcc-patches/2025-August/692113.html > > This patch tries to propagate that through the RISC-V parsing code. > I realise this isn't very elegant, sorry. > > I think riscv_compare_version_priority should also logically suppress > diagnostics, since it's supposed to be a pure query function. (From > that point of view, advocating for this change for Alfie's patch might > have been a bit unfair.) > > Tested as far as building riscv64-linux-gnu with --enable-werror-always. > I'll rely on the CI for the real testing. > > WDYT? Is the cure worse than the disease here? > > Richard > > > gcc/ > * config/riscv/riscv-protos.h > (riscv_process_target_version_attr): Change location_t argument > to location_t *. > * config/riscv/riscv-subset.h > (riscv_subset_list::riscv_subset_list): Change location_t argument > to location_t *. > (riscv_subset_list::parse): Likwise. > (riscv_subset_list::set_loc): Likewise. > (riscv_minimal_hwprobe_feature_bits): Likewise. > (riscv_subset_list::m_loc): Change type to location_t. > * common/config/riscv/riscv-common.cc > (riscv_subset_list::riscv_subset_list): Change location_t argument > to location_t *. > (riscv_subset_list::add): Suppress diagnostics when m_loc is null. > (riscv_subset_list::parsing_subset_version): Likewise. > (riscv_subset_list::parse_profiles): Likewise. > (riscv_subset_list::parse_base_ext): Likewise. > (riscv_subset_list::parse_single_std_ext): Likewise. > (riscv_subset_list::check_conflict_ext): Likewise. > (riscv_subset_list::parse_single_multiletter_ext): Likewise. > (riscv_subset_list::parse): Change location_t argument to location_t > *. > (riscv_subset_list::set_loc): Likewise. > (riscv_minimal_hwprobe_feature_bits): Likewise. > (riscv_parse_arch_string): Update call accordingly. > * config/riscv/riscv-target-attr.cc > (riscv_target_attr_parser::m_loc): Change type to location_t *. > (riscv_target_attr_parser::riscv_target_attr_parser): Change > location_t argument to location_t *. > (riscv_process_one_target_attr): Likewise. > (riscv_process_target_attr): Likewise. > (riscv_process_target_version_attr): Likewise. > (riscv_target_attr_parser::parse_arch): Suppress diagnostics when > m_loc is null. > (riscv_target_attr_parser::handle_arch): Likewise. > (riscv_target_attr_parser::handle_cpu): Likewise. > (riscv_target_attr_parser::handle_tune): Likewise. > (riscv_target_attr_parser::handle_priority): Likewise. > (riscv_option_valid_attribute_p): Update call accordingly. > (riscv_option_valid_version_attribute_p): Likewise. > * config/riscv/riscv.cc (parse_features_for_version): Add a > location_t * argument. > (dispatch_function_versions): Update call accordingly. > (riscv_compare_version_priority): Likewise, suppressing diagnostics. > --- > gcc/common/config/riscv/riscv-common.cc | 169 +++++++++++++----------- > gcc/config/riscv/riscv-protos.h | 2 +- > gcc/config/riscv/riscv-subset.h | 13 +- > gcc/config/riscv/riscv-target-attr.cc | 102 +++++++------- > gcc/config/riscv/riscv.cc | 18 +-- > 5 files changed, 170 insertions(+), 134 deletions(-) > > diff --git a/gcc/common/config/riscv/riscv-common.cc > b/gcc/common/config/riscv/riscv-common.cc > index f2ede074ac5..6582c15bae2 100644 > --- a/gcc/common/config/riscv/riscv-common.cc > +++ b/gcc/common/config/riscv/riscv-common.cc > @@ -378,7 +378,7 @@ riscv_subset_t::riscv_subset_t () > { > } > > -riscv_subset_list::riscv_subset_list (const char *arch, location_t loc) > +riscv_subset_list::riscv_subset_list (const char *arch, location_t *loc) > : m_arch (arch), m_loc (loc), m_head (NULL), m_tail (NULL), m_xlen (0), > m_subset_num (0), m_allow_adding_dup (false) > { > @@ -584,47 +584,49 @@ riscv_subset_list::add (const char *subset, int > major_version, > else > { > /* The extension is already in the list. */ > - if (!m_allow_adding_dup > - || ext->major_version != major_version > - || ext->minor_version != minor_version) > - error_at ( > - m_loc, > - "%<-march=%s%>: extension %qs appear more than one time", > - m_arch, > - subset); > + if (m_loc > + && (!m_allow_adding_dup > + || ext->major_version != major_version > + || ext->minor_version != minor_version)) > + error_at (*m_loc, "%<-march=%s%>: extension %qs appear more " > + "than one time", m_arch, subset); > } > return; > } > else if (strlen (subset) == 1 && !standard_extensions_p (subset)) > { > - error_at (m_loc, > - "%<-march=%s%>: extension %qs is unsupported standard single " > - "letter extension", > - m_arch, subset); > + if (m_loc) > + error_at (*m_loc, > + "%<-march=%s%>: extension %qs is unsupported standard " > + "single letter extension", > + m_arch, subset); > return; > } > else if (subset[0] == 'z' && !standard_extensions_p (subset)) > { > - error_at (m_loc, > - "%<-march=%s%>: extension %qs starts with 'z' but is " > - "unsupported standard extension", > - m_arch, subset); > + if (m_loc) > + error_at (*m_loc, > + "%<-march=%s%>: extension %qs starts with 'z' but is " > + "unsupported standard extension", > + m_arch, subset); > return; > } > else if (subset[0] == 's' && !standard_extensions_p (subset)) > { > - error_at (m_loc, > - "%<-march=%s%>: extension %qs starts with 's' but is " > - "unsupported standard supervisor extension", > - m_arch, subset); > + if (m_loc) > + error_at (*m_loc, > + "%<-march=%s%>: extension %qs starts with 's' but is " > + "unsupported standard supervisor extension", > + m_arch, subset); > return; > } > else if (subset[0] == 'x' && !standard_extensions_p (subset)) > { > - error_at (m_loc, > - "%<-march=%s%>: extension %qs starts with 'x' but is " > - "unsupported non-standard extension", > - m_arch, subset); > + if (m_loc) > + error_at (*m_loc, > + "%<-march=%s%>: extension %qs starts with 'x' but is " > + "unsupported non-standard extension", > + m_arch, subset); > return; > } > > @@ -886,15 +888,17 @@ riscv_subset_list::parsing_subset_version (const char > *ext, > { > if (!ISDIGIT (*(p+1))) > { > - error_at (m_loc, "%<-march=%s%>: expect number " > - "after %<%dp%>", m_arch, version); > + if (m_loc) > + error_at (*m_loc, "%<-march=%s%>: expect number " > + "after %<%dp%>", m_arch, version); > return NULL; > } > if (!major_p) > { > - error_at (m_loc, "%<-march=%s%>: for %<%s%dp%dp?%>, version " > - "number with more than 2 level is not supported", > - m_arch, ext, major, version); > + if (m_loc) > + error_at (*m_loc, "%<-march=%s%>: for %<%s%dp%dp?%>, " > + "version number with more than 2 level is not " > + "supported", m_arch, ext, major, version); > return NULL; > } > major = version; > @@ -957,8 +961,9 @@ riscv_subset_list::parse_profiles (const char *arch) > /* If isn't '_' after profile, need to add it and mention the user. > */ > if (after_part[0] != '_') > { > - warning_at (m_loc, 0, "Should use \"%c\" to contact Profiles with > other " > - "extensions", '_'); > + if (m_loc) > + warning_at (*m_loc, 0, "Should use \"%c\" to contact Profiles " > + "with other extensions", '_'); > return p_str + "_" + after_part; > } > > @@ -996,9 +1001,10 @@ riscv_subset_list::parse_base_ext (const char *p) > } > else > { > - error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32, > rv64," > - " a supported RVA profile or refer to a supported CPU", > - m_arch); > + if (m_loc) > + error_at (*m_loc, "%<-march=%s%>: ISA string must begin with rv32, " > + "rv64, a supported RVA profile or refer to a supported CPU", > + m_arch); > return NULL; > } > > @@ -1021,8 +1027,9 @@ riscv_subset_list::parse_base_ext (const char *p) > > if (m_xlen > 64) > { > - error_at (m_loc, "%<-march=%s%>: rv%de is not a valid base ISA", > - m_arch, m_xlen); > + if (m_loc) > + error_at (*m_loc, "%<-march=%s%>: rv%de is not a valid base ISA", > + m_arch, m_xlen); > return NULL; > } > break; > @@ -1033,8 +1040,9 @@ riscv_subset_list::parse_base_ext (const char *p) > /* std_ext_p= */ true, &explicit_version_p); > if (major_version != 0 || minor_version != 0) > { > - warning_at (m_loc, 0, "version of %<g%> will be omitted, please " > - "specify version for individual extension"); > + if (m_loc) > + warning_at (*m_loc, 0, "version of %<g%> will be omitted, please " > + "specify version for individual extension"); > } > > /* We have special rule for G, we disallow rv32gm2p but allow > rv32g_zicsr > @@ -1052,8 +1060,9 @@ riscv_subset_list::parse_base_ext (const char *p) > break; > > default: > - error_at (m_loc, "%<-march=%s%>: first ISA subset must be %<e%>, " > - "%<i%> or %<g%>", m_arch); > + if (m_loc) > + error_at (*m_loc, "%<-march=%s%>: first ISA subset must be %<e%>, " > + "%<i%> or %<g%>", m_arch); > return NULL; > } > return p; > @@ -1074,10 +1083,9 @@ riscv_subset_list::parse_single_std_ext (const char > *p, bool exact_single_p) > { > if (*p == 'x' || *p == 's' || *p == 'z') > { > - error_at (m_loc, > - "%<-march=%s%>: Not single-letter extension. " > - "%<%c%>", > - m_arch, *p); > + if (m_loc) > + error_at (*m_loc, "%<-march=%s%>: Not single-letter extension. > %<%c%>", > + m_arch, *p); > return nullptr; > } > > @@ -1183,54 +1191,58 @@ riscv_subset_list::handle_combine_ext () > void > riscv_subset_list::check_conflict_ext () > { > + if (!m_loc) > + return; > + > if (lookup ("zcf") && m_xlen == 64) > - error_at (m_loc, "%<-march=%s%>: zcf extension supports in rv32 only", > + error_at (*m_loc, "%<-march=%s%>: zcf extension supports in rv32 only", > m_arch); > > if (lookup ("zilsd") && m_xlen == 64) > - error_at (m_loc, "%<-march=%s%>: zilsd extension supports in rv32 only", > + error_at (*m_loc, "%<-march=%s%>: zilsd extension supports in rv32 only", > m_arch); > > if (lookup ("zclsd") && m_xlen == 64) > - error_at (m_loc, "%<-march=%s%>: zclsd extension supports in rv32 only", > + error_at (*m_loc, "%<-march=%s%>: zclsd extension supports in rv32 only", > m_arch); > > if (lookup ("ssnpm") && m_xlen == 32) > - error_at (m_loc, "%<-march=%s%>: ssnpm extension supports in rv64 only", > + error_at (*m_loc, "%<-march=%s%>: ssnpm extension supports in rv64 only", > m_arch); > > if (lookup ("smnpm") && m_xlen == 32) > - error_at (m_loc, "%<-march=%s%>: smnpm extension supports in rv64 only", > + error_at (*m_loc, "%<-march=%s%>: smnpm extension supports in rv64 only", > m_arch); > > if (lookup ("smmpm") && m_xlen == 32) > - error_at (m_loc, "%<-march=%s%>: smmpm extension supports in rv64 only", > + error_at (*m_loc, "%<-march=%s%>: smmpm extension supports in rv64 only", > m_arch); > > if (lookup ("sspm") && m_xlen == 32) > - error_at (m_loc, "%<-march=%s%>: sspm extension supports in rv64 only", > + error_at (*m_loc, "%<-march=%s%>: sspm extension supports in rv64 only", > m_arch); > > if (lookup ("supm") && m_xlen == 32) > - error_at (m_loc, "%<-march=%s%>: supm extension supports in rv64 only", > + error_at (*m_loc, "%<-march=%s%>: supm extension supports in rv64 only", > m_arch); > > if (lookup ("zfinx") && lookup ("f")) > - error_at (m_loc, > + error_at (*m_loc, > "%<-march=%s%>: z*inx conflicts with floating-point " > "extensions", > m_arch); > > /* 'H' hypervisor extension requires base ISA with 32 registers. */ > if (lookup ("e") && lookup ("h")) > - error_at (m_loc, "%<-march=%s%>: h extension requires i extension", > m_arch); > + error_at (*m_loc, "%<-march=%s%>: h extension requires i extension", > + m_arch); > > if (lookup ("zcd")) > { > if (lookup ("zcmt")) > - error_at (m_loc, "%<-march=%s%>: zcd conflicts with zcmt", m_arch); > + error_at (*m_loc, "%<-march=%s%>: zcd conflicts with zcmt", m_arch); > if (lookup ("zcmp")) > - error_at (m_loc, "%<-march=%s%>: zcd conflicts with zcmp", m_arch); > + error_at (*m_loc, "%<-march=%s%>: zcd conflicts with zcmp", m_arch); > } > > if ((lookup ("v") || lookup ("zve32x") > @@ -1238,9 +1250,9 @@ riscv_subset_list::check_conflict_ext () > || lookup ("zve64f") || lookup ("zve64d") > || lookup ("zvl32b") || lookup ("zvl64b") > || lookup ("zvl128b") || lookup ("zvfh")) > - && lookup ("xtheadvector")) > - error_at (m_loc, "%<-march=%s%>: xtheadvector conflicts with vector " > - "extension or its sub-extensions", m_arch); > + && lookup ("xtheadvector")) > + error_at (*m_loc, "%<-march=%s%>: xtheadvector conflicts with vector " > + "extension or its sub-extensions", m_arch); > } > > /* Parsing function for multi-letter extensions. > @@ -1336,8 +1348,9 @@ riscv_subset_list::parse_single_multiletter_ext (const > char *p, > > if (strlen (subset) == 1) > { > - error_at (m_loc, "%<-march=%s%>: name of %s must be more than 1 > letter", > - m_arch, ext_type_str); > + if (m_loc) > + error_at (*m_loc, "%<-march=%s%>: name of %s must be more " > + "than 1 letter", m_arch, ext_type_str); > free (subset); > return NULL; > } > @@ -1348,8 +1361,9 @@ riscv_subset_list::parse_single_multiletter_ext (const > char *p, > > if (*p != '\0' && *p != '_') > { > - error_at (m_loc, "%<-march=%s%>: %s must separate with %<_%>", > - m_arch, ext_type_str); > + if (m_loc) > + error_at (*m_loc, "%<-march=%s%>: %s must separate with %<_%>", > + m_arch, ext_type_str); > return NULL; > } > > @@ -1386,10 +1400,12 @@ riscv_subset_list::parse_single_ext (const char *p, > bool exact_single_p) > } > } > > -/* Parsing arch string to subset list, return NULL if parsing failed. */ > +/* Parsing arch string to subset list, return NULL if parsing failed. > + If LOC is nonnull, report diagnostics against location *LOC, otherwise > + remain silent. */ > > riscv_subset_list * > -riscv_subset_list::parse (const char *arch, location_t loc) > +riscv_subset_list::parse (const char *arch, location_t *loc) > { > if (riscv_subset_list::parse_failed) > return NULL; > @@ -1412,8 +1428,9 @@ riscv_subset_list::parse (const char *arch, location_t > loc) > case 'e': > case 'i': > case 'g': > - error_at (loc, "%<-march=%s%>: i, e or g must be the first > extension", > - arch); > + if (loc) > + error_at (*loc, "%<-march=%s%>: i, e or g must be " > + "the first extension", arch); > goto fail; > default: > p = subset_list->parse_single_ext (p, /*exact_single_p=*/ false); > @@ -1448,7 +1465,7 @@ riscv_subset_list::clone () const > } > > void > -riscv_subset_list::set_loc (location_t loc) > +riscv_subset_list::set_loc (location_t *loc) > { > m_loc = loc; > } > @@ -1622,12 +1639,15 @@ riscv_ext_is_subset (struct cl_target_option *opts, > The minimal feature bits refer to using the earliest extension that > appeared > in the Linux hwprobe to support the specified ISA string. This ensures > that > older kernels, which may lack certain implied extensions, can still run > the > - FMV dispatcher correctly. */ > + FMV dispatcher correctly. > + > + If LOC is nonnull, report any diagnostics against *LOC, otherwise remain > + silent. */ > > bool > riscv_minimal_hwprobe_feature_bits (const char *isa, > struct riscv_feature_bits *res, > - location_t loc) > + location_t *loc) > { > riscv_subset_list *subset_list; > subset_list = riscv_subset_list::parse (isa, loc); > @@ -1697,7 +1717,7 @@ riscv_parse_arch_string (const char *isa, > location_t loc) > { > riscv_subset_list *subset_list; > - subset_list = riscv_subset_list::parse (isa, loc); > + subset_list = riscv_subset_list::parse (isa, &loc); > if (!subset_list) > return; > > @@ -1904,7 +1924,8 @@ riscv_multi_lib_info_t::parse ( > } > > multi_lib_info->subset_list = > - riscv_subset_list::parse (multi_lib_info->arch_str.c_str (), > input_location); > + riscv_subset_list::parse (multi_lib_info->arch_str.c_str (), > + &input_location); > > return true; > } > @@ -2093,7 +2114,7 @@ riscv_compute_multilib ( > return multilib_dir; > > subset_list = riscv_subset_list::parse (riscv_current_arch_str.c_str (), > - input_location); > + &input_location); > > /* Failed to parse -march, fallback to using what gcc use. */ > if (subset_list == NULL) > diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h > index b4973251535..cf417e733fc 100644 > --- a/gcc/config/riscv/riscv-protos.h > +++ b/gcc/config/riscv/riscv-protos.h > @@ -837,7 +837,7 @@ riscv_option_valid_attribute_p (tree, tree, tree, int); > extern bool > riscv_option_valid_version_attribute_p (tree, tree, tree, int); > extern bool > -riscv_process_target_version_attr (tree, location_t); > +riscv_process_target_version_attr (tree, location_t *); > extern void > riscv_override_options_internal (struct gcc_options *); > extern void riscv_option_override (void); > diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h > index a35537d7754..4cd860fee59 100644 > --- a/gcc/config/riscv/riscv-subset.h > +++ b/gcc/config/riscv/riscv-subset.h > @@ -52,8 +52,9 @@ private: > /* Original arch string. */ > const char *m_arch; > > - /* Location of arch string, used for report error. */ > - location_t m_loc; > + /* A pointer to the location that should be used for diagnostics, > + or null if diagnostics should be suppressed. */ > + location_t *m_loc; > > /* Head of subset info list. */ > riscv_subset_t *m_head; > @@ -70,7 +71,7 @@ private: > /* Allow adding the same extension more than once. */ > bool m_allow_adding_dup; > > - riscv_subset_list (const char *, location_t); > + riscv_subset_list (const char *, location_t *); > > const char *parsing_subset_version (const char *, const char *, unsigned *, > unsigned *, bool, bool *); > @@ -106,12 +107,12 @@ public: > > riscv_subset_list *clone () const; > > - static riscv_subset_list *parse (const char *, location_t); > + static riscv_subset_list *parse (const char *, location_t *); > const char *parse_single_ext (const char *, bool exact_single_p = true); > > int match_score (riscv_subset_list *) const; > > - void set_loc (location_t); > + void set_loc (location_t *); > > void set_allow_adding_dup (bool v) { m_allow_adding_dup = v; } > > @@ -182,7 +183,7 @@ extern void > riscv_set_arch_by_subset_list (riscv_subset_list *, struct gcc_options *); > extern bool riscv_minimal_hwprobe_feature_bits (const char *, > struct riscv_feature_bits *, > - location_t); > + location_t *); > extern bool > riscv_ext_is_subset (struct cl_target_option *, struct cl_target_option *); > > diff --git a/gcc/config/riscv/riscv-target-attr.cc > b/gcc/config/riscv/riscv-target-attr.cc > index 8ad3025579b..5e01c921454 100644 > --- a/gcc/config/riscv/riscv-target-attr.cc > +++ b/gcc/config/riscv/riscv-target-attr.cc > @@ -34,7 +34,7 @@ namespace { > class riscv_target_attr_parser > { > public: > - riscv_target_attr_parser (location_t loc) > + riscv_target_attr_parser (location_t *loc) > : m_found_arch_p (false) > , m_found_tune_p (false) > , m_found_cpu_p (false) > @@ -62,7 +62,7 @@ private: > bool m_found_cpu_p; > bool m_found_priority_p; > riscv_subset_list *m_subset_list; > - location_t m_loc; > + location_t *m_loc; > const riscv_cpu_info *m_cpu_info; > const char *m_tune; > int m_priority; > @@ -102,15 +102,17 @@ riscv_target_attr_parser::parse_arch (const char *str) > { > if (TARGET_64BIT && strncmp ("32", str + 2, strlen ("32")) == 0) > { > - error_at (m_loc, "unexpected arch for %<target()%> attribute: " > - "must start with rv64 but found %qs", str); > + if (m_loc) > + error_at (*m_loc, "unexpected arch for %<target()%> attribute: " > + "must start with rv64 but found %qs", str); > goto fail; > } > > if (!TARGET_64BIT && strncmp ("64", str + 2, strlen ("64")) == 0) > { > - error_at (m_loc, "unexpected arch for %<target()%> attribute: " > - "must start with rv32 but found %qs", str); > + if (m_loc) > + error_at (*m_loc, "unexpected arch for %<target()%> attribute: " > + "must start with rv32 but found %qs", str); > goto fail; > } > > @@ -140,10 +142,9 @@ riscv_target_attr_parser::parse_arch (const char *str) > { > if (token[0] != '+') > { > - error_at ( > - m_loc, > - "unexpected arch for %<target()%> attribute: must start " > - "with + or rv"); > + if (*m_loc) > + error_at (*m_loc, "unexpected arch for %<target()%> " > + "attribute: must start with + or rv"); > goto fail; > } > > @@ -151,10 +152,9 @@ riscv_target_attr_parser::parse_arch (const char *str) > /* Check parse_single_ext has consume all string. */ > if (*result != '\0') > { > - error_at ( > - m_loc, > - "unexpected arch for %<target()%> attribute: bad " > - "string found %qs", token); > + if (m_loc) > + error_at (*m_loc, "unexpected arch for %<target()%> " > + "attribute: bad string found %qs", token); > goto fail; > } > > @@ -179,8 +179,8 @@ fail: > bool > riscv_target_attr_parser::handle_arch (const char *str) > { > - if (m_found_arch_p) > - error_at (m_loc, "%<target()%> attribute: arch appears more than once"); > + if (m_found_arch_p && m_loc) > + error_at (*m_loc, "%<target()%> attribute: arch appears more than once"); > m_found_arch_p = true; > return parse_arch (str); > } > @@ -190,15 +190,16 @@ riscv_target_attr_parser::handle_arch (const char *str) > bool > riscv_target_attr_parser::handle_cpu (const char *str) > { > - if (m_found_cpu_p) > - error_at (m_loc, "%<target()%> attribute: cpu appears more than once"); > + if (m_found_cpu_p && m_loc) > + error_at (*m_loc, "%<target()%> attribute: cpu appears more than once"); > > m_found_cpu_p = true; > const riscv_cpu_info *cpu_info = riscv_find_cpu (str); > > if (!cpu_info) > { > - error_at (m_loc, "%<target()%> attribute: unknown CPU %qs", str); > + if (m_loc) > + error_at (*m_loc, "%<target()%> attribute: unknown CPU %qs", str); > return false; > } > > @@ -218,14 +219,15 @@ riscv_target_attr_parser::handle_cpu (const char *str) > bool > riscv_target_attr_parser::handle_tune (const char *str) > { > - if (m_found_tune_p) > - error_at (m_loc, "%<target()%> attribute: tune appears more than once"); > + if (m_found_tune_p && m_loc) > + error_at (*m_loc, "%<target()%> attribute: tune appears more than once"); > m_found_tune_p = true; > const struct riscv_tune_info *tune = riscv_parse_tune (str, true); > > if (tune == nullptr) > { > - error_at (m_loc, "%<target()%> attribute: unknown TUNE %qs", str); > + if (m_loc) > + error_at (*m_loc, "%<target()%> attribute: unknown TUNE %qs", str); > return false; > } > > @@ -237,13 +239,15 @@ riscv_target_attr_parser::handle_tune (const char *str) > bool > riscv_target_attr_parser::handle_priority (const char *str) > { > - if (m_found_priority_p) > - error_at (m_loc, "%<target()%> attribute: priority appears more than > once"); > + if (m_found_priority_p && m_loc) > + error_at (*m_loc, "%<target()%> attribute: priority appears " > + "more than once"); > m_found_priority_p = true; > > if (sscanf (str, "%d", &m_priority) != 1) > { > - error_at (m_loc, "%<target()%> attribute: invalid priority %qs", str); > + if (m_loc) > + error_at (*m_loc, "%<target()%> attribute: invalid priority %qs", > str); > return false; > } > > @@ -282,7 +286,7 @@ riscv_target_attr_parser::update_settings (struct > gcc_options *opts) const > > static bool > riscv_process_one_target_attr (char *arg_str, > - location_t loc, > + location_t *loc, > riscv_target_attr_parser &attr_parser, > const struct riscv_attribute_info *attrs) > { > @@ -290,7 +294,8 @@ riscv_process_one_target_attr (char *arg_str, > > if (len == 0) > { > - error_at (loc, "malformed %<target()%> attribute"); > + if (loc) > + error_at (*loc, "malformed %<target()%> attribute"); > return false; > } > > @@ -302,10 +307,9 @@ riscv_process_one_target_attr (char *arg_str, > > if (!arg) > { > - error_at ( > - loc, > - "attribute %<target(\"%s\")%> does not accept an argument", > - str_to_check); > + if (loc) > + error_at (*loc, "attribute %<target(\"%s\")%> does not " > + "accept an argument", str_to_check); > return false; > } > > @@ -324,7 +328,8 @@ riscv_process_one_target_attr (char *arg_str, > return (&attr_parser->*attr->handler) (arg); > } > > - error_at (loc, "Got unknown attribute %<target(\"%s\")%>", str_to_check); > + if (loc) > + error_at (*loc, "Got unknown attribute %<target(\"%s\")%>", > str_to_check); > return false; > } > > @@ -347,11 +352,12 @@ num_occurrences_in_str (char c, char *str) > } > > /* Parse the string in ARGS that contains the target attribute information > - and update the global target options space. */ > + and update the global target options space. If LOC is nonnull, report > + diagnostics against location *LOC, otherwise remain silent. */ > > bool > riscv_process_target_attr (const char *args, > - location_t loc, > + location_t *loc, > const struct riscv_attribute_info *attrs) > { > size_t len = strlen (args); > @@ -387,8 +393,8 @@ riscv_process_target_attr (const char *args, > > if (num_attrs != num_semicolons + 1) > { > - error_at (loc, "malformed %<target(\"%s\")%> attribute", > - args); > + if (loc) > + error_at (*loc, "malformed %<target(\"%s\")%> attribute", args); > return false; > } > > @@ -399,11 +405,12 @@ riscv_process_target_attr (const char *args, > } > > /* Parse the tree in ARGS that contains the target attribute information > - and update the global target options space. */ > + and update the global target options space. If LOC is nonnull, report > + diagnostics against *LOC, otherwise remain silent. */ > > static bool > riscv_process_target_attr (tree args, > - location_t loc, > + location_t *loc, > const struct riscv_attribute_info *attrs) > { > if (TREE_CODE (args) == TREE_LIST) > @@ -424,7 +431,8 @@ riscv_process_target_attr (tree args, > > if (TREE_CODE (args) != STRING_CST) > { > - error_at (loc, "attribute %<target%> argument not a string"); > + if (loc) > + error_at (*loc, "attribute %<target%> argument not a string"); > return false; > } > > @@ -466,7 +474,7 @@ riscv_option_valid_attribute_p (tree fndecl, tree, tree > args, int) > TREE_TARGET_OPTION > (target_option_default_node)); > > /* Now we can parse the attributes and set &global_options accordingly. */ > - ret = riscv_process_target_attr (args, loc, riscv_target_attrs); > + ret = riscv_process_target_attr (args, &loc, riscv_target_attrs); > if (ret) > { > riscv_override_options_internal (&global_options); > @@ -481,16 +489,19 @@ riscv_option_valid_attribute_p (tree fndecl, tree, tree > args, int) > } > > /* Parse the tree in ARGS that contains the target_version attribute > - information and update the global target options space. */ > + information and update the global target options space. If LOC is > nonnull, > + report diagnostics against *LOC, otherwise remain silent. */ > > bool > -riscv_process_target_version_attr (tree args, location_t loc) > +riscv_process_target_version_attr (tree args, location_t *loc) > { > if (TREE_CODE (args) == TREE_LIST) > { > if (TREE_CHAIN (args)) > { > - error ("attribute %<target_version%> has multiple values"); > + if (loc) > + error_at (*loc, "attribute %<target_version%> " > + "has multiple values"); > return false; > } > args = TREE_VALUE (args); > @@ -498,7 +509,8 @@ riscv_process_target_version_attr (tree args, location_t > loc) > > if (!args || TREE_CODE (args) != STRING_CST) > { > - error ("attribute %<target_version%> argument not a string"); > + if (loc) > + error_at (*loc, "attribute %<target_version%> argument not a string"); > return false; > } > > @@ -541,7 +553,7 @@ riscv_option_valid_version_attribute_p (tree fndecl, > tree, tree args, int) > cl_target_option_restore (&global_options, &global_options_set, > TREE_TARGET_OPTION > (target_option_current_node)); > > - ret = riscv_process_target_version_attr (args, loc); > + ret = riscv_process_target_version_attr (args, &loc); > > /* Set up any additional state. */ > if (ret) > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > index 4935367dd0e..e3b385b9150 100644 > --- a/gcc/config/riscv/riscv.cc > +++ b/gcc/config/riscv/riscv.cc > @@ -13949,10 +13949,13 @@ riscv_c_mode_for_floating_type (enum tree_index ti) > return default_mode_for_floating_type (ti); > } > > -/* This parses the attribute arguments to target_version in DECL and modifies > - the feature mask and priority required to select those targets. */ > +/* Parse the attribute arguments to target_version in DECL and modify > + the feature mask and priority required to select those targets. > + If LOC is nonnull, report diagnostics against *LOC, otherwise > + remain silent. */ > static void > parse_features_for_version (tree decl, > + location_t *loc, > struct riscv_feature_bits &res, > int &priority) > { > @@ -13983,14 +13986,12 @@ parse_features_for_version (tree decl, > cl_target_option_restore (&global_options, &global_options_set, > default_opts); > > - riscv_process_target_version_attr (TREE_VALUE (version_attr), > - DECL_SOURCE_LOCATION (decl)); > + riscv_process_target_version_attr (TREE_VALUE (version_attr), loc); > > priority = global_options.x_riscv_fmv_priority; > const char *arch_string = global_options.x_riscv_arch_string; > bool parse_res > - = riscv_minimal_hwprobe_feature_bits (arch_string, &res, > - DECL_SOURCE_LOCATION (decl)); > + = riscv_minimal_hwprobe_feature_bits (arch_string, &res, loc); > gcc_assert (parse_res); > > cl_target_option_restore (&global_options, &global_options_set, > @@ -14047,8 +14048,8 @@ riscv_compare_version_priority (tree decl1, tree > decl2) > struct riscv_feature_bits mask1, mask2; > int prio1, prio2; > > - parse_features_for_version (decl1, mask1, prio1); > - parse_features_for_version (decl2, mask2, prio2); > + parse_features_for_version (decl1, nullptr, mask1, prio1); > + parse_features_for_version (decl2, nullptr, mask2, prio2); > > return compare_fmv_features (mask1, mask2, prio1, prio2); > } > @@ -14351,6 +14352,7 @@ dispatch_function_versions (tree dispatch_decl, > version_info.version_decl = version_decl; > // Get attribute string, parse it and find the right features. > parse_features_for_version (version_decl, > + &DECL_SOURCE_LOCATION (version_decl), > version_info.features, > version_info.prio); > function_versions.push_back (version_info); > -- > 2.43.0 >