diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index e950f3eb09..86da9e907b 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -517,19 +517,26 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, diag::err_param_default_argument_member_template_redecl) << WhichKind << NewParam->getDefaultArgRange(); - } else if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(New)) { - CXXSpecialMember NewSM = getSpecialMember(Ctor), - OldSM = getSpecialMember(cast<CXXConstructorDecl>(Old)); - if (NewSM != OldSM) { - Diag(NewParam->getLocation(),diag::warn_default_arg_makes_ctor_special) - << NewParam->getDefaultArgRange() << NewSM; - Diag(Old->getLocation(), diag::note_previous_declaration_special) - << OldSM; - } } } } + // DR1344: If a default argument is added outside a class definition and that + // default argument makes the function a special member function, the program + // is ill-formed. This can only happen for constructors. + if (isa<CXXConstructorDecl>(New) && + New->getMinRequiredArguments() < Old->getMinRequiredArguments()) { + CXXSpecialMember NewSM = getSpecialMember(cast<CXXMethodDecl>(New)), + OldSM = getSpecialMember(cast<CXXMethodDecl>(Old)); + if (NewSM != OldSM) { + ParmVarDecl *NewParam = New->getParamDecl(New->getMinRequiredArguments()); + assert(NewParam->hasDefaultArg()); + Diag(NewParam->getLocation(), diag::err_default_arg_makes_ctor_special) + << NewParam->getDefaultArgRange() << NewSM; + Diag(Old->getLocation(), diag::note_previous_declaration); + } + } + // C++11 [dcl.constexpr]p1: If any declaration of a function or function // template has a constexpr specifier then all its declarations shall // contain the constexpr specifier. |