summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorCharles Davis <cdavis@mines.edu>2010-02-18 02:00:42 +0000
committerCharles Davis <cdavis@mines.edu>2010-02-18 02:00:42 +0000
commitfea484560945ee26c883f1a455e38e11d9743757 (patch)
treebafa66d7c500c21bee25448307cc9588f36b6324 /clang/lib/Sema/SemaDecl.cpp
parent84c51c35812049a1a82f33b0708a1e2d6e041a6a (diff)
downloadbcm5719-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.cpp20
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);
}
OpenPOWER on IntegriCloud