diff options
author | Charles Davis <cdavis@mines.edu> | 2010-02-18 02:00:42 +0000 |
---|---|---|
committer | Charles Davis <cdavis@mines.edu> | 2010-02-18 02:00:42 +0000 |
commit | fea484560945ee26c883f1a455e38e11d9743757 (patch) | |
tree | bafa66d7c500c21bee25448307cc9588f36b6324 /clang/lib/Sema/SemaDecl.cpp | |
parent | 84c51c35812049a1a82f33b0708a1e2d6e041a6a (diff) | |
download | bcm5719-llvm-fea484560945ee26c883f1a455e38e11d9743757.tar.gz bcm5719-llvm-fea484560945ee26c883f1a455e38e11d9743757.zip |
Allow redefinitions of extern inline functions in GNU89 mode, just as GCC
does. Fixes PR5253.
llvm-svn: 96553
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e7217dc2200..949669aa572 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -908,6 +908,16 @@ static Sema::CXXSpecialMember getSpecialMember(ASTContext &Ctx, return Sema::CXXCopyAssignment; } +/// canREdefineFunction - checks if a function can be redefined. Currently, +/// only extern inline functions can be redefined, and even then only in +/// GNU89 mode. +static bool canRedefineFunction(const FunctionDecl *FD, + const LangOptions& LangOpts) { + return (LangOpts.GNUMode && !LangOpts.C99 && !LangOpts.CPlusPlus && + FD->isInlineSpecified() && + FD->getStorageClass() == FunctionDecl::Extern); +} + /// MergeFunctionDecl - We just parsed a function 'New' from /// declarator D which has the same name and scope as a previous /// declaration 'Old'. Figure out how to resolve this situation, @@ -956,9 +966,12 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { QualType OldQType = Context.getCanonicalType(Old->getType()); QualType NewQType = Context.getCanonicalType(New->getType()); + // Don't complain about this if we're in GNU89 mode and the old function + // is an extern inline function. if (!isa<CXXMethodDecl>(New) && !isa<CXXMethodDecl>(Old) && New->getStorageClass() == FunctionDecl::Static && - Old->getStorageClass() != FunctionDecl::Static) { + Old->getStorageClass() != FunctionDecl::Static && + !canRedefineFunction(Old, getLangOptions())) { Diag(New->getLocation(), diag::err_static_non_static) << New; Diag(Old->getLocation(), PrevDiag); @@ -4062,8 +4075,11 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) { CurFunctionNeedsScopeChecking = false; // See if this is a redefinition. + // But don't complain if we're in GNU89 mode and the previous definition + // was an extern inline function. const FunctionDecl *Definition; - if (FD->getBody(Definition)) { + if (FD->getBody(Definition) && + !canRedefineFunction(Definition, getLangOptions())) { Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName(); Diag(Definition->getLocation(), diag::note_previous_definition); } |