diff options
| author | Steve Naroff <snaroff@apple.com> | 2008-01-14 20:51:29 +0000 |
|---|---|---|
| committer | Steve Naroff <snaroff@apple.com> | 2008-01-14 20:51:29 +0000 |
| commit | 012484d6c80fc1b2867c576d7d3468d8bb70847a (patch) | |
| tree | a6a5586d7b6f3e1ebc020bb0a14853e606c79d4d /clang | |
| parent | 38987c1dcc5b66adaaa4281d3fd7c19bd2e2df71 (diff) | |
| download | bcm5719-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.cpp | 25 | ||||
| -rw-r--r-- | clang/test/Sema/merge-decls.c | 15 |
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'}} + |

