[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
John McCall
rjmccall at apple.com
Thu Aug 19 18:40:01 PDT 2010
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.
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(); }
+ };
+}
More information about the cfe-commits
mailing list