[cfe-commits] r132104 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/SemaCXX/copy-constructor-error.cpp test/SemaCXX/default-arg-special-member.cpp

Douglas Gregor dgregor at apple.com
Wed Jun 1 16:43:55 PDT 2011


On May 25, 2011, at 6:26 PM, Sean Hunt wrote:

> Author: coppro
> Date: Wed May 25 20:26:05 2011
> New Revision: 132104
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=132104&view=rev
> Log:
> Implement a new warning for when adding a default argument to a method
> makes it into a special member function. This is very bad and can lead
> to all sorts of nastiness including implicit member functions violating
> the One Definition Rule. This should probably be made ill-formed in a
> later version of the standard, but for now we'll just warn.
> 
> Added:
>    cfe/trunk/test/SemaCXX/default-arg-special-member.cpp
> Modified:
>    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>    cfe/trunk/lib/Sema/SemaDecl.cpp
>    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>    cfe/trunk/test/SemaCXX/copy-constructor-error.cpp
> 
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=132104&r1=132103&r2=132104&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed May 25 20:26:05 2011
> @@ -1416,6 +1416,13 @@
> def err_uninitialized_member_in_ctor : Error<
>   "%select{|implicit default }0constructor for %1 must explicitly initialize "
>   "the %select{reference|const}2 member %3">;
> +def warn_default_arg_makes_ctor_special : Warning<
> +  "addition of default argument on redeclaration makes this constructor a "
> +  "%select{default|copy|move}0 constructor">;
> +def note_previous_declaration_special : Note<
> +  // The ERRORs are in hopes that if they occur, they'll get reported.
> +  "previous declaration was %select{*ERROR*|a copy constructor|a move "
> +  "constructor|*ERROR*|*ERROR*|*ERROR*|not a special member function}0">;
> 
> def err_use_of_default_argument_to_function_declared_later : Error<
>   "use of default argument to function %0 that is declared later in class %1">;
> 
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=132104&r1=132103&r2=132104&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed May 25 20:26:05 2011
> @@ -1505,14 +1505,14 @@
> /// getSpecialMember - get the special member enum for a method.
> Sema::CXXSpecialMember Sema::getSpecialMember(const CXXMethodDecl *MD) {
>   if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
> +    if (Ctor->isDefaultConstructor())
> +      return Sema::CXXDefaultConstructor;
> +
>     if (Ctor->isCopyConstructor())
>       return Sema::CXXCopyConstructor;
> -    
> +
>     if (Ctor->isMoveConstructor())
>       return Sema::CXXMoveConstructor;
> -    
> -    if (Ctor->isDefaultConstructor())
> -      return Sema::CXXDefaultConstructor;
>   } else if (isa<CXXDestructorDecl>(MD)) {
>     return Sema::CXXDestructor;
>   } else if (MD->isCopyAssignmentOperator()) {
> 
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=132104&r1=132103&r2=132104&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed May 25 20:26:05 2011
> @@ -457,6 +457,15 @@
>              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;
> +        }
>       }
>     }
>   }

Do you plan to do the same thing for copy-assignment or move-assignment operators?

	- Doug




More information about the cfe-commits mailing list