]> granicus.if.org Git - clang/commitdiff
Simplify and correct the check for function redefinitions. This does two things:
authorDouglas Gregor <dgregor@apple.com>
Wed, 29 Oct 2008 15:10:40 +0000 (15:10 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 29 Oct 2008 15:10:40 +0000 (15:10 +0000)
  - 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

lib/Sema/SemaDecl.cpp
test/SemaCXX/fntype-decl.cpp
test/SemaCXX/overload-call.cpp

index 90fe1ee8a8f519242ccb4d61c32fd77fef8c80ae..2306151279c95d39ab0b3a08e7fe607800e9bc1e 100644 (file)
@@ -1761,20 +1761,6 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
   
   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, Declarator &D) {
 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
index d9fb8bbb5935b4a862dc941ea3560c0bd122ee31..ee72f0cdaf17c22f1d9291efd4a39cea20326f0e 100644 (file)
@@ -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 @@ int g(int x, int y = 2);
 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'}}
+
index 5b4f404d1b2cc834b884662b117bfbbb0606f1a6..963f7bd1e344ba198481b5ffba2d300e5ebdd128 100644 (file)
@@ -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) {