]> granicus.if.org Git - clang/commitdiff
Fix crasher when redefining functions. Not 100% pleased with this solution, but it...
authorSteve Naroff <snaroff@apple.com>
Mon, 14 Jan 2008 20:51:29 +0000 (20:51 +0000)
committerSteve Naroff <snaroff@apple.com>
Mon, 14 Jan 2008 20:51:29 +0000 (20:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45975 91177308-0d34-0410-b5e6-96231b3b80d8

Sema/SemaDecl.cpp
test/Sema/merge-decls.c

index 1610008191b0889c31f50dea0cc6301ffcc5d3ca..621e2d98955fbdc58890a2628c149455d9dfb022 100644 (file)
@@ -245,16 +245,12 @@ FunctionDecl *Sema::MergeFunctionDecl(FunctionDecl *New, ScopedDecl *OldD) {
     if (OldQType.getTypePtr()->getTypeClass() == Type::FunctionNoProto && 
         Old->getResultType() == New->getResultType())
       return New;
-    // Function types need to be compatible, not identical. This handles
-    // duplicate function decls like "void f(int); void f(enum X);" properly.
-    if (Context.functionTypesAreCompatible(OldQType, NewQType))
-      return New;
   }
+  // Function types need to be compatible, not identical. This handles
+  // duplicate function decls like "void f(int); void f(enum X);" properly.
+  if (Context.functionTypesAreCompatible(OldQType, NewQType))
+    return New;
 
-  if (New->getBody() == 0 && OldQType == NewQType) {
-    return 0;
-  }
-  
   // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
   // TODO: This is totally simplistic.  It should handle merging functions
   // together etc, merging extern int X; int X; ...
@@ -950,9 +946,20 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
   }
   
   Scope *GlobalScope = FnBodyScope->getParent();
-  
+
+  // See if this is a redefinition.
+  ScopedDecl *PrevDcl = LookupScopedDecl(D.getIdentifier(), Decl::IDNS_Ordinary,
+                                         D.getIdentifierLoc(), GlobalScope);
+  if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(PrevDcl)) {
+    if (FD->getBody()) {
+      Diag(D.getIdentifierLoc(), diag::err_redefinition, 
+           D.getIdentifier()->getName());
+      Diag(FD->getLocation(), diag::err_previous_definition);
+    }
+  }
   FunctionDecl *FD =
     static_cast<FunctionDecl*>(ActOnDeclarator(GlobalScope, D, 0));
+  assert(FD != 0 && "ActOnDeclarator() didn't return a FunctionDecl");
   CurFunctionDecl = FD;
   
   // Create Decl objects for each parameter, adding them to the FunctionDecl.
index f9a89988f2f7e373166ec4c68567b47461c3e751..22026e7f2589270b99b53be947157d8a21d8207c 100644 (file)
@@ -1,8 +1,19 @@
 // RUN: clang %s -verify -fsyntax-only
 
 void foo(void);
-void foo(void) {} // expected-error{{previous definition is here}}
-void foo(void);
+void foo(void) {} 
 void foo(void);
+void foo(void); // expected-error{{previous definition is here}}
 
 void foo(int); // expected-error {{redefinition of 'foo'}}
+
+int funcdef()
+{
+ return 0;
+}
+
+int funcdef();
+
+int funcdef2() { return 0; } // expected-error{{previous definition is here}}
+int funcdef2() { return 0; } // expected-error {{redefinition of 'funcdef2'}}
+