From: Matthias Kretz <m.kretz@gsi.de>
To: <gcc-patches@gcc.gnu.org>
Cc: <libstdc++@gcc.gnu.org>
Subject: [PATCH] Add gnu::diagnose_as attribute
Date: Tue, 4 May 2021 13:13:23 +0200 [thread overview]
Message-ID: <91863212.B8guWdUDZo@excalibur> (raw)
In-Reply-To: <20210427094648.GL3008@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 3647 bytes --]
From: Matthias Kretz <kretz@kde.org>
This attribute overrides the diagnostics output string for the entity it
appertains to. The motivation is to improve QoI for library TS
implementations, where diagnostics have a very bad signal-to-noise ratio
due to the long namespaces involved.
On Tuesday, 27 April 2021 11:46:48 CEST Jonathan Wakely wrote:
> I think it's a great idea and would like to use it for all the TS
> implementations where there is some inline namespace that the user
> doesn't care about. std::experimental::fundamentals_v1:: would be much
> better as just std::experimental::, or something like std::[LFTS]::.
With the attribute, it is possible to solve PR89370 and make
std::__cxx11::basic_string<_CharT, _Traits, _Alloc> appear as
std::string in diagnostic output without extra hacks to recognize the
type.
gcc/ChangeLog:
PR c++/89370
* doc/extend.texi: Document the diagnose_as attribute.
* doc/invoke.texi: Document -fno-diagnostics-use-aliases.
gcc/c-family/ChangeLog:
PR c++/89370
* c.opt (fdiagnostics-use-aliases): New diagnostics flag.
gcc/cp/ChangeLog:
PR c++/89370
* error.c (dump_scope): When printing the name of a namespace,
look for the diagnose_as attribute. If found, print the
associated string instead of calling dump_decl.
(dump_decl_name_or_diagnose_as): New function to replace
dump_decl (pp, DECL_NAME(t), flags) and inspect the tree for the
diagnose_as attribute before printing the DECL_NAME.
(dump_aggr_type): If the type has a diagnose_as attribute, print
the associated string instead of printing the original type
name.
(dump_simple_decl): Call dump_decl_name_or_diagnose_as instead
of dump_decl.
(dump_decl): Ditto.
(lang_decl_name): Ditto.
(dump_function_decl): Ensure complete replacement of the class
template diagnostics if a diagnose_as attribute is present.
(dump_function_name): Replace the function diagnostic output if
the diagnose_as attribute is set.
* name-lookup.c (handle_namespace_attrs): Handle the diagnose_as
attribute. Ensure exactly one string argument. Ensure previous
diagnose_as attributes used the same name.
* tree.c (cxx_attribute_table): Add diagnose_as attribute to the
table.
(check_diagnose_as_redeclaration): New function; copied and
adjusted from check_abi_tag_redeclaration.
(handle_diagnose_as_attribute): New function; copied and
adjusted from handle_abi_tag_attribute. If the given *node is a
TYPE_DECL and the TREE_TYPE is an implicit class template
instantiation, call decl_attributes to add the diagnose_as
attribute to the TREE_TYPE.
---
gcc/c-family/c.opt | 4 ++
gcc/cp/error.c | 85 ++++++++++++++++++++++++++++---
gcc/cp/name-lookup.c | 27 ++++++++++
gcc/cp/tree.c | 117 +++++++++++++++++++++++++++++++++++++++++++
gcc/doc/extend.texi | 37 ++++++++++++++
gcc/doc/invoke.texi | 9 +++-
6 files changed, 270 insertions(+), 9 deletions(-)
--
──────────────────────────────────────────────────────────────────────────
Dr. Matthias Kretz https://mattkretz.github.io
GSI Helmholtz Centre for Heavy Ion Research https://gsi.de
std::experimental::simd https://github.com/VcDevel/std-simd
──────────────────────────────────────────────────────────────────────────
[-- Attachment #2: 0001-Add-gnu-diagnose_as-attribute.patch --]
[-- Type: text/x-patch, Size: 16239 bytes --]
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 3f8b72cdc00..0cf01c6dba4 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1582,6 +1582,10 @@ fdiagnostics-show-template-tree
C++ ObjC++ Var(flag_diagnostics_show_template_tree) Init(0)
Print hierarchical comparisons when template types are mismatched.
+fdiagnostics-use-aliases
+C++ Var(flag_diagnostics_use_aliases) Init(1)
+Replace identifiers or scope names in diagnostics as defined by the diagnose_as attribute.
+
fdirectives-only
C ObjC C++ ObjC++
Preprocess directives only.
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index c88d1749a0f..10b547afaa7 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "internal-fn.h"
#include "gcc-rich-location.h"
#include "cp-name-hint.h"
+#include "attribs.h"
#define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',')
#define pp_separate_with_semicolon(PP) pp_cxx_separate_with (PP, ';')
@@ -66,6 +67,7 @@ static void dump_alias_template_specialization (cxx_pretty_printer *, tree, int)
static void dump_type (cxx_pretty_printer *, tree, int);
static void dump_typename (cxx_pretty_printer *, tree, int);
static void dump_simple_decl (cxx_pretty_printer *, tree, tree, int);
+static void dump_decl_name_or_diagnose_as (cxx_pretty_printer *, tree, int);
static void dump_decl (cxx_pretty_printer *, tree, int);
static void dump_template_decl (cxx_pretty_printer *, tree, int);
static void dump_function_decl (cxx_pretty_printer *, tree, int);
@@ -231,7 +233,15 @@ dump_scope (cxx_pretty_printer *pp, tree scope, int flags)
{
if (scope != global_namespace)
{
- dump_decl (pp, scope, f);
+ tree diagnose_as
+ = flag_diagnostics_use_aliases
+ ? lookup_attribute ("diagnose_as", DECL_ATTRIBUTES (scope))
+ : NULL_TREE;
+ if (diagnose_as)
+ pp_cxx_ws_string (
+ pp, TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (diagnose_as))));
+ else
+ dump_decl (pp, scope, f);
pp_cxx_colon_colon (pp);
}
}
@@ -743,6 +753,7 @@ dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags)
tree decl = TYPE_NAME (t);
+ tree diagnose_as = NULL_TREE;
if (decl)
{
typdef = (!DECL_ARTIFICIAL (decl)
@@ -769,8 +780,15 @@ dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags)
if (! (flags & TFF_UNQUALIFIED_NAME))
dump_scope (pp, CP_DECL_CONTEXT (decl), flags | TFF_SCOPE);
flags &= ~TFF_UNQUALIFIED_NAME;
+
+ tree diagnose_as_specialized = NULL_TREE;
if (tmplate)
{
+ if (flag_diagnostics_use_aliases)
+ diagnose_as_specialized
+ = lookup_attribute ("diagnose_as",
+ TYPE_ATTRIBUTES (TREE_TYPE (decl)));
+
/* Because the template names are mangled, we have to locate
the most general template, and use that name. */
tree tpl = TYPE_TI_TEMPLATE (t);
@@ -779,9 +797,25 @@ dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags)
tpl = DECL_TI_TEMPLATE (tpl);
decl = tpl;
}
+
+ if (flag_diagnostics_use_aliases)
+ diagnose_as = lookup_attribute ("diagnose_as",
+ TYPE_ATTRIBUTES (TREE_TYPE (decl)));
+ if (diagnose_as_specialized
+ && (!diagnose_as || TREE_VALUE(diagnose_as_specialized)
+ != TREE_VALUE(diagnose_as)))
+ {
+ pp_cxx_ws_string (
+ pp, TREE_STRING_POINTER (
+ TREE_VALUE (TREE_VALUE (diagnose_as_specialized))));
+ return;
+ }
}
- if (LAMBDA_TYPE_P (t))
+ if (diagnose_as)
+ pp_cxx_ws_string (pp, TREE_STRING_POINTER (
+ TREE_VALUE (TREE_VALUE (diagnose_as))));
+ else if (LAMBDA_TYPE_P (t))
{
/* A lambda's "type" is essentially its signature. */
pp_string (pp, M_("<lambda"));
@@ -1103,7 +1137,7 @@ dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags)
pp_string (pp, " capture>");
}
else
- dump_decl (pp, DECL_NAME (t), flags);
+ dump_decl_name_or_diagnose_as (pp, t, flags);
}
else if (DECL_DECOMPOSITION_P (t))
pp_string (pp, M_("<structured bindings>"));
@@ -1147,6 +1181,25 @@ dump_decl_name (cxx_pretty_printer *pp, tree t, int flags)
pp_cxx_tree_identifier (pp, t);
}
+/* Print the DECL_NAME of DECL unless a different string was requested by the
+ diagnose_as attribute. */
+
+static void
+dump_decl_name_or_diagnose_as (cxx_pretty_printer *pp, tree decl, int flags)
+{
+ if (flag_diagnostics_use_aliases)
+ {
+ tree attr = lookup_attribute ("diagnose_as", DECL_ATTRIBUTES (decl));
+ if (attr)
+ {
+ pp_cxx_ws_string (
+ pp, TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
+ return;
+ }
+ }
+ dump_decl_name (pp, DECL_NAME (decl), flags);
+}
+
/* Dump a human readable string for the decl T under control of FLAGS. */
static void
@@ -1192,7 +1245,7 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags)
|| flags & TFF_CLASS_KEY_OR_ENUM))
{
pp_cxx_ws_string (pp, "using");
- dump_decl (pp, DECL_NAME (t), flags);
+ dump_decl_name_or_diagnose_as(pp, t, flags);
pp_cxx_whitespace (pp);
pp_cxx_ws_string (pp, "=");
pp_cxx_whitespace (pp);
@@ -1374,7 +1427,7 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags)
TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX))
dump_simple_decl (pp, t, TREE_TYPE (t), flags);
else if (DECL_NAME (t))
- dump_decl (pp, DECL_NAME (t), flags);
+ dump_decl_name_or_diagnose_as (pp, t, flags);
else if (DECL_INITIAL (t))
dump_expr (pp, DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS);
else
@@ -1393,7 +1446,7 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags)
}
dump_type (pp, scope, flags);
pp_cxx_colon_colon (pp);
- dump_decl (pp, DECL_NAME (t), flags);
+ dump_decl_name_or_diagnose_as (pp, t, flags);
if (variadic)
pp_cxx_ws_string (pp, "...");
}
@@ -1657,7 +1710,13 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
/* Pretty print template instantiations only. */
if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t)
&& !(flags & TFF_NO_TEMPLATE_BINDINGS)
- && flag_pretty_templates)
+ && flag_pretty_templates
+ // skip the output of template parameters if the function is a member of a
+ // class with diagnose_as attribute:
+ && !(flag_diagnostics_use_aliases
+ && DECL_CLASS_SCOPE_P (t)
+ && lookup_attribute ("diagnose_as",
+ TYPE_ATTRIBUTES (DECL_CONTEXT (t)))))
{
tree tmpl;
@@ -1885,6 +1944,16 @@ dump_exception_spec (cxx_pretty_printer *pp, tree t, int flags)
static void
dump_function_name (cxx_pretty_printer *pp, tree t, int flags)
{
+ if (flag_diagnostics_use_aliases)
+ {
+ tree attr = lookup_attribute ("diagnose_as", DECL_ATTRIBUTES (t));
+ if (attr)
+ {
+ pp_cxx_ws_string (
+ pp, TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
+ return;
+ }
+ }
tree name = DECL_NAME (t);
/* We can get here with a decl that was synthesized by language-
@@ -3133,7 +3202,7 @@ lang_decl_name (tree decl, int v, bool translate)
&& TREE_CODE (decl) == NAMESPACE_DECL)
dump_decl (cxx_pp, decl, TFF_PLAIN_IDENTIFIER | TFF_UNQUALIFIED_NAME);
else
- dump_decl (cxx_pp, DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
+ dump_decl_name_or_diagnose_as (cxx_pp, decl, TFF_PLAIN_IDENTIFIER);
return pp_ggc_formatted_text (cxx_pp);
}
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 4e84e2f9987..80637503310 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -6082,6 +6082,33 @@ handle_namespace_attrs (tree ns, tree attributes)
DECL_ATTRIBUTES (ns) = tree_cons (name, args,
DECL_ATTRIBUTES (ns));
}
+ else if (is_attribute_p ("diagnose_as", name))
+ {
+ if (!args || TREE_CHAIN(args))
+ {
+ error ("the %qE attribute requires exactly one argument", name);
+ continue;
+ }
+ if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
+ {
+ error ("the argument to the %qE attribute must be a string "
+ "literal", name);
+ continue;
+ }
+ tree existing
+ = lookup_attribute ("diagnose_as", DECL_ATTRIBUTES (ns));
+ if (existing
+ && !cp_tree_equal(TREE_VALUE (args),
+ TREE_VALUE (TREE_VALUE (existing))))
+ {
+ error ("the namespace %qE already uses a different diagnose_as "
+ "attribute value", ns);
+ inform (DECL_SOURCE_LOCATION (ns), "previous declaration here");
+ continue;
+ }
+ DECL_ATTRIBUTES (ns) = tree_cons (name, args,
+ DECL_ATTRIBUTES (ns));
+ }
else
{
warning (OPT_Wattributes, "%qD attribute directive ignored",
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a8bfd5fc053..f7b93dc89d7 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -46,6 +46,7 @@ static tree verify_stmt_tree_r (tree *, int *, void *);
static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *);
static tree handle_abi_tag_attribute (tree *, tree, tree, int, bool *);
+static tree handle_diagnose_as_attribute (tree *, tree, tree, int, bool *);
/* If REF is an lvalue, returns the kind of lvalue that REF is.
Otherwise, returns clk_none. */
@@ -4860,6 +4861,8 @@ const struct attribute_spec cxx_attribute_table[] =
handle_init_priority_attribute, NULL },
{ "abi_tag", 1, -1, false, false, false, true,
handle_abi_tag_attribute, NULL },
+ { "diagnose_as", 1, 1, false, false, false, false,
+ handle_diagnose_as_attribute, NULL },
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
};
@@ -5128,6 +5131,120 @@ handle_abi_tag_attribute (tree* node, tree name, tree args,
return NULL_TREE;
}
+static bool
+check_diagnose_as_redeclaration (const_tree decl, const_tree old,
+ const_tree new_)
+{
+ if (!old)
+ return true;
+ if (TREE_CODE (TREE_VALUE (old)) == TREE_LIST)
+ old = TREE_VALUE (old);
+ if (TREE_CODE (TREE_VALUE (new_)) == TREE_LIST)
+ new_ = TREE_VALUE (new_);
+ tree old_value = TREE_VALUE (old);
+ tree new_value = TREE_VALUE (new_);
+ if (cp_tree_equal (old_value, new_value))
+ return true;
+ error ("conflicting declaration of %<diagnose_as%> attribute on %qD would "
+ "overwrite %qE with %qE", decl, old_value, new_value);
+ return false;
+}
+
+static tree
+handle_diagnose_as_attribute (tree* node, tree name, tree args,
+ int flags, bool* no_add_attrs)
+{
+ tree decl = NULL_TREE;
+ if (!args || TREE_CHAIN (args))
+ {
+ error ("the %qE attribute requires exactly one argument", name);
+ goto fail;
+ }
+ if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
+ {
+ error ("the argument to the %qE attribute must be a string literal",
+ name);
+ goto fail;
+ }
+ if (TREE_CODE (*node) == TYPE_DECL)
+ {
+ // Apply the attribute to the type alias itself.
+ decl = *node;
+ tree type = TREE_TYPE (*node);
+ if (CLASS_TYPE_P (type) && CLASSTYPE_IMPLICIT_INSTANTIATION (type))
+ {
+ if (COMPLETE_OR_OPEN_TYPE_P (type))
+ warning (OPT_Wattributes, "%qE attribute cannot be applied to %qT "
+ "after its instantiation", name, type);
+ else
+ {
+ type = strip_typedefs(type, nullptr, 0);
+ // And apply the attribute to the specialization on the RHS.
+ tree attributes = tree_cons (name, args, NULL_TREE);
+ decl_attributes (&type, attributes,
+ ATTR_FLAG_TYPE_IN_PLACE, NULL_TREE);
+ }
+ }
+ }
+ else if (TYPE_P (*node))
+ {
+ if (!OVERLOAD_TYPE_P (*node))
+ {
+ error ("%qE attribute applied to non-class, non-enum type %qT",
+ name, *node);
+ goto fail;
+ }
+ else if (!(flags & (int)ATTR_FLAG_TYPE_IN_PLACE))
+ {
+ error ("%qE attribute applied to %qT after its definition",
+ name, *node);
+ goto fail;
+ }
+ decl = TYPE_NAME (*node);
+ }
+ else
+ {
+ if (!VAR_OR_FUNCTION_DECL_P (*node))
+ {
+ error ("%qE attribute applied to non-function, non-variable %qD",
+ name, *node);
+ goto fail;
+ }
+ else if (DECL_LANGUAGE (*node) == lang_c)
+ {
+ error ("%qE attribute applied to extern \"C\" declaration %qD",
+ name, *node);
+ goto fail;
+ }
+ decl = *node;
+ }
+
+ // Make sure all declarations have the same diagnose_as string.
+ if (DECL_SOURCE_LOCATION (decl) != input_location)
+ {
+ tree attributes = TYPE_P (*node) ? TYPE_ATTRIBUTES (*node)
+ : DECL_ATTRIBUTES (decl);
+ if (!check_diagnose_as_redeclaration (
+ decl, lookup_attribute ("diagnose_as", attributes), args))
+ goto fail;
+ }
+ else if (CLASS_TYPE_P (*node) && CLASSTYPE_IMPLICIT_INSTANTIATION (*node))
+ {
+ // The above branch (different source location) is taken for declarations
+ // of type aliases that modify an implicit template specialization on the
+ // RHS. This branch is taken when the template is instantiated via
+ // instantiate_class_template_1, in which case the attribute either
+ // already has the value from the general template or from a type alias.
+ goto fail;
+ }
+
+ return NULL_TREE;
+
+ fail:
+ *no_add_attrs = true;
+ return NULL_TREE;
+}
+
/* Return a new PTRMEM_CST of the indicated TYPE. The MEMBER is the
thing pointed to by the constant. */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index c8caf36f293..7976e3a72d4 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2865,6 +2865,43 @@ types (@pxref{Variable Attributes}, @pxref{Type Attributes}.)
The message attached to the attribute is affected by the setting of
the @option{-fmessage-length} option.
+@item diagnose_as ("@var{string}")
+@cindex @code{diagnose_as} function attribute
+The @code{diagnose_as} attribute modifies how the entity the attribute
+appertains to is diagnosed in compiler messages and __FUNCTION__ /
+__PRETTY_FUNCTION__ macros. If the attribute is applied to a @code{namespace},
+the specified string replaces the complete enclosing scope. The effect of the
+@code{diagnose_as} attribute can be disabled with the
+@option{-fno-diagnostics-use-aliases} command line option.
+
+@smallexample
+namespace Foo @{
+ namespace Bar @{
+ inline namespace v1 [[gnu::diagnose_as("Foobar")]] @{
+ int f() @{
+ // __PRETTY_FUNCTION__ == "void Foobar::f()"
+ @}
+ @}
+ @}
+@}
+// In function 'int Foobar::f()':
+// warning: no return statement in function returning non-void [-Wreturn-type]
+@end smallexample
+
+The @code{diagnose_as} attribute can be used with namespaces, functions,
+variables, alias declarations (but not alias templates), and user-defined types
+(classes, unions, and enums). If the alias declaration aliases an implicit class
+template specialization, the attribute is additionally applied to the class
+template specialization.
+
+@smallexample
+template <class T> struct basic_string @{@};
+using string [[gnu::diagnose_as("string")]] = basic_string<char>;
+int f(basic_string<char>) @{@}
+// In function 'int f(string)':
+// warning: no return statement in function returning non-void [-Wreturn-type]
+@end smallexample
+
@item error ("@var{message}")
@itemx warning ("@var{message}")
@cindex @code{error} function attribute
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index f5a9dc33819..84c19344c89 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -311,7 +311,8 @@ Objective-C and Objective-C++ Dialects}.
-fdiagnostics-show-path-depths @gol
-fno-show-column @gol
-fdiagnostics-column-unit=@r{[}display@r{|}byte@r{]} @gol
--fdiagnostics-column-origin=@var{origin}}
+-fdiagnostics-column-origin=@var{origin} @gol
+-fno-diagnostics-aliases}
@item Warning Options
@xref{Warning Options,,Options to Request or Suppress Warnings}.
@@ -5077,6 +5078,12 @@ first column. The default value of 1 corresponds to traditional GCC
behavior and to the GNU style guide. Some utilities may perform better with an
origin of 0; any non-negative value may be specified.
+@item -fno-diagnostics-use-aliases
+@opindex fno-diagnostics-use-aliases
+@opindex fdiagnostics-use-aliases
+Do not replace identifiers or scope names with the aliases defined with the
+@code{[[gnu::diagnose_as("alias")]]} attribute.
+
@item -fdiagnostics-format=@var{FORMAT}
@opindex fdiagnostics-format
Select a different format for printing diagnostics.
next prev parent reply other threads:[~2021-05-04 11:13 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-23 15:16 [RFC] " Matthias Kretz
2021-04-27 9:46 ` Jonathan Wakely
2021-05-04 11:13 ` Matthias Kretz [this message]
2021-05-04 13:34 ` [PATCH] " David Malcolm
2021-05-04 14:23 ` Matthias Kretz
2021-05-04 14:32 ` Matthias Kretz
2021-05-04 19:00 ` David Malcolm
2021-05-04 19:22 ` Matthias Kretz
2021-05-14 16:05 ` Martin Sebor
2021-05-26 21:33 ` Matthias Kretz
2021-05-27 17:39 ` Jason Merrill
2021-05-27 18:54 ` Matthias Kretz
2021-05-27 21:15 ` Jason Merrill
2021-05-27 22:07 ` Matthias Kretz
2021-05-28 3:05 ` Jason Merrill
2021-05-28 7:42 ` Matthias Kretz
2021-06-01 19:12 ` Jason Merrill
2021-06-01 21:01 ` Matthias Kretz
2021-06-11 10:01 ` Matthias Kretz
2021-06-15 15:51 ` Jason Merrill
2021-06-15 20:56 ` Matthias Kretz
2021-06-16 0:48 ` Jason Merrill
2021-06-22 7:30 ` Matthias Kretz
2021-06-22 19:52 ` Jason Merrill
2021-06-22 20:01 ` Matthias Kretz
2021-06-22 20:12 ` Jason Merrill
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=91863212.B8guWdUDZo@excalibur \
--to=m.kretz@gsi.de \
--cc=gcc-patches@gcc.gnu.org \
--cc=libstdc++@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).