diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-11-28 03:45:24 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-11-28 03:45:24 +0000 |
commit | b8abff66a8d30356c82314c4734c692cdd479e5e (patch) | |
tree | 69c0613bc44454c61dfe43e4da6529126e636f8b /lib/Sema/SemaDeclCXX.cpp | |
parent | 1994e3993e5e2c606f4ab22563768af6f03dad30 (diff) |
C++ core issue 1344, PR10618: promote "addition of default argument makes this
a special member" diagnostic from warning to error, and fix the cases where it
produced diagnostics with incorrect wording.
We don't support this as an extension, and we ban it even in C++98 mode. This
breaks too much (for instance, the ABI-specified calling convention for a type
can change if it acquires a copy constructor through the addition of a default
argument).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168769 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-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. |