summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2008-01-14 20:51:29 +0000
committerSteve Naroff <snaroff@apple.com>2008-01-14 20:51:29 +0000
commit012484d6c80fc1b2867c576d7d3468d8bb70847a (patch)
treea6a5586d7b6f3e1ebc020bb0a14853e606c79d4d /clang
parent38987c1dcc5b66adaaa4281d3fd7c19bd2e2df71 (diff)
downloadbcm5719-llvm-012484d6c80fc1b2867c576d7d3468d8bb70847a.tar.gz
bcm5719-llvm-012484d6c80fc1b2867c576d7d3468d8bb70847a.zip
Fix crasher when redefining functions. Not 100% pleased with this solution, but it is clearly an improvement. Will discuss with Chris later.
llvm-svn: 45975
Diffstat (limited to 'clang')
-rw-r--r--clang/Sema/SemaDecl.cpp25
-rw-r--r--clang/test/Sema/merge-decls.c15
2 files changed, 29 insertions, 11 deletions
diff --git a/clang/Sema/SemaDecl.cpp b/clang/Sema/SemaDecl.cpp
index 1610008191b..621e2d98955 100644
--- a/clang/Sema/SemaDecl.cpp
+++ b/clang/Sema/SemaDecl.cpp
@@ -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.
diff --git a/clang/test/Sema/merge-decls.c b/clang/test/Sema/merge-decls.c
index f9a89988f2f..22026e7f258 100644
--- a/clang/test/Sema/merge-decls.c
+++ b/clang/test/Sema/merge-decls.c
@@ -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'}}
+
OpenPOWER on IntegriCloud