c-objc-common.c (c_tree_printer): For a typedef name, print the stripped version...
authorMarek Polacek <polacek@redhat.com>
Thu, 30 Oct 2014 17:22:12 +0000 (17:22 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Thu, 30 Oct 2014 17:22:12 +0000 (17:22 +0000)
* c-objc-common.c (c_tree_printer) <case 'T'>: For a typedef name,
print the stripped version as well, if they're not the same.

* gcc.dg/diag-aka-1.c: New test.
* gcc.dg/pr13804-1.c: Adjust dg-error.
* gcc.dg/redecl-14.c: Likewise.
* gcc.dg/pr56980.c: Adjust dg-message.

From-SVN: r216941

gcc/c/ChangeLog
gcc/c/c-objc-common.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/diag-aka-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr13804-1.c
gcc/testsuite/gcc.dg/pr56980.c
gcc/testsuite/gcc.dg/redecl-14.c

index e2d061f928700f0ba247e1ac92e818a0c2218ebc..24781e1b7a2198b091f89c60b0e5cd82eb20cae7 100644 (file)
@@ -1,3 +1,8 @@
+2014-10-30  Marek Polacek  <polacek@redhat.com>
+
+       * c-objc-common.c (c_tree_printer) <case 'T'>: For a typedef name,
+       print the stripped version as well, if they're not the same.
+
 2014-10-29  Richard Sandiford  <richard.sandiford@arm.com>
 
        * c-decl.c, c-tree.h, c-typeck.c: Remove redundant enum from
index 12db5487894598c0d769f75dd9b0575a8c6c91fb..64481a5b7ac5074bb63a090a5594fca0400d6fa4 100644 (file)
@@ -127,23 +127,48 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
       break;
 
     case 'T':
-      gcc_assert (TYPE_P (t));
-      name = TYPE_NAME (t);
-
-      if (name && TREE_CODE (name) == TYPE_DECL)
-       {
-         if (DECL_NAME (name))
-           pp_identifier (cpp, lang_hooks.decl_printable_name (name, 2));
-         else
-           cpp->type_id (t);
-         return true;
-       }
-      else
-       {
+      {
+       gcc_assert (TYPE_P (t));
+       struct obstack *ob = pp_buffer (cpp)->obstack;
+       char *p = (char *) obstack_base (ob);
+       /* Remember the end of the initial dump.  */
+       int len = obstack_object_size (ob);
+
+       name = TYPE_NAME (t);
+       if (name && TREE_CODE (name) == TYPE_DECL && DECL_NAME (name))
+         pp_identifier (cpp, lang_hooks.decl_printable_name (name, 2));
+       else
          cpp->type_id (t);
-         return true;
-       }
-      break;
+
+       /* 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 it in that case, we play ugly obstack games.  */
+       if (TYPE_CANONICAL (t) && t != TYPE_CANONICAL (t))
+         {
+           c_pretty_printer cpp2;
+           /* Print the stripped version into a temporary printer.  */
+           cpp2.type_id (TYPE_CANONICAL (t));
+           struct obstack *ob2 = cpp2.buffer->obstack;
+           /* Get the stripped version from the temporary printer.  */
+           const char *aka = (char *) obstack_base (ob2);
+           int aka_len = obstack_object_size (ob2);
+           int type1_len = obstack_object_size (ob) - len;
+
+           /* If they are identical, bail out.  */
+           if (aka_len == type1_len && memcmp (p + len, aka, aka_len) == 0)
+             return true;
+
+           /* They're not, print the stripped version now.  */
+           pp_c_whitespace (cpp);
+           pp_left_brace (cpp);
+           pp_c_ws_string (cpp, _("aka"));
+           pp_c_whitespace (cpp);
+           cpp->type_id (TYPE_CANONICAL (t));
+           pp_right_brace (cpp);
+         }
+       return true;
+      }
 
     case 'E':
       if (TREE_CODE (t) == IDENTIFIER_NODE)
index b6cc2e444b83bb3190af6dc6efe226442539f342..3aa9b6b5a56ff15f2a1a615e38e7dcfd10c5dca6 100644 (file)
@@ -1,3 +1,10 @@
+2014-10-30  Marek Polacek  <polacek@redhat.com>
+
+       * gcc.dg/diag-aka-1.c: New test.
+       * gcc.dg/pr13804-1.c: Adjust dg-error.
+       * gcc.dg/redecl-14.c: Likewise.
+       * gcc.dg/pr56980.c: Adjust dg-message.
+
 2014-10-30  Ian Lance Taylor  <iant@google.com>
 
        * gcc.misc-tests/godump-1.c: Skip if ! lp64.
diff --git a/gcc/testsuite/gcc.dg/diag-aka-1.c b/gcc/testsuite/gcc.dg/diag-aka-1.c
new file mode 100644 (file)
index 0000000..87bc757
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat" } */
+
+typedef struct A { int i; } B;
+typedef struct T { int i; } T;
+typedef const float TFA;
+typedef TFA TFB;
+typedef TFB TFC;
+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 fn2 (TFC *);
+
+void 
+bar (B *b, int *i)
+{
+  fn1 ((struct B *) b); /* { dg-warning "passing argument" } */
+  fn2 (i); /* { dg-warning "passing argument" } */
+  sizeof (arr); /* { dg-error "invalid application of .sizeof. to incomplete type .int \\(\\*\\\[\\\]\\)\\\[\\\]." } */
+}
+
+int
+foo (void *a)
+{
+  T *t = a; /* { dg-warning "request for implicit conversion from .void \\*. to .T \\* {aka struct T \\*}. not" } */
+  return t->i;
+}
index 4363678289f0bc4e6e26847e7b23997b8e463ff0..65b238a9b8fefdc6c4b8d6c510e9c262e8f925fc 100644 (file)
@@ -20,9 +20,9 @@ void
 f (void)
 {
   x0.c; /* { dg-error "'struct s0' has no member named 'c'" } */
-  x1.c; /* { dg-error "'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' 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'" } */
 }
index f48379a79ec2ba7abf17e242867f994f4f75a3da..27405efac4e3df1f46f10a92f21245032a36a40d 100644 (file)
@@ -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 \\*." } */
-void foo_u (union U); /* { dg-message "expected .union U. but argument is of type .V \\*." } */
-void foo_e (enum E); /* { dg-message "expected .enum E. but argument is of type .F \\*." } */
-void foo_sp (B *); /* { dg-message "expected .B \\*. but argument is of type .struct B \\*." } */
-void foo_up (V *); /* { dg-message "expected .V \\*. but argument is of type .union V \\*." } */
-void foo_ep (F *); /* { dg-message "expected .F \\*. 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)
index b27c02441d337240d50056d2f61962c11f128204..97003c1234b85152fd5b156ba6b61b1cc3b4d168 100644 (file)
@@ -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'" } */
+  sizeof (*a[0]); /* { dg-error "invalid application of 'sizeof' to incomplete type 'IA {aka int\\\[\\\]}'" } */
 }