Handle incompatible redeclarations of library builtins better.
Invalid redeclarations of valid explicit declarations shouldn't
take the same path as redeclarations of implicit declarations,
and invalid local extern declarations shouldn't foul things up
for everybody else.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179482 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Sema/extern-redecl.c b/test/Sema/extern-redecl.c
index 64885a0..e9a4c57 100644
--- a/test/Sema/extern-redecl.c
+++ b/test/Sema/extern-redecl.c
@@ -42,3 +42,23 @@
   }
   int x = sizeof(test4_array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}
 }
+
+// Test that invalid local extern declarations of library
+// builtins behave reasonably.
+extern void abort(void); // expected-note 2 {{previous declaration is here}}
+extern float *calloc(); // expected-warning {{incompatible redeclaration of library function}} expected-note {{is a builtin}} expected-note 2 {{previous declaration is here}}
+void test5a() {
+  int abort(); // expected-error {{conflicting types}}
+  float *malloc(); // expected-warning {{incompatible redeclaration of library function}} expected-note 2 {{is a builtin}}
+  int *calloc(); // expected-error {{conflicting types}}
+}
+void test5b() {
+  int abort(); // expected-error {{conflicting types}}
+  float *malloc(); // expected-warning {{incompatible redeclaration of library function}}
+  int *calloc(); // expected-error {{conflicting types}}
+}
+void test5c() {
+  void (*_abort)(void) = &abort;
+  void *(*_malloc)() = &malloc;
+  float *(*_calloc)() = &calloc;
+}