diff options
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index acacdc263c08..844299bb87cf 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -547,17 +547,23 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Diag(OldParam->getLocation(), diag::note_previous_definition) << OldParam->getDefaultArgRange(); } else if (OldParamHasDfl) { - // Merge the old default argument into the new parameter. - // It's important to use getInit() here; getDefaultArg() - // strips off any top-level ExprWithCleanups. - NewParam->setHasInheritedDefaultArg(); - if (OldParam->hasUnparsedDefaultArg()) - NewParam->setUnparsedDefaultArg(); - else if (OldParam->hasUninstantiatedDefaultArg()) - NewParam->setUninstantiatedDefaultArg( - OldParam->getUninstantiatedDefaultArg()); - else - NewParam->setDefaultArg(OldParam->getInit()); + // Merge the old default argument into the new parameter unless the new + // function is a friend declaration in a template class. In the latter + // case the default arguments will be inherited when the friend + // declaration will be instantiated. + if (New->getFriendObjectKind() == Decl::FOK_None || + !New->getLexicalDeclContext()->isDependentContext()) { + // It's important to use getInit() here; getDefaultArg() + // strips off any top-level ExprWithCleanups. + NewParam->setHasInheritedDefaultArg(); + if (OldParam->hasUnparsedDefaultArg()) + NewParam->setUnparsedDefaultArg(); + else if (OldParam->hasUninstantiatedDefaultArg()) + NewParam->setUninstantiatedDefaultArg( + OldParam->getUninstantiatedDefaultArg()); + else + NewParam->setDefaultArg(OldParam->getInit()); + } } else if (NewParamHasDfl) { if (New->getDescribedFunctionTemplate()) { // Paragraph 4, quoted above, only applies to non-template functions. @@ -638,7 +644,12 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Diag(Old->getLocation(), diag::note_previous_declaration); Invalid = true; } else if (!Old->getMostRecentDecl()->isInlined() && New->isInlined() && - Old->isDefined(Def)) { + Old->isDefined(Def) && + // If a friend function is inlined but does not have 'inline' + // specifier, it is a definition. Do not report attribute conflict + // in this case, redefinition will be diagnosed later. + (New->isInlineSpecified() || + New->getFriendObjectKind() == Decl::FOK_None)) { // C++11 [dcl.fcn.spec]p4: // If the definition of a function appears in a translation unit before its // first declaration as inline, the program is ill-formed. @@ -13232,6 +13243,14 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, } } + ExprResult FullAssertExpr = ActOnFinishFullExpr(AssertExpr, StaticAssertLoc, + /*DiscardedValue*/false, + /*IsConstexpr*/true); + if (FullAssertExpr.isInvalid()) + Failed = true; + else + AssertExpr = FullAssertExpr.get(); + Decl *Decl = StaticAssertDecl::Create(Context, CurContext, StaticAssertLoc, AssertExpr, AssertMessage, RParenLoc, Failed); |