Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp (revision 209303) +++ lib/Sema/SemaDecl.cpp (working copy) @@ -2748,18 +2748,13 @@ Diag(New->getLocation(), diag::warn_redecl_library_builtin) << New; Diag(OldLocation, diag::note_previous_builtin_declaration) << Old << Old->getType(); + // New user declared function is overriding the built-in. Not only + // forget about its "builtin-ness", but also make the impliclitly + // declared built-in function invalid; otherwise, We have a built-in + // declaration AST whose Identifier is Builtin::NotBuiltin. + New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin); + Old->setInvalidDecl(); - // If this is a global redeclaration, just forget hereafter - // about the "builtin-ness" of the function. - // - // Doing this for local extern declarations is problematic. If - // the builtin declaration remains visible, a second invalid - // local declaration will produce a hard error; if it doesn't - // remain visible, a single bogus local redeclaration (which is - // actually only a warning) could break all the downstream code. - if (!New->getLexicalDeclContext()->isFunctionOrMethod()) - New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin); - return false; } Index: test/CodeGen/locally-redeclared-builtin-call.c =================================================================== --- test/CodeGen/locally-redeclared-builtin-call.c (revision 0) +++ test/CodeGen/locally-redeclared-builtin-call.c (working copy) @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// rdar://16897451 + +int Test() +{ + int a,b; + int pow (int,int); + return pow(a,b); +} +// CHECK-NOT: call i32 @llvm.pow.i32 +// CHECK: [[CALL:%.*]] = call i32 @pow(i32 %0, i32 %1) +// ret i32 [[CALL]] + +int pow(int c,int d) +{ + return c*d; +} Index: test/Sema/extern-redecl.c =================================================================== --- test/Sema/extern-redecl.c (revision 209303) +++ test/Sema/extern-redecl.c (working copy) @@ -49,12 +49,12 @@ 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}} + float *malloc(); // expected-warning {{incompatible redeclaration of library function}} expected-note {{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}} + float *malloc(); int *calloc(); // expected-error {{conflicting types}} } void test5c() {