diff mbox series

[committed] v5: C/C++: fix quoting of "aka" typedef information (PR 62170)

Message ID 1511383566-32317-1-git-send-email-dmalcolm@redhat.com
State New
Headers show
Series [committed] v5: C/C++: fix quoting of "aka" typedef information (PR 62170) | expand

Commit Message

David Malcolm Nov. 22, 2017, 8:46 p.m. UTC
Looks like this got dropped on the floor back in June.

Jason approved an earlier version of this, so I've gone ahead and
updated it, and committed it to trunk.

Here's the version I've committed to trunk (as r255076), having verified
bootstrap&regrtest (on x86_64-pc-linux-gnu).

Changed in v5:
  * testsuite fixups

Changed in v4:
  * update for removal of " {enum}" in r250231

Changed in v3:
  * use correct size for obstack_blank_fast

Changed in v2:
  * cp/error.c: type_to_string: use obstack_blank_fast rather
    than directly manipulating ob->next_free

Blurb from v1:

PR 62170 describes a problem with how the quoting in pp_format
interacts with the "aka" information for typedefs in %qT for
the C family of frontends, and also now for %qH and %qI in the
C++ frontend: we print:

  'Py_ssize_t* {aka int*}'
   ^^^^^^^^^^^^^^^^^^^^^^ colorized as "quote"

i.e.
  '[START_COLOR]Py_ssize_t* {aka int*}[END_COLOR]'

when we should print:

  'Py_ssize_t*' {aka 'int*'}
   ^^^^^^^^^^^        ^^^^ colorized as "quote"

i.e.
  '[START_COLOR]Py_ssize_t*[END_COLOR]' {aka '[START_COLOR]int*[END_COLOR]'}

where the opening and closing quote characters and colorization are
added by the 'q' handling within pp_format.

This patch fixes the quoting by updating the %T handling in C and C++
and the %H/%I handling in C++ to insert the quoting appropriately.
It converts the "quote" param of the pp_format_decoder callback from
bool to bool *, allowing for the %T and %H/%I handlers to write
false back to it, to avoid printing the closing quote for the cases
like the above where the trailing closing quote isn't needed.

It introduces pp_begin_quote/pp_end_quote to simplify this.  These
take a "bool show_color", rather than using "pp_show_color (pp)"
since cxx_pp's pp_show_color isn't currently initialized (since
cxx_initialize_diagnostics happens before diagnostic_color_init).

gcc/c/ChangeLog:
	PR c++/62170
	* c-objc-common.c (c_tree_printer): Convert penultimate param from
	bool to bool *.  Within '%T' handling, if showing an "aka", use
	"quoted" param to add appropriate quoting.

gcc/cp/ChangeLog:
	PR c++/62170
	* error.c (type_to_string): Add leading comment.  Add params
	"postprocessed", "quote", and "show_color", using them to fix
	quoting of the "aka" for types involving typedefs.
	(arg_to_string): Update for new params to type_to_string.
	(cxx_format_postprocessor::handle): Likewise.
	(cp_printer): Convert penultimate param from bool to bool *.
	Update call to type_to_string and calls to
	defer_phase_2_of_type_diff.

gcc/fortran/ChangeLog:
	PR c++/62170
	* error.c (gfc_notify_std): Convert "quoted" param from bool to
	bool *.

gcc/ChangeLog:
	PR c++/62170
	* pretty-print.c (pp_format): Move quoting implementation to
	pp_begin_quote and pp_end_quote.  Update pp_format_decoder call
	to pass address of "quote" local.
	(pp_begin_quote): New function.
	(pp_end_quote): New function.
	* pretty-print.h (printer_fn): Convert penultimate param from bool
	to bool *.
	(pp_begin_quote): New decl.
	(pp_end_quote): New decl.
	* tree-diagnostic.c (default_tree_printer): Convert penultimate
	param from bool to bool *.
	* tree-diagnostic.h (default_tree_printer): Likewise.

gcc/testsuite/ChangeLog:
	PR c++/62170
	* g++.dg/diagnostic/aka1.C: Update expected error messages to
	reflect fixes to quoting.
	* g++.dg/diagnostic/aka2.C: New test case.
	* g++.dg/parse/error55.C: Update expected error messages to
	reflect fixes to quoting.
	* gcc.dg/diag-aka-1.c: Likewise.
	* gcc.dg/diag-aka-2.c: New test case.
	* gcc.dg/pr13804-1.c: Update expected error messages to reflect
	fixes to quoting.
	* gcc.dg/pr56980.c: Likewise.
	* gcc.dg/pr65050.c: Likewise.
	* gcc.dg/redecl-14.c: Likewise.
	* gcc.dg/utf16-4.c Likewise.
	* gcc.target/i386/sse-vect-types.c (__m128d): Likewise.
	* obj-c++.dg/invalid-type-1.mm: Likewise.
	* objc.dg/proto-lossage-4.m: Likewise.
---
 gcc/c/c-objc-common.c                          | 12 +++-
 gcc/cp/error.c                                 | 99 +++++++++++++++++++++-----
 gcc/fortran/error.c                            |  2 +-
 gcc/pretty-print.c                             | 37 +++++++---
 gcc/pretty-print.h                             |  5 +-
 gcc/testsuite/g++.dg/diagnostic/aka1.C         |  2 +-
 gcc/testsuite/g++.dg/diagnostic/aka2.C         | 32 +++++++++
 gcc/testsuite/g++.dg/parse/error55.C           |  2 +-
 gcc/testsuite/gcc.dg/diag-aka-1.c              |  4 +-
 gcc/testsuite/gcc.dg/diag-aka-2.c              | 12 ++++
 gcc/testsuite/gcc.dg/pr13804-1.c               |  4 +-
 gcc/testsuite/gcc.dg/pr56980.c                 | 12 ++--
 gcc/testsuite/gcc.dg/pr65050.c                 |  8 +--
 gcc/testsuite/gcc.dg/redecl-14.c               |  2 +-
 gcc/testsuite/gcc.dg/utf16-4.c                 |  2 +-
 gcc/testsuite/gcc.target/i386/sse-vect-types.c |  2 +-
 gcc/testsuite/obj-c++.dg/invalid-type-1.mm     |  4 +-
 gcc/testsuite/objc.dg/proto-lossage-4.m        |  6 +-
 gcc/tree-diagnostic.c                          |  2 +-
 gcc/tree-diagnostic.h                          |  2 +-
 20 files changed, 194 insertions(+), 57 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/aka2.C
 create mode 100644 gcc/testsuite/gcc.dg/diag-aka-2.c
diff mbox series

Patch

diff --git a/gcc/c/c-objc-common.c b/gcc/c/c-objc-common.c
index 8f4d3eb..6d923eb 100644
--- a/gcc/c/c-objc-common.c
+++ b/gcc/c/c-objc-common.c
@@ -29,7 +29,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "c-objc-common.h"
 
 static bool c_tree_printer (pretty_printer *, text_info *, const char *,
-			    int, bool, bool, bool, bool, const char **);
+			    int, bool, bool, bool, bool *, const char **);
 
 bool
 c_missing_noreturn_ok_p (tree decl)
@@ -79,7 +79,7 @@  c_objc_common_init (void)
 static bool
 c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
 		int precision, bool wide, bool set_locus, bool hash,
-		bool, const char **)
+		bool *quoted, const char **)
 {
   tree t = NULL_TREE;
   tree name;
@@ -166,12 +166,20 @@  c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
 	      return true;
 
 	    /* They're not, print the stripped version now.  */
+	    if (*quoted)
+	      pp_end_quote (pp, pp_show_color (pp));
 	    pp_c_whitespace (cpp);
 	    pp_left_brace (cpp);
 	    pp_c_ws_string (cpp, _("aka"));
 	    pp_c_whitespace (cpp);
+	    if (*quoted)
+	      pp_begin_quote (pp, pp_show_color (pp));
 	    cpp->type_id (TYPE_CANONICAL (t));
+	    if (*quoted)
+	      pp_end_quote (pp, pp_show_color (pp));
 	    pp_right_brace (cpp);
+	    /* No further closing quotes are needed.  */
+	    *quoted = false;
 	  }
 	return true;
       }
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 6d1f3da..a47822a 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -57,7 +57,7 @@  static const char *expr_to_string (tree);
 static const char *fndecl_to_string (tree, int);
 static const char *op_to_string	(bool, enum tree_code);
 static const char *parm_to_string (int);
-static const char *type_to_string (tree, int);
+static const char *type_to_string (tree, int, bool, bool *, bool);
 
 static void dump_alias_template_specialization (cxx_pretty_printer *, tree, int);
 static void dump_type (cxx_pretty_printer *, tree, int);
@@ -99,7 +99,7 @@  static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *);
 static void cp_print_error_function (diagnostic_context *, diagnostic_info *);
 
 static bool cp_printer (pretty_printer *, text_info *, const char *,
-			int, bool, bool, bool, bool, const char **);
+			int, bool, bool, bool, bool *, const char **);
 
 /* Struct for handling %H or %I, which require delaying printing the
    type until a postprocessing stage.  */
@@ -3144,8 +3144,28 @@  op_to_string (bool assop, enum tree_code p)
   return id ? IDENTIFIER_POINTER (id) : M_("<unknown>");
 }
 
+/* Return a GC-allocated representation of type TYP, with verbosity VERBOSE.
+
+   If QUOTE is non-NULL and if *QUOTE is true, then quotes are added to the
+   string in appropriate places, and *QUOTE is written to with false
+   to suppress pp_format's trailing close quote so that e.g.
+     foo_typedef {aka underlying_foo} {enum}
+   can be printed by "%qT" as:
+     `foo_typedef' {aka `underlying_foo'} {enum}
+   rather than:
+     `foo_typedef {aka underlying_foo} {enum}'
+   When adding such quotes, if POSTPROCESSED is true (for handling %H and %I)
+   then a leading open quote will be added, whereas if POSTPROCESSED is false
+   (for handling %T) then any leading quote has already been added by
+   pp_format, or is not needed due to QUOTE being NULL (for template arguments
+   within %H and %I).
+
+   SHOW_COLOR is used to determine the colorization of any quotes that
+   are added.  */
+
 static const char *
-type_to_string (tree typ, int verbose)
+type_to_string (tree typ, int verbose, bool postprocessed, bool *quote,
+		bool show_color)
 {
   int flags = 0;
   if (verbose)
@@ -3153,7 +3173,19 @@  type_to_string (tree typ, int verbose)
   flags |= TFF_TEMPLATE_HEADER;
 
   reinit_cxx_pp ();
+
+  if (postprocessed && quote && *quote)
+    pp_begin_quote (cxx_pp, show_color);
+
+  struct obstack *ob = pp_buffer (cxx_pp)->obstack;
+  int type_start, type_len;
+  type_start = obstack_object_size (ob);
+
   dump_type (cxx_pp, typ, flags);
+
+  /* Remember the end of the initial dump.  */
+  type_len = obstack_object_size (ob) - type_start;
+
   /* If we're printing a type that involves typedefs, also print the
      stripped version.  But sometimes the stripped version looks
      exactly the same, so we don't want it after all.  To avoid printing
@@ -3162,21 +3194,44 @@  type_to_string (tree typ, int verbose)
       && !uses_template_parms (typ))
     {
       int aka_start, aka_len; char *p;
-      struct obstack *ob = pp_buffer (cxx_pp)->obstack;
-      /* Remember the end of the initial dump.  */
-      int len = obstack_object_size (ob);
       tree aka = strip_typedefs (typ);
+      if (quote && *quote)
+	pp_end_quote (cxx_pp, show_color);
       pp_string (cxx_pp, " {aka");
       pp_cxx_whitespace (cxx_pp);
+      if (quote && *quote)
+	pp_begin_quote (cxx_pp, show_color);
       /* And remember the start of the aka dump.  */
       aka_start = obstack_object_size (ob);
       dump_type (cxx_pp, aka, flags);
       aka_len = obstack_object_size (ob) - aka_start;
+      if (quote && *quote)
+	pp_end_quote (cxx_pp, show_color);
       pp_right_brace (cxx_pp);
       p = (char*)obstack_base (ob);
-      /* If they are identical, cut off the aka with a NUL.  */
-      if (len == aka_len && memcmp (p, p+aka_start, len) == 0)
-	p[len] = '\0';
+      /* If they are identical, cut off the aka by unwinding the obstack.  */
+      if (type_len == aka_len
+	  && memcmp (p + type_start, p+aka_start, type_len) == 0)
+	{
+	  /* We can't add a '\0' here, since we may be adding a closing quote
+	     below, and it would be hidden by the '\0'.
+	     Instead, manually unwind the current object within the obstack
+	     so that the insertion point is at the end of the type, before
+	     the "' {aka".  */
+	  int delta = type_start + type_len - obstack_object_size (ob);
+	  gcc_assert (delta <= 0);
+	  obstack_blank_fast (ob, delta);
+	}
+      else
+	if (quote)
+	  /* No further closing quotes are needed.  */
+	  *quote = false;
+    }
+
+  if (quote && *quote)
+    {
+      pp_end_quote (cxx_pp, show_color);
+      *quote = false;
     }
   return pp_ggc_formatted_text (cxx_pp);
 }
@@ -3634,7 +3689,7 @@  static const char *
 arg_to_string (tree arg, bool verbose)
 {
   if (TYPE_P (arg))
-    return type_to_string (arg, verbose);
+    return type_to_string (arg, verbose, true, NULL, false);
   else
     return expr_to_string (arg);
 }
@@ -3924,10 +3979,13 @@  cxx_format_postprocessor::handle (pretty_printer *pp)
 	}
       else
 	{
-	  /* If the types were not comparable, they are printed normally,
-	     and no difference tree is printed.  */
-	  type_a_text = type_to_string (type_a.m_tree, type_a.m_verbose);
-	  type_b_text = type_to_string (type_b.m_tree, type_b.m_verbose);
+	  /* If the types were not comparable (or if only one of %H/%I was
+	     provided), they are printed normally, and no difference tree
+	     is printed.  */
+	  type_a_text = type_to_string (type_a.m_tree, type_a.m_verbose,
+					true, &type_a.m_quote, show_color);
+	  type_b_text = type_to_string (type_b.m_tree, type_b.m_verbose,
+					true, &type_b.m_quote, show_color);
 	}
 
       if (type_a.m_quote)
@@ -4000,7 +4058,7 @@  defer_phase_2_of_type_diff (deferred_printed_type *deferred,
 static bool
 cp_printer (pretty_printer *pp, text_info *text, const char *spec,
 	    int precision, bool wide, bool set_locus, bool verbose,
-	    bool quoted, const char **buffer_ptr)
+	    bool *quoted, const char **buffer_ptr)
 {
   gcc_assert (pp->m_format_postprocessor);
   cxx_format_postprocessor *postprocessor
@@ -4043,7 +4101,12 @@  cp_printer (pretty_printer *pp, text_info *text, const char *spec,
     case 'P': result = parm_to_string (next_int);		break;
     case 'Q': result = op_to_string (true, next_tcode);		break;
     case 'S': result = subst_to_string (next_tree);		break;
-    case 'T': result = type_to_string (next_tree, verbose);	break;
+    case 'T':
+      {
+	result = type_to_string (next_tree, verbose, false, quoted,
+				 pp_show_color (pp));
+      }
+      break;
     case 'V': result = cv_to_string (next_tree, verbose);	break;
     case 'X': result = eh_spec_to_string (next_tree, verbose);  break;
 
@@ -4059,14 +4122,14 @@  cp_printer (pretty_printer *pp, text_info *text, const char *spec,
     case 'H':
       {
 	defer_phase_2_of_type_diff (&postprocessor->m_type_a, next_tree,
-				    buffer_ptr, verbose, quoted);
+				    buffer_ptr, verbose, *quoted);
 	return true;
       }
 
     case 'I':
       {
 	defer_phase_2_of_type_diff (&postprocessor->m_type_b, next_tree,
-				    buffer_ptr, verbose, quoted);
+				    buffer_ptr, verbose, *quoted);
 	return true;
       }
 
diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
index 3ad1cf9..2cece49 100644
--- a/gcc/fortran/error.c
+++ b/gcc/fortran/error.c
@@ -918,7 +918,7 @@  gfc_notify_std (int std, const char *gmsgid, ...)
 static bool
 gfc_format_decoder (pretty_printer *pp, text_info *text, const char *spec,
 		    int precision, bool wide, bool set_locus, bool hash,
-		    bool quoted, const char **buffer_ptr)
+		    bool *quoted, const char **buffer_ptr)
 {
   switch (*spec)
     {
diff --git a/gcc/pretty-print.c b/gcc/pretty-print.c
index e66d898..1fbd2fe 100644
--- a/gcc/pretty-print.c
+++ b/gcc/pretty-print.c
@@ -1209,10 +1209,7 @@  pp_format (pretty_printer *pp, text_info *text)
       gcc_assert (!wide || precision == 0);
 
       if (quote)
-	{
-	  pp_string (pp, open_quote);
-	  pp_string (pp, colorize_start (pp_show_color (pp), "quote"));
-	}
+	pp_begin_quote (pp, pp_show_color (pp));
 
       switch (*p)
 	{
@@ -1345,19 +1342,21 @@  pp_format (pretty_printer *pp, text_info *text)
 	  {
 	    bool ok;
 
+	    /* Call the format decoder.
+	       Pass the address of "quote" so that format decoders can
+	       potentially disable printing of the closing quote
+	       (e.g. when printing "'TYPEDEF' aka 'TYPE'" in the C family
+	       of frontends).  */
 	    gcc_assert (pp_format_decoder (pp));
 	    ok = pp_format_decoder (pp) (pp, text, p,
-					 precision, wide, plus, hash, quote,
+					 precision, wide, plus, hash, &quote,
 					 formatters[argno]);
 	    gcc_assert (ok);
 	  }
 	}
 
       if (quote)
-	{
-	  pp_string (pp, colorize_stop (pp_show_color (pp)));
-	  pp_string (pp, close_quote);
-	}
+	pp_end_quote (pp, pp_show_color (pp));
 
       obstack_1grow (&buffer->chunk_obstack, '\0');
       *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);
@@ -1731,6 +1730,26 @@  pp_separate_with (pretty_printer *pp, char c)
   pp_space (pp);
 }
 
+/* Add a localized open quote, and if SHOW_COLOR is true, begin colorizing
+   using the "quote" color.  */
+
+void
+pp_begin_quote (pretty_printer *pp, bool show_color)
+{
+  pp_string (pp, open_quote);
+  pp_string (pp, colorize_start (show_color, "quote"));
+}
+
+/* If SHOW_COLOR is true, stop colorizing.
+   Add a localized close quote.  */
+
+void
+pp_end_quote (pretty_printer *pp, bool show_color)
+{
+  pp_string (pp, colorize_stop (show_color));
+  pp_string (pp, close_quote);
+}
+
 
 /* The string starting at P has LEN (at least 1) bytes left; if they
    start with a valid UTF-8 sequence, return the length of that
diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h
index 98296b1..9f6e2bb 100644
--- a/gcc/pretty-print.h
+++ b/gcc/pretty-print.h
@@ -179,7 +179,7 @@  struct pp_wrapping_mode_t
    A client-supplied formatter returns true if everything goes well,
    otherwise it returns false.  */
 typedef bool (*printer_fn) (pretty_printer *, text_info *, const char *,
-			    int, bool, bool, bool, bool, const char **);
+			    int, bool, bool, bool, bool *, const char **);
 
 /* Client supplied function used to decode formats.  */
 #define pp_format_decoder(PP) (PP)->format_decoder
@@ -386,6 +386,9 @@  extern void pp_write_text_to_stream (pretty_printer *);
 extern void pp_write_text_as_dot_label_to_stream (pretty_printer *, bool);
 extern void pp_maybe_space (pretty_printer *);
 
+extern void pp_begin_quote (pretty_printer *, bool);
+extern void pp_end_quote (pretty_printer *, bool);
+
 /* Switch into verbatim mode and return the old mode.  */
 static inline pp_wrapping_mode_t
 pp_set_verbatim_wrapping_ (pretty_printer *pp)
diff --git a/gcc/testsuite/g++.dg/diagnostic/aka1.C b/gcc/testsuite/g++.dg/diagnostic/aka1.C
index 37f8df9..cb314fb 100644
--- a/gcc/testsuite/g++.dg/diagnostic/aka1.C
+++ b/gcc/testsuite/g++.dg/diagnostic/aka1.C
@@ -12,4 +12,4 @@  void A::f() {
 typedef A B;
 
 // We do want an aka for a real typedef.
-B b = 0;			// { dg-error "B .aka A." }
+B b = 0;			// { dg-error "'B' {aka 'A'}" }
diff --git a/gcc/testsuite/g++.dg/diagnostic/aka2.C b/gcc/testsuite/g++.dg/diagnostic/aka2.C
new file mode 100644
index 0000000..a43f9e3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/aka2.C
@@ -0,0 +1,32 @@ 
+/* Verify that the "aka" descriptions for typedefs are correctly
+   quoted (PR 62170).  */
+
+/* Exercise %H and %I.  */
+
+typedef struct s1 t1;
+typedef struct s2 {int i;} t2;
+
+int foo(t1 *);
+
+void test_1 () {
+  t2 pos;
+
+  foo (&pos); // { dg-error "cannot convert 't2\\*' {aka 's2\\*'} to 't1\\*' {aka 's1\\*'} for argument '1' to 'int foo\\(t1\\*\\)'" }
+}
+
+/* Exercise %T.  */
+
+typedef struct s3
+{  
+  void m3 ();
+} t3;
+
+void test_2 (const s3 *ptr)
+{
+  ptr->m3 (); // { dg-error "passing 'const s3' as 'this' argument discards qualifiers" }
+}
+
+void test_3 (const t3 *ptr)
+{
+  ptr->m3 (); // { dg-error "passing 'const t3' {aka 'const s3'} as 'this' argument discards qualifiers" }
+}
diff --git a/gcc/testsuite/g++.dg/parse/error55.C b/gcc/testsuite/g++.dg/parse/error55.C
index 24cca50..70af85d 100644
--- a/gcc/testsuite/g++.dg/parse/error55.C
+++ b/gcc/testsuite/g++.dg/parse/error55.C
@@ -3,5 +3,5 @@ 
 class A { };
 typedef A B;
 void foo (B &a) {
-  a.x();  // { dg-error "'B {aka class A}' has no member named 'x'" }
+  a.x();  // { dg-error "'B' {aka 'class A'} has no member named 'x'" }
 }
diff --git a/gcc/testsuite/gcc.dg/diag-aka-1.c b/gcc/testsuite/gcc.dg/diag-aka-1.c
index 87bc757..fde4ca7 100644
--- a/gcc/testsuite/gcc.dg/diag-aka-1.c
+++ b/gcc/testsuite/gcc.dg/diag-aka-1.c
@@ -10,7 +10,7 @@  typedef int IA[];
 typedef IA *IAP;
 extern IAP arr[];
 
-void fn1 (B *); /* { dg-message "expected .B \\* {aka struct A \\*}. but argument is of type .struct B \\*." } */
+void fn1 (B *); /* { dg-message "expected 'B \\*' {aka 'struct A \\*'} but argument is of type 'struct B \\*'" } */
 void fn2 (TFC *);
 
 void 
@@ -24,6 +24,6 @@  bar (B *b, int *i)
 int
 foo (void *a)
 {
-  T *t = a; /* { dg-warning "request for implicit conversion from .void \\*. to .T \\* {aka struct T \\*}. not" } */
+  T *t = a; /* { dg-warning "request for implicit conversion from 'void \\*' to 'T \\*' {aka 'struct T \\*'} not" } */
   return t->i;
 }
diff --git a/gcc/testsuite/gcc.dg/diag-aka-2.c b/gcc/testsuite/gcc.dg/diag-aka-2.c
new file mode 100644
index 0000000..a4b2242
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/diag-aka-2.c
@@ -0,0 +1,12 @@ 
+/* Verify that the "aka" descriptions for typedefs are correctly
+   quoted (PR 62170).  */
+
+typedef struct s1 t1;
+
+int foo(t1 *); /* { dg-message "expected 't1 \\*' {aka 'struct s1 \\*'} but argument is of type 't2 \\*' {aka 'struct s2 \\*'}" } */
+
+int bar() {
+  typedef struct s2 {int i;} t2;
+  t2 pos;
+  return foo(&pos); /* { dg-error "incompatible pointer type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr13804-1.c b/gcc/testsuite/gcc.dg/pr13804-1.c
index 65b238a..5fc17f4 100644
--- a/gcc/testsuite/gcc.dg/pr13804-1.c
+++ b/gcc/testsuite/gcc.dg/pr13804-1.c
@@ -20,9 +20,9 @@  void
 f (void)
 {
   x0.c; /* { dg-error "'struct s0' has no member named 'c'" } */
-  x1.c; /* { dg-error "'S0 {aka struct s0}' has no member named 'c'" } */
+  x1.c; /* { dg-error "'S0' {aka 'struct s0'} has no member named 'c'" } */
   x2.c; /* { dg-error "'union u0' has no member named 'c'" } */
-  x3.c; /* { dg-error "'U0 {aka union u0}' has no member named 'c'" } */
+  x3.c; /* { dg-error "'U0' {aka 'union u0'} has no member named 'c'" } */
   x4->c; /* { dg-error "'struct s0' has no member named 'c'" } */
   x5->c; /* { dg-error "'union u0' has no member named 'c'" } */
 }
diff --git a/gcc/testsuite/gcc.dg/pr56980.c b/gcc/testsuite/gcc.dg/pr56980.c
index 27405ef..5303c61 100644
--- a/gcc/testsuite/gcc.dg/pr56980.c
+++ b/gcc/testsuite/gcc.dg/pr56980.c
@@ -5,12 +5,12 @@  typedef struct A { int i; } B;
 typedef union U { int i; } V;
 typedef enum E { G } F;
 
-void foo_s (struct A); /* { dg-message "expected .struct A. but argument is of type .B \\* {aka struct A \\*}." } */
-void foo_u (union U); /* { dg-message "expected .union U. but argument is of type .V \\* {aka union U \\*}." } */
-void foo_e (enum E); /* { dg-message "expected .enum E. but argument is of type .F \\* {aka enum E \\*}." } */
-void foo_sp (B *); /* { dg-message "expected .B \\* {aka struct A \\*}. but argument is of type .struct B \\*." } */
-void foo_up (V *); /* { dg-message "expected .V \\* {aka union U \\*}. but argument is of type .union V \\*." } */
-void foo_ep (F *); /* { dg-message "expected .F \\* {aka enum E \\*}. but argument is of type .enum F \\*." } */
+void foo_s (struct A); /* { dg-message "expected .struct A. but argument is of type 'B \\*' {aka 'struct A \\*'}" } */
+void foo_u (union U); /* { dg-message "expected .union U. but argument is of type 'V \\*' {aka 'union U \\*'}" } */
+void foo_e (enum E); /* { dg-message "expected .enum E. but argument is of type 'F \\*' {aka 'enum E \\*'}" } */
+void foo_sp (B *); /* { dg-message "expected 'B \\*' {aka 'struct A \\*'} but argument is of type .struct B \\*." } */
+void foo_up (V *); /* { dg-message "expected 'V \\*' {aka 'union U \\*'} but argument is of type .union V \\*." } */
+void foo_ep (F *); /* { dg-message "expected 'F \\*' {aka 'enum E \\*'} but argument is of type .enum F \\*." } */
 
 void 
 bar (B *b, V *v, F *f)
diff --git a/gcc/testsuite/gcc.dg/pr65050.c b/gcc/testsuite/gcc.dg/pr65050.c
index 0822a99..e29559d 100644
--- a/gcc/testsuite/gcc.dg/pr65050.c
+++ b/gcc/testsuite/gcc.dg/pr65050.c
@@ -2,9 +2,9 @@ 
 /* { dg-do compile } */
 
 typedef int A[];
-struct S { int i; A a[5]; } s; /* { dg-error "array type has incomplete element type .A {aka int\\\[\\\]}." } */
+struct S { int i; A a[5]; } s; /* { dg-error "array type has incomplete element type 'A' {aka 'int\\\[\\\]'}" } */
 extern void foo (int p[2][]); /* { dg-error "array type has incomplete element type .int\\\[\\\]." } */
-extern void bar (A p[2]); /* { dg-error "array type has incomplete element type .A {aka int\\\[\\\]}." } */
+extern void bar (A p[2]); /* { dg-error "array type has incomplete element type 'A' {aka 'int\\\[\\\]'}" } */
 
 void
 foo (int p[2][]) /* { dg-error "array type has incomplete element type .int\\\[\\\]." } */
@@ -12,7 +12,7 @@  foo (int p[2][]) /* { dg-error "array type has incomplete element type .int\\\[\
 }
 
 void
-bar (A p[2]) /* { dg-error "array type has incomplete element type .A {aka int\\\[\\\]}." } */
+bar (A p[2]) /* { dg-error "array type has incomplete element type 'A' {aka 'int\\\[\\\]'}" } */
 {
 }
 
@@ -20,4 +20,4 @@  struct T;
 struct T t[5]; /* { dg-error "array type has incomplete element type .struct T." } */
 struct U u[] = { { "abc" } }; /* { dg-error "array type has incomplete element type .struct U." } */
 typedef struct T TT;
-TT tt[5]; /* { dg-error "array type has incomplete element type .TT {aka struct T}." } */
+TT tt[5]; /* { dg-error "array type has incomplete element type 'TT' {aka 'struct T'}" } */
diff --git a/gcc/testsuite/gcc.dg/redecl-14.c b/gcc/testsuite/gcc.dg/redecl-14.c
index 97003c1..1bf1d96 100644
--- a/gcc/testsuite/gcc.dg/redecl-14.c
+++ b/gcc/testsuite/gcc.dg/redecl-14.c
@@ -18,5 +18,5 @@  f (void)
   }
   extern IAP a[];
   extern IAP a[5];
-  sizeof (*a[0]); /* { dg-error "invalid application of 'sizeof' to incomplete type 'IA {aka int\\\[\\\]}'" } */
+  sizeof (*a[0]); /* { dg-error "invalid application of 'sizeof' to incomplete type 'IA' {aka 'int\\\[\\\]'}" } */
 }
diff --git a/gcc/testsuite/gcc.dg/utf16-4.c b/gcc/testsuite/gcc.dg/utf16-4.c
index e2f115e..4b20387 100644
--- a/gcc/testsuite/gcc.dg/utf16-4.c
+++ b/gcc/testsuite/gcc.dg/utf16-4.c
@@ -12,7 +12,7 @@  char16_t	c2 = u'\U00064321';	/* { dg-warning "constant too long" } */
 char16_t	c3 = 'a';
 char16_t	c4 = U'a';
 char16_t	c5 = U'\u2029';
-char16_t	c6 = U'\U00064321';	/* { dg-warning "conversion from .(long )?unsigned int. to .char16_t {aka short unsigned int}. changes value from .410401. to .17185." } */
+char16_t	c6 = U'\U00064321';	/* { dg-warning "conversion from .(long )?unsigned int. to 'char16_t' {aka 'short unsigned int'} changes value from .410401. to .17185." } */
 char16_t	c7 = L'a';
 char16_t	c8 = L'\u2029';
 char16_t 	c9 = L'\U00064321';	/* { dg-warning "conversion" "" { target { 4byte_wchar_t } } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse-vect-types.c b/gcc/testsuite/gcc.target/i386/sse-vect-types.c
index 9cb6f3e..ac4ece4 100644
--- a/gcc/testsuite/gcc.target/i386/sse-vect-types.c
+++ b/gcc/testsuite/gcc.target/i386/sse-vect-types.c
@@ -10,4 +10,4 @@  __m128d foo1(__m128d z, __m128d  a, int N) {
   }
   return a;
 }
-/* { dg-message "note: expected '\[^'\n\]*' but argument is of type '\[^'\n\]*'" "note: expected" { target *-*-* } 0 } */
+/* { dg-message "note: expected '.*'.* but argument is of type '.*'" "note: expected" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/obj-c++.dg/invalid-type-1.mm b/gcc/testsuite/obj-c++.dg/invalid-type-1.mm
index cb2138f..59c8666 100644
--- a/gcc/testsuite/obj-c++.dg/invalid-type-1.mm
+++ b/gcc/testsuite/obj-c++.dg/invalid-type-1.mm
@@ -18,8 +18,8 @@  id <MyProtocol> object; /* This is fine.  */
 
 AClass <MyProtocol> *object1; /* This is fine.  */
 
-Integer <MyProtocol> *object2; /* { dg-error ".Integer {aka int}. is not a template" } */
+Integer <MyProtocol> *object2; /* { dg-error "'Integer' {aka 'int'} is not a template" } */
 /* { dg-error ".MyProtocol. was not declared in this scope" "" { target *-*-* } .-1 } */
 
-Integer <NonExistingProtocol> *object3; /* { dg-error ".Integer {aka int}. is not a template" } */
+Integer <NonExistingProtocol> *object3; /* { dg-error "'Integer' {aka 'int'} is not a template" } */
 /* { dg-error ".NonExistingProtocol. was not declared in this scope" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/objc.dg/proto-lossage-4.m b/gcc/testsuite/objc.dg/proto-lossage-4.m
index c9c80b7..182e92d 100644
--- a/gcc/testsuite/objc.dg/proto-lossage-4.m
+++ b/gcc/testsuite/objc.dg/proto-lossage-4.m
@@ -28,13 +28,13 @@  long foo(void) {
   receiver += [receiver anotherValue]; /* { dg-warning "invalid receiver type .intptr_t." } */
 
   receiver += [(Obj *)receiver someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */
-/* { dg-warning "assignment to 'intptr_t {aka (long )?int}' from 'id' makes integer from pointer without a cast" "" { target *-*-* } .-1 } */
+/* { dg-warning "assignment to 'intptr_t' {aka '(long )?int'} from 'id' makes integer from pointer without a cast" "" { target *-*-* } .-1 } */
 
   receiver += [(Obj *)receiver anotherValue];
   receiver += [(Obj <Proto> *)receiver someValue];
   receiver += [(Obj <Proto> *)receiver anotherValue];
   receiver += [objrcvr someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */
-/* { dg-warning "assignment to 'intptr_t {aka (long )?int}' from 'id' makes integer from pointer without a cast" "" { target *-*-* } .-1 } */
+/* { dg-warning "assignment to 'intptr_t' {aka '(long )?int'} from 'id' makes integer from pointer without a cast" "" { target *-*-* } .-1 } */
 
   receiver += [objrcvr anotherValue];
   receiver += [(Obj <Proto> *)objrcvr someValue];
@@ -42,7 +42,7 @@  long foo(void) {
   receiver += [objrcvr2 someValue];
   receiver += [objrcvr2 anotherValue];
   receiver += [(Obj *)objrcvr2 someValue]; /* { dg-warning ".Obj. may not respond to .\\-someValue." } */
-/* { dg-warning "assignment to 'intptr_t {aka (long )?int}' from 'id' makes integer from pointer without a cast" "" { target *-*-* } .-1 } */
+/* { dg-warning "assignment to 'intptr_t' {aka '(long )?int'} from 'id' makes integer from pointer without a cast" "" { target *-*-* } .-1 } */
 
   receiver += [(Obj *)objrcvr2 anotherValue];
 
diff --git a/gcc/tree-diagnostic.c b/gcc/tree-diagnostic.c
index 023e896..c80ae54 100644
--- a/gcc/tree-diagnostic.c
+++ b/gcc/tree-diagnostic.c
@@ -246,7 +246,7 @@  virt_loc_aware_diagnostic_finalizer (diagnostic_context *context,
 bool
 default_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
 		      int precision, bool wide, bool set_locus, bool hash,
-		      bool, const char **)
+		      bool *, const char **)
 {
   tree t;
 
diff --git a/gcc/tree-diagnostic.h b/gcc/tree-diagnostic.h
index 85aa980..e38bb44 100644
--- a/gcc/tree-diagnostic.h
+++ b/gcc/tree-diagnostic.h
@@ -55,6 +55,6 @@  void virt_loc_aware_diagnostic_finalizer (diagnostic_context *,
 
 void tree_diagnostics_defaults (diagnostic_context *context);
 bool default_tree_printer (pretty_printer *, text_info *, const char *,
-			   int, bool, bool, bool, bool, const char **);
+			   int, bool, bool, bool, bool *, const char **);
 
 #endif /* ! GCC_TREE_DIAGNOSTIC_H */