+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.
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
|| 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
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
--- /dev/null
+/* 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 } */
+}