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) <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
This commit is contained in:
Marek Polacek 2014-10-30 17:22:12 +00:00 committed by Marek Polacek
parent f1308e4b82
commit 2d51fcef56
7 changed files with 90 additions and 24 deletions

View 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

View 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);
{
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);
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
{
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)

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

View File

@ -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;
}

View 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'" } */
}

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

View 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\\\[\\\]}'" } */
}