===================================================================
@@ -1630,13 +1630,14 @@ validate_proto_after_old_defn (tree newd
/* Subroutine of diagnose_mismatched_decls. Report the location of DECL,
first in a pair of mismatched declarations, using the diagnostic
function DIAG. */
static void
locate_old_decl (tree decl)
{
- if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
+ if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl)
+ && !C_DECL_DECLARED_BUILTIN (decl))
;
else if (DECL_INITIAL (decl))
inform (input_location, "previous definition of %q+D was here", decl);
else if (C_DECL_IMPLICIT (decl))
inform (input_location, "previous implicit declaration of %q+D was here", decl);
else
===================================================================
@@ -0,0 +1,22 @@
+/* This test assumes -fbuiltin and not -fansi to get "index" and "memchr" builtin DECLs. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+/* The bug this is testing is that if a new decl conflicts with an
+ explicit decl, you don't get the "changes type of builtin" message,
+ but if there was *also* a builtin, you *also* don't get the
+ "previous declaration was here" message, leaving you with no clue
+ where the previous declaration came from. */
+
+extern char foo(int,int); /* { dg-message "previous declaration of 'foo' was here" } */
+extern char *index(const char *,int); /* { dg-message "previous declaration of 'index' was here" } */
+
+/* This changes the type of "index", which is both a builtin and an
+ explicit decl. */
+int index; /* { dg-error "redeclared as different kind of symbol" } */
+
+/* This changes the type of "memchr", which is only a builtin. */
+int memchr; /* { dg-warning "built-in function 'memchr' declared as non-function" } */
+
+/* This changes the type of "foo", which is only an explicit decl. */
+int foo; /* { dg-error "redeclared as different kind of symbol" } */