c-decl.c (locate_old_decl): If a previous conflicting decl is both explicit and built...
authorDJ Delorie <dj@redhat.com>
Wed, 6 Nov 2013 23:33:33 +0000 (18:33 -0500)
committerDJ Delorie <dj@gcc.gnu.org>
Wed, 6 Nov 2013 23:33:33 +0000 (18:33 -0500)
* c-decl.c (locate_old_decl): If a previous conflicting decl is
both explicit and builtin, print the location of the explicit one.

* gcc.dg/mismatch-decl-1.c: New test.

From-SVN: r204491

gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/mismatch-decl-1.c [new file with mode: 0644]

index 9a9eed3..cc335e4 100644 (file)
@@ -1,3 +1,8 @@
+2013-11-06  DJ Delorie  <dj@redhat.com>
+
+       * c-decl.c (locate_old_decl): If a previous conflicting decl is
+       both explicit and builtin, print the location of the explicit one.
+
 2013-11-05  Tobias Burnus  <burnus@net-b.de>
 
        * c-parser.c (c_parser_omp_for, c_parser_omp_parallel,
index 2833fdb..23f0516 100644 (file)
@@ -1634,7 +1634,8 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
 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);
index ce0c26c..b857d00 100644 (file)
@@ -1,3 +1,7 @@
+2013-11-06  DJ Delorie  <dj@redhat.com>
+
+       * gcc.dg/mismatch-decl-1.c: New test.
+
 2013-11-06  Joseph Myers  <joseph@codesourcery.com>
 
        * gcc.dg/torture/float128-cmp-invalid.c,
diff --git a/gcc/testsuite/gcc.dg/mismatch-decl-1.c b/gcc/testsuite/gcc.dg/mismatch-decl-1.c
new file mode 100644 (file)
index 0000000..da4db0a
--- /dev/null
@@ -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" } */