From 2d51fcef56807789d5a6d929174a4581bd9e2ce3 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 30 Oct 2014 17:22:12 +0000 Subject: [PATCH] c-objc-common.c (c_tree_printer): For a typedef name, print the stripped version as well, if they're not the same. * c-objc-common.c (c_tree_printer) : 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 | 5 +++ gcc/c/c-objc-common.c | 57 ++++++++++++++++++++++--------- gcc/testsuite/ChangeLog | 7 ++++ gcc/testsuite/gcc.dg/diag-aka-1.c | 29 ++++++++++++++++ gcc/testsuite/gcc.dg/pr13804-1.c | 4 +-- gcc/testsuite/gcc.dg/pr56980.c | 12 +++---- gcc/testsuite/gcc.dg/redecl-14.c | 2 +- 7 files changed, 91 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/diag-aka-1.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index e2d061f9287..24781e1b7a2 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2014-10-30 Marek Polacek + + * c-objc-common.c (c_tree_printer) : For a typedef name, + print the stripped version as well, if they're not the same. + 2014-10-29 Richard Sandiford * c-decl.c, c-tree.h, c-typeck.c: Remove redundant enum from diff --git a/gcc/c/c-objc-common.c b/gcc/c/c-objc-common.c index 12db5487894..64481a5b7ac 100644 --- a/gcc/c/c-objc-common.c +++ b/gcc/c/c-objc-common.c @@ -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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b6cc2e444b8..3aa9b6b5a56 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-10-30 Marek Polacek + + * 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 * 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 index 00000000000..87bc75753e4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/diag-aka-1.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/pr13804-1.c b/gcc/testsuite/gcc.dg/pr13804-1.c index 4363678289f..65b238a9b8f 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' 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'" } */ } diff --git a/gcc/testsuite/gcc.dg/pr56980.c b/gcc/testsuite/gcc.dg/pr56980.c index f48379a79ec..27405efac4e 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 \\*." } */ -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) diff --git a/gcc/testsuite/gcc.dg/redecl-14.c b/gcc/testsuite/gcc.dg/redecl-14.c index b27c02441d3..97003c1234b 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'" } */ + sizeof (*a[0]); /* { dg-error "invalid application of 'sizeof' to incomplete type 'IA {aka int\\\[\\\]}'" } */ } -- 2.30.2