Simplify and correct the check for function redefinitions. This does two things:

  - Allows definitions of overloaded functions :)
  - Eliminates extraneous error messages when we have a definition of a 
    function that isn't an overload but doesn't have exactly the same type
    as the original.
  



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58382 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 90fe1ee..2306151 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1761,20 +1761,6 @@
   
   Scope *GlobalScope = FnBodyScope->getParent();
 
-  // See if this is a redefinition.
-  Decl *PrevDcl = LookupDecl(D.getIdentifier(), Decl::IDNS_Ordinary,
-                             GlobalScope);
-  if (PrevDcl && isDeclInScope(PrevDcl, CurContext)) {
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(PrevDcl)) {
-      const FunctionDecl *Definition;
-      if (FD->getBody(Definition)) {
-        Diag(D.getIdentifierLoc(), diag::err_redefinition, 
-             D.getIdentifier()->getName());
-        Diag(Definition->getLocation(), diag::err_previous_definition);
-      }
-    }
-  }
-
   return ActOnStartOfFunctionDef(FnBodyScope,
                                  ActOnDeclarator(GlobalScope, D, 0));
 }
@@ -1782,6 +1768,15 @@
 Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) {
   Decl *decl = static_cast<Decl*>(D);
   FunctionDecl *FD = cast<FunctionDecl>(decl);
+
+  // See if this is a redefinition.
+  const FunctionDecl *Definition;
+  if (FD->getBody(Definition)) {
+    Diag(FD->getLocation(), diag::err_redefinition, 
+         FD->getName());
+    Diag(Definition->getLocation(), diag::err_previous_definition);
+  }
+
   PushDeclContext(FD);
     
   // Check the validity of our function parameters
diff --git a/test/SemaCXX/fntype-decl.cpp b/test/SemaCXX/fntype-decl.cpp
index d9fb8bb..ee72f0c 100644
--- a/test/SemaCXX/fntype-decl.cpp
+++ b/test/SemaCXX/fntype-decl.cpp
@@ -2,7 +2,7 @@
 
 // PR2942
 typedef void fn(int);
-fn f;
+fn f; // expected-error{{previous declaration is here}}
 
 int g(int x, int y);
 int g(int x, int y = 2);
@@ -10,6 +10,11 @@
 typedef int g_type(int, int);
 g_type g;
 
-int h(int x) {
+int h(int x) { // expected-error{{previous definition is here}}
   return g(x);
 }
+
+float f(int) { } // expected-error{{functions that differ only in their return type cannot be overloaded}}
+
+int h(int) { } // expected-error{{redefinition of 'h'}}
+
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index 5b4f404..963f7bd 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -1,6 +1,6 @@
 // RUN: clang -fsyntax-only -pedantic -verify %s 
-int* f(int);
-float* f(float);
+int* f(int) { return 0; }
+float* f(float) { return 0; }
 void f();
 
 void test_f(int iv, float fv) {