r248953 - [Sema] Don't crash when friending an unqualified templated constructor

Sean Silva via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 2 20:02:39 PDT 2015


On Wed, Sep 30, 2015 at 3:07 PM, David Majnemer via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: majnemer
> Date: Wed Sep 30 17:07:43 2015
> New Revision: 248953
>
> URL: http://llvm.org/viewvc/llvm-project?rev=248953&view=rev
> Log:
> [Sema] Don't crash when friending an unqualified templated constructor
>
> Unqualified templated constructors cannot be friended and our lack of a
> diagnostic led to violated invariants.  Instead, raise a diagnostic when
> processing the friend declaration.
>
> This fixes PR20251.
>
> Modified:
>     cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>     cfe/trunk/test/CXX/class/class.friend/p1.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=248953&r1=248952&r2=248953&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Sep 30 17:07:43 2015
> @@ -12689,15 +12689,31 @@ NamedDecl *Sema::ActOnFriendFunctionDecl
>      DC = CurContext;
>      assert(isa<CXXRecordDecl>(DC) && "friend declaration not in class?");
>    }
> -
> +
>    if (!DC->isRecord()) {
> +    int DiagArg = -1;
> +    switch (D.getName().getKind()) {
> +    case UnqualifiedId::IK_ConstructorTemplateId:
> +    case UnqualifiedId::IK_ConstructorName:
> +      DiagArg = 0;
> +      break;
> +    case UnqualifiedId::IK_DestructorName:
> +      DiagArg = 1;
> +      break;
> +    case UnqualifiedId::IK_ConversionFunctionId:
> +      DiagArg = 2;
> +      break;
> +    case UnqualifiedId::IK_Identifier:
> +    case UnqualifiedId::IK_ImplicitSelfParam:
> +    case UnqualifiedId::IK_LiteralOperatorId:
> +    case UnqualifiedId::IK_OperatorFunctionId:
> +    case UnqualifiedId::IK_TemplateId:
> +      break;
> +      llvm_unreachable("Didn't expect this kind of unqualified-id!");
>

Is the break followed by unreachable intentional?

-- Sean Silva


> +    }
>      // This implies that it has to be an operator or function.
> -    if (D.getName().getKind() == UnqualifiedId::IK_ConstructorName ||
> -        D.getName().getKind() == UnqualifiedId::IK_DestructorName ||
> -        D.getName().getKind() == UnqualifiedId::IK_ConversionFunctionId) {
> -      Diag(Loc, diag::err_introducing_special_friend) <<
> -        (D.getName().getKind() == UnqualifiedId::IK_ConstructorName ? 0 :
> -         D.getName().getKind() == UnqualifiedId::IK_DestructorName ? 1 :
> 2);
> +    if (DiagArg >= 0) {
> +      Diag(Loc, diag::err_introducing_special_friend) << DiagArg;
>        return nullptr;
>      }
>    }
>
> Modified: cfe/trunk/test/CXX/class/class.friend/p1.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.friend/p1.cpp?rev=248953&r1=248952&r2=248953&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/CXX/class/class.friend/p1.cpp (original)
> +++ cfe/trunk/test/CXX/class/class.friend/p1.cpp Wed Sep 30 17:07:43 2015
> @@ -79,3 +79,9 @@ class PreDeclared;
>  int myoperation(float f) {
>    return (int) f;
>  }
> +
> +template <typename T>
> +class B {
> +  template <typename U>
> +  friend B<U>() {} // expected-error {{must use a qualified name when
> declaring a constructor as a friend}}
> +};
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151002/d44d589f/attachment-0001.html>


More information about the cfe-commits mailing list