[PATCHSET] Add error metadata to diagnostics
This short patchset from David Malcolm enables errors to contain extra metadata - this is particularly useful for the Rust frontend, which will rely on that implementation to emit standard Rust error codes [1]. This series of patches is necessary for much of our more recent additions to the frontend, including the work of one of this year's GSoC student, Mahad Muhammad, who has spent a lot of time working on emitting these error codes from the Rust frontend for GCC. We will soon resume upstreaming patches from our development repository to the main GCC repository, in the hopes of distributing the Rust frontend as part of the GCC 14.1 release. [PATCH 1/2] diagnostics: add error_meta [PATCH 2/2] Experiment with adding an error code to an error Are these OK for trunk? Kindly, Arthur -- Gcc-rust mailing list Gcc-rust@gcc.gnu.org https://gcc.gnu.org/mailman/listinfo/gcc-rust
[PATCH 1/2] diagnostics: add error_meta
From: David Malcolm --- gcc/diagnostic-core.h | 3 +++ gcc/diagnostic.cc | 15 +++ 2 files changed, 18 insertions(+) diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h index 7334c79e8e6..c9e27fd2e6e 100644 --- a/gcc/diagnostic-core.h +++ b/gcc/diagnostic-core.h @@ -92,6 +92,9 @@ extern void error_n (location_t, unsigned HOST_WIDE_INT, const char *, extern void error_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); extern void error_at (rich_location *, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); +extern void error_meta (rich_location *, const diagnostic_metadata &, + const char *, ...) + ATTRIBUTE_GCC_DIAG(3,4); extern void fatal_error (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3) ATTRIBUTE_NORETURN; /* Pass one of the OPT_W* from options.h as the second parameter. */ diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index c523f215bae..65c0cfbf11a 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -2108,6 +2108,21 @@ error_at (rich_location *richloc, const char *gmsgid, ...) va_end (ap); } +/* Same as above, but with metadata. */ + +void +error_meta (rich_location *richloc, const diagnostic_metadata &metadata, + const char *gmsgid, ...) +{ + gcc_assert (richloc); + + auto_diagnostic_group d; + va_list ap; + va_start (ap, gmsgid); + diagnostic_impl (richloc, &metadata, -1, gmsgid, &ap, DK_ERROR); + va_end (ap); +} + /* "Sorry, not implemented." Use for a language feature which is required by the relevant specification but not implemented by GCC. An object file will not be produced. */ -- 2.40.0 -- Gcc-rust mailing list Gcc-rust@gcc.gnu.org https://gcc.gnu.org/mailman/listinfo/gcc-rust
[PATCH 2/2] Experiment with adding an error code to an error
From: David Malcolm --- gcc/rust/rust-diagnostics.cc | 11 +++ gcc/rust/rust-diagnostics.h | 18 ++ gcc/rust/rust-gcc-diagnostics.cc | 33 +++ gcc/rust/typecheck/rust-casts.cc | 2 +- .../rust/compile/bad_as_bool_char.rs | 4 +-- 5 files changed, 65 insertions(+), 3 deletions(-) diff --git a/gcc/rust/rust-diagnostics.cc b/gcc/rust/rust-diagnostics.cc index 4e5c2ececd4..f29aec67652 100644 --- a/gcc/rust/rust-diagnostics.cc +++ b/gcc/rust/rust-diagnostics.cc @@ -166,6 +166,17 @@ rust_error_at (const Location location, const char *fmt, ...) va_end (ap); } +void +rust_error_at (const RichLocation &location, const ErrorCode code, + const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + rust_be_error_at (location, code, expand_message (fmt, ap)); + va_end (ap); +} + void rust_warning_at (const Location location, int opt, const char *fmt, ...) { diff --git a/gcc/rust/rust-diagnostics.h b/gcc/rust/rust-diagnostics.h index 43fee8baf4f..d198bd5736f 100644 --- a/gcc/rust/rust-diagnostics.h +++ b/gcc/rust/rust-diagnostics.h @@ -50,6 +50,18 @@ // clang-format off // simple location + +struct ErrorCode +{ + explicit ErrorCode (const char *str) : m_str (str) + { +gcc_assert (str); +gcc_assert (str[0] == 'E'); + } + + const char *m_str; +}; + extern void rust_internal_error_at (const Location, const char *fmt, ...) RUST_ATTRIBUTE_GCC_DIAG (2, 3) @@ -72,6 +84,9 @@ rust_inform (const Location, const char *fmt, ...) extern void rust_error_at (const RichLocation &, const char *fmt, ...) RUST_ATTRIBUTE_GCC_DIAG (2, 3); +extern void +rust_error_at (const RichLocation &, const ErrorCode, const char *fmt, ...) + RUST_ATTRIBUTE_GCC_DIAG (3, 4); // clang-format on // These interfaces provide a way for the front end to ask for @@ -97,6 +112,9 @@ rust_be_error_at (const Location, const std::string &errmsg); extern void rust_be_error_at (const RichLocation &, const std::string &errmsg); extern void +rust_be_error_at (const RichLocation &, const ErrorCode, + const std::string &errmsg); +extern void rust_be_warning_at (const Location, int opt, const std::string &warningmsg); extern void rust_be_fatal_error (const Location, const std::string &errmsg) diff --git a/gcc/rust/rust-gcc-diagnostics.cc b/gcc/rust/rust-gcc-diagnostics.cc index 72d2c068541..58c0a5654ea 100644 --- a/gcc/rust/rust-gcc-diagnostics.cc +++ b/gcc/rust/rust-gcc-diagnostics.cc @@ -22,6 +22,7 @@ #include "rust-diagnostics.h" #include "options.h" +#include "diagnostic-metadata.h" void rust_be_internal_error_at (const Location location, const std::string &errmsg) @@ -70,6 +71,38 @@ rust_be_error_at (const RichLocation &location, const std::string &errmsg) error_at (&gcc_loc, "%s", errmsg.c_str ()); } +class rust_error_code_rule : public diagnostic_metadata::rule +{ +public: + rust_error_code_rule (const ErrorCode code) : m_code (code) {} + + char *make_description () const final override + { +return xstrdup (m_code.m_str); + } + + char *make_url () const final override + { +return concat ("https://doc.rust-lang.org/error-index.html#";, m_code.m_str, + NULL); + } + +private: + const ErrorCode m_code; +}; + +void +rust_be_error_at (const RichLocation &location, const ErrorCode code, + const std::string &errmsg) +{ + /* TODO: 'error_at' would like a non-'const' 'rich_location *'. */ + rich_location &gcc_loc = const_cast (location.get ()); + diagnostic_metadata m; + rust_error_code_rule rule (code); + m.add_rule (rule); + error_meta (&gcc_loc, m, "%s", errmsg.c_str ()); +} + void rust_be_get_quotechars (const char **open_qu, const char **close_qu) { diff --git a/gcc/rust/typecheck/rust-casts.cc b/gcc/rust/typecheck/rust-casts.cc index e379216b948..987542e59c4 100644 --- a/gcc/rust/typecheck/rust-casts.cc +++ b/gcc/rust/typecheck/rust-casts.cc @@ -283,7 +283,7 @@ TypeCastRules::emit_cast_error () const RichLocation r (locus); r.add_range (from.get_locus ()); r.add_range (to.get_locus ()); - rust_error_at (r, "invalid cast %<%s%> to %<%s%>", + rust_error_at (r, ErrorCode ("E0054"), "invalid cast %<%s%> to %<%s%>", from.get_ty ()->get_name ().c_str (), to.get_ty ()->get_name ().c_str ()); } diff --git a/gcc/testsuite/rust/compile/bad_as_bool_char.rs b/gcc/testsuite/rust/compile/bad_as_bool_char.rs index 91a28eebe00..9652915fe11 100644 --- a/gcc/testsuite/rust/compile/bad_as_bool_char.rs +++ b/gcc/testsuite/rust/compile/bad_as_bool_char.rs @@ -5,13 +5,13 @@ pub fn main () let fone = t as f32; // { dg-error "invalid cast" } let fzero = f as f64; // { dg-error "invalid cast" } - let nb = 0u8 as bool; // { dg-error "invalid cast" } + let nb = 0u8 as bool; // { dg-error "invalid cast .u8. to .bool. \\\[E0054\\\]" } let nc = true as char; // { dg-error "inval
Re: [PATCH 1/2] diagnostics: add error_meta
On Wed, 2023-09-06 at 15:53 +0200, Arthur Cohen wrote: > From: David Malcolm I guess I can review this patch :) Needs a ChangeLog entry, so here's one: gcc/ChangeLog * diagnostic-core.h (error_meta): New decl. * diagnostic.cc (error_meta): New. Also, needs a signed-off-by, so here's one: Signed-off-by: David Malcolm OK for trunk with those added. Thanks Dave > > --- > gcc/diagnostic-core.h | 3 +++ > gcc/diagnostic.cc | 15 +++ > 2 files changed, 18 insertions(+) > > diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h > index 7334c79e8e6..c9e27fd2e6e 100644 > --- a/gcc/diagnostic-core.h > +++ b/gcc/diagnostic-core.h > @@ -92,6 +92,9 @@ extern void error_n (location_t, unsigned > HOST_WIDE_INT, const char *, > extern void error_at (location_t, const char *, ...) > ATTRIBUTE_GCC_DIAG(2,3); > extern void error_at (rich_location *, const char *, ...) > ATTRIBUTE_GCC_DIAG(2,3); > +extern void error_meta (rich_location *, const diagnostic_metadata > &, > + const char *, ...) > + ATTRIBUTE_GCC_DIAG(3,4); > extern void fatal_error (location_t, const char *, ...) > ATTRIBUTE_GCC_DIAG(2,3) > ATTRIBUTE_NORETURN; > /* Pass one of the OPT_W* from options.h as the second parameter. > */ > diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc > index c523f215bae..65c0cfbf11a 100644 > --- a/gcc/diagnostic.cc > +++ b/gcc/diagnostic.cc > @@ -2108,6 +2108,21 @@ error_at (rich_location *richloc, const char > *gmsgid, ...) > va_end (ap); > } > > +/* Same as above, but with metadata. */ > + > +void > +error_meta (rich_location *richloc, const diagnostic_metadata > &metadata, > + const char *gmsgid, ...) > +{ > + gcc_assert (richloc); > + > + auto_diagnostic_group d; > + va_list ap; > + va_start (ap, gmsgid); > + diagnostic_impl (richloc, &metadata, -1, gmsgid, &ap, DK_ERROR); > + va_end (ap); > +} > + > /* "Sorry, not implemented." Use for a language feature which is > required by the relevant specification but not implemented by > GCC. > An object file will not be produced. */ -- Gcc-rust mailing list Gcc-rust@gcc.gnu.org https://gcc.gnu.org/mailman/listinfo/gcc-rust
Re: [PATCH 2/2] Experiment with adding an error code to an error
On Wed, 2023-09-06 at 15:53 +0200, Arthur Cohen wrote: > From: David Malcolm This is probably something for the gcc-rust maintainers to review (rather than me self-reviewing with my "diagnostics maintainer" hat on). Doesn't have a ChangeLog entry, FWIW. Doesn't have a signed-off-by, so here's one: Signed-off-by: David Malcolm [...snip...] > diff --git a/gcc/rust/rust-gcc-diagnostics.cc b/gcc/rust/rust-gcc- > diagnostics.cc > index 72d2c068541..58c0a5654ea 100644 > --- a/gcc/rust/rust-gcc-diagnostics.cc > +++ b/gcc/rust/rust-gcc-diagnostics.cc [...snip...] > +void > +rust_be_error_at (const RichLocation &location, const ErrorCode > code, > + const std::string &errmsg) > +{ > + /* TODO: 'error_at' would like a non-'const' 'rich_location *'. The above comment should refer to "error_meta", rather than "error_at"... > */ > + rich_location &gcc_loc = const_cast (location.get > ()); > + diagnostic_metadata m; > + rust_error_code_rule rule (code); > + m.add_rule (rule); > + error_meta (&gcc_loc, m, "%s", errmsg.c_str ()); ... to match this call. [...snip...] Otherwise, LGTM, but as I said, this is more in the gcc-rust maintainers' area. Dave -- Gcc-rust mailing list Gcc-rust@gcc.gnu.org https://gcc.gnu.org/mailman/listinfo/gcc-rust
Re: [PATCH 1/2] diagnostics: add error_meta
On 9/6/23 16:12, David Malcolm wrote: On Wed, 2023-09-06 at 15:53 +0200, Arthur Cohen wrote: From: David Malcolm I guess I can review this patch :) Needs a ChangeLog entry, so here's one: gcc/ChangeLog * diagnostic-core.h (error_meta): New decl. * diagnostic.cc (error_meta): New. Also, needs a signed-off-by, so here's one: Signed-off-by: David Malcolm Right! Now that we enforce Changelogs and SoB lines in our CI, I completely forgot to add them back to older commits. I'll fix the second commit too. Thanks for the fast review! OK for trunk with those added. Thanks Dave --- gcc/diagnostic-core.h | 3 +++ gcc/diagnostic.cc | 15 +++ 2 files changed, 18 insertions(+) diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h index 7334c79e8e6..c9e27fd2e6e 100644 --- a/gcc/diagnostic-core.h +++ b/gcc/diagnostic-core.h @@ -92,6 +92,9 @@ extern void error_n (location_t, unsigned HOST_WIDE_INT, const char *, extern void error_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); extern void error_at (rich_location *, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); +extern void error_meta (rich_location *, const diagnostic_metadata &, + const char *, ...) + ATTRIBUTE_GCC_DIAG(3,4); extern void fatal_error (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3) ATTRIBUTE_NORETURN; /* Pass one of the OPT_W* from options.h as the second parameter. */ diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index c523f215bae..65c0cfbf11a 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -2108,6 +2108,21 @@ error_at (rich_location *richloc, const char *gmsgid, ...) va_end (ap); } +/* Same as above, but with metadata. */ + +void +error_meta (rich_location *richloc, const diagnostic_metadata &metadata, + const char *gmsgid, ...) +{ + gcc_assert (richloc); + + auto_diagnostic_group d; + va_list ap; + va_start (ap, gmsgid); + diagnostic_impl (richloc, &metadata, -1, gmsgid, &ap, DK_ERROR); + va_end (ap); +} + /* "Sorry, not implemented." Use for a language feature which is required by the relevant specification but not implemented by GCC. An object file will not be produced. */ -- Gcc-rust mailing list Gcc-rust@gcc.gnu.org https://gcc.gnu.org/mailman/listinfo/gcc-rust