[cfe-commits] r111609 - in /cfe/trunk: lib/Sema/SemaAccess.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.decls/temp.friend/p5.cpp

Douglas Gregor dgregor at apple.com
Thu Aug 19 20:27:01 PDT 2010


On Aug 19, 2010, at 6:40 PM, John McCall wrote:

> Author: rjmccall
> Date: Thu Aug 19 20:40:01 2010
> New Revision: 111609
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=111609&view=rev
> Log:
> Detect efforts to declare a template member friend and explicitly ignore them.
> Avoids a crash.

I had to revert this because the new test was failing on the buildbots.

	- Doug

> 
> Modified:
>    cfe/trunk/lib/Sema/SemaAccess.cpp
>    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>    cfe/trunk/lib/Sema/SemaTemplate.cpp
>    cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p5.cpp
> 
> Modified: cfe/trunk/lib/Sema/SemaAccess.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAccess.cpp?rev=111609&r1=111608&r2=111609&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaAccess.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaAccess.cpp Thu Aug 19 20:40:01 2010
> @@ -514,6 +514,9 @@
> static AccessResult MatchesFriend(Sema &S,
>                                   const EffectiveContext &EC,
>                                   FriendDecl *FriendD) {
> +  if (FriendD->isInvalidDecl())
> +    return AR_accessible;
> +
>   if (TypeSourceInfo *T = FriendD->getFriendType())
>     return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
> 
> 
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=111609&r1=111608&r2=111609&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Aug 19 20:40:01 2010
> @@ -6538,6 +6538,8 @@
>   FrD->setAccess(AS_public);
>   CurContext->addDecl(FrD);
> 
> +  if (ND->isInvalidDecl()) FrD->setInvalidDecl();
> +
>   return DeclPtrTy::make(ND);
> }
> 
> 
> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=111609&r1=111608&r2=111609&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Aug 19 20:40:01 2010
> @@ -1365,8 +1365,12 @@
>   // If there were at least as many template-ids as there were template
>   // parameter lists, then there are no template parameter lists remaining for
>   // the declaration itself.
> -  if (Idx >= NumParamLists)
> +  if (Idx >= NumParamLists) {
> +    // Silently drop template member friend declarations.
> +    // TODO: implement these
> +    if (IsFriend && NumParamLists) Invalid = true;
>     return 0;
> +  }
> 
>   // If there were too many template parameter lists, complain about that now.
>   if (Idx != NumParamLists - 1) {
> @@ -1395,6 +1399,11 @@
>     }
>   }
> 
> +  // Silently drop template member template friend declarations.
> +  // TODO: implement these
> +  if (IsFriend && NumParamLists > 1)
> +    Invalid = true;
> +
>   // Return the last template parameter list, which corresponds to the
>   // entity being declared.
>   return ParamLists[NumParamLists - 1];
> 
> Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p5.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p5.cpp?rev=111609&r1=111608&r2=111609&view=diff
> ==============================================================================
> --- cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p5.cpp (original)
> +++ cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p5.cpp Thu Aug 19 20:40:01 2010
> @@ -1,13 +1,58 @@
> // RUN: %clang_cc1 -fsyntax-only -verify %s
> 
> -template <class T> class A {
> -  class Member {
> +namespace test0 {
> +  template <class T> class A {
> +    class Member {};
>   };
> -};
> 
> -class B {
> -  template <class T> friend class A<T>::Member;
> -};
> +  class B {
> +    template <class T> friend class A<T>::Member;
> +  };
> +
> +  A<int> a;
> +  B b;
> +}
> +
> +// rdar://problem/8204127
> +namespace test1 {
> +  template <class T> struct A;
> +
> +  class C {
> +    static void foo();
> +    template <class T> friend void A<T>::f();
> +  };
> 
> -A<int> a;
> -B b;
> +  template <class T> struct A {
> +    void f() { C::foo(); }
> +  };
> +
> +  template <class T> struct A<T*> {
> +    void f() { C::foo(); }
> +  };
> +
> +  template <> struct A<char> {
> +    void f() { C::foo(); }
> +  };
> +}
> +
> +// FIXME: these should fail!
> +namespace test2 {
> +  template <class T> struct A;
> +
> +  class C {
> +    static void foo();
> +    template <class T> friend void A<T>::g();
> +  };
> +
> +  template <class T> struct A {
> +    void f() { C::foo(); }
> +  };
> +
> +  template <class T> struct A<T*> {
> +    void f() { C::foo(); }
> +  };
> +
> +  template <> struct A<char> {
> +    void f() { C::foo(); }
> +  };
> +}
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits





More information about the cfe-commits mailing list