Commit 0e36f5c7 by Marek Polacek Committed by Marek Polacek

re PR c/67580 (Improve error message on missing "struct" tag)

	PR c/67580
	* c-decl.c (tag_exists_p): New function.
	* c-parser.c (c_parser_declaration_or_fndef): Give a hint when
	struct/union/enum keywords are missing.
	* c-tree.h (tag_exists_p): Declare.

	* gcc.dg/pr67580.c: New test.

From-SVN: r227803
parent c33c18cd
2015-09-15 Marek Polacek <polacek@redhat.com>
PR c/67580
* c-decl.c (tag_exists_p): New function.
* c-parser.c (c_parser_declaration_or_fndef): Give a hint when
struct/union/enum keywords are missing.
* c-tree.h (tag_exists_p): Declare.
2015-09-15 Marek Polacek <polacek@redhat.com>
* c-decl.c (lookup_label): Return NULL_TREE instead of 0.
(lookup_tag): Change the type of THISLEVEL_ONLY to bool.
Return NULL_TREE instead of 0.
......
......@@ -3856,6 +3856,18 @@ lookup_tag (enum tree_code code, tree name, bool thislevel_only,
return b->decl;
}
/* Return true if a definition exists for NAME with code CODE. */
bool
tag_exists_p (enum tree_code code, tree name)
{
struct c_binding *b = I_TAG_BINDING (name);
if (b == NULL || b->decl == NULL_TREE)
return false;
return TREE_CODE (b->decl) == code;
}
/* Print an error message now
for a recent invalid struct, union or enum cross reference.
We don't print them immediately because they are not invalid
......
......@@ -1539,8 +1539,16 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|| c_parser_peek_2nd_token (parser)->type == CPP_MULT)
&& (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
{
error_at (here, "unknown type name %qE",
c_parser_peek_token (parser)->value);
tree name = c_parser_peek_token (parser)->value;
error_at (here, "unknown type name %qE", name);
/* Give a hint to the user. This is not C++ with its implicit
typedef. */
if (tag_exists_p (RECORD_TYPE, name))
inform (here, "use %<struct%> keyword to refer to the type");
else if (tag_exists_p (UNION_TYPE, name))
inform (here, "use %<union%> keyword to refer to the type");
else if (tag_exists_p (ENUMERAL_TYPE, name))
inform (here, "use %<enum%> keyword to refer to the type");
/* Parse declspecs normally to get a correct pointer type, but avoid
a further "fails to be a type name" error. Refuse nested functions
......
......@@ -701,6 +701,7 @@ extern tree c_omp_reduction_lookup (tree, tree);
extern tree c_check_omp_declare_reduction_r (tree *, int *, void *);
extern void c_pushtag (location_t, tree, tree);
extern void c_bind (location_t, tree, bool);
extern bool tag_exists_p (enum tree_code, tree);
/* In c-errors.c */
extern void pedwarn_c90 (location_t, int opt, const char *, ...)
......
2015-09-15 Marek Polacek <polacek@redhat.com>
PR c/67580
* gcc.dg/pr67580.c: New test.
2015-09-15 Richard Biener <rguenther@suse.de>
PR tree-optimization/67470
......
/* PR c/67580 */
/* { dg-do compile } */
struct S { int s; };
union U { int s; };
enum E { A };
void
f (void)
{
S s; /* { dg-error "unknown type name" } */
/* { dg-message "use .struct. keyword to refer to the type" "" { target *-*-* } 11 } */
U u; /* { dg-error "unknown type name" } */
/* { dg-message "use .union. keyword to refer to the type" "" { target *-*-* } 13 } */
E e; /* { dg-error "unknown type name" } */
/* { dg-message "use .enum. keyword to refer to the type" "" { target *-*-* } 15 } */
}
void
g (void)
{
struct T { int i; };
union V { int i; };
enum F { J };
T t; /* { dg-error "unknown type name" } */
/* { dg-message "use .struct. keyword to refer to the type" "" { target *-*-* } 25 } */
V v; /* { dg-error "unknown type name" } */
/* { dg-message "use .union. keyword to refer to the type" "" { target *-*-* } 27 } */
F f; /* { dg-error "unknown type name" } */
/* { dg-message "use .enum. keyword to refer to the type" "" { target *-*-* } 29 } */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment