public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
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.

  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).