[cfe-commits] r130772 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Parse/ParseDeclCXX.cpp lib/Sema/SemaDecl.cpp test/CXX/temp/temp.decls/temp.friend/p3.cpp test/SemaTemplate/friend-template.cpp

Chandler Carruth chandlerc at gmail.com
Tue May 3 11:35:10 PDT 2011


Author: chandlerc
Date: Tue May  3 13:35:10 2011
New Revision: 130772

URL: http://llvm.org/viewvc/llvm-project?rev=130772&view=rev
Log:
When parsing a template friend declaration we dropped the template
parameters on the floor in certain cases:
class X {
  template <typename T> friend typename A<T>::Foo;
};

This was parsed as a *non* template friend declaration some how, and
received an ExtWarn. Fixing the parser to actually provide the template
parameters to the freestanding declaration parse triggers the code which
specifically looks for such constructs and hard errors on them.

Along the way, this prevents us from trying to instantiate constructs
like the above inside of a outer template. This is important as loosing
the template parameters means we don't have a well formed declaration
and template instantiation will be unable to rebuild the AST. That fixes
a crash in the GCC test suite.

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p3.cpp
    cfe/trunk/test/SemaTemplate/friend-template.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=130772&r1=130771&r2=130772&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue May  3 13:35:10 2011
@@ -1026,10 +1026,11 @@
   void ActOnPopScope(SourceLocation Loc, Scope *S);
   void ActOnTranslationUnitScope(Scope *S);
 
-  /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
-  /// no declarator (e.g. "struct foo;") is parsed.
   Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
                                    DeclSpec &DS);
+  Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
+                                   DeclSpec &DS,
+                                   MultiTemplateParamsArg TemplateParams);
   
   StmtResult ActOnVlaStmt(const DeclSpec &DS);
 

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=130772&r1=130771&r2=130772&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue May  3 13:35:10 2011
@@ -1547,7 +1547,7 @@
   if (Tok.is(tok::semi)) {
     ConsumeToken();
     Decl *TheDecl =
-      Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS);
+      Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS, TemplateParams);
     DS.complete(TheDecl);
     return;
   }

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=130772&r1=130771&r2=130772&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue May  3 13:35:10 2011
@@ -2132,6 +2132,16 @@
 /// no declarator (e.g. "struct foo;") is parsed.
 Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
                                        DeclSpec &DS) {
+  return ParsedFreeStandingDeclSpec(S, AS, DS,
+                                    MultiTemplateParamsArg(*this, 0, 0));
+}
+
+/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
+/// no declarator (e.g. "struct foo;") is parsed. It also accopts template
+/// parameters to cope with template friend declarations.
+Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
+                                       DeclSpec &DS,
+                                       MultiTemplateParamsArg TemplateParams) {
   Decl *TagD = 0;
   TagDecl *Tag = 0;
   if (DS.getTypeSpecType() == DeclSpec::TST_class ||
@@ -2163,7 +2173,7 @@
     // whatever routines created it handled the friendship aspect.
     if (TagD && !Tag)
       return 0;
-    return ActOnFriendTypeDecl(S, DS, MultiTemplateParamsArg(*this, 0, 0));
+    return ActOnFriendTypeDecl(S, DS, TemplateParams);
   }
 
   // Track whether we warned about the fact that there aren't any

Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p3.cpp?rev=130772&r1=130771&r2=130772&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p3.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p3.cpp Tue May  3 13:35:10 2011
@@ -8,5 +8,5 @@
   template <class T> friend class A;
   template <class T> friend class Undeclared;
   
-  template <class T> friend typename A<T>::Member; // expected-warning {{non-class type 'typename A<T>::Member' cannot be a friend}}
+  template <class T> friend typename A<T>::Member; // expected-error {{friend type templates must use an elaborated type}}
 };

Modified: cfe/trunk/test/SemaTemplate/friend-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/friend-template.cpp?rev=130772&r1=130771&r2=130772&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/friend-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/friend-template.cpp Tue May  3 13:35:10 2011
@@ -216,3 +216,11 @@
 
   X<int, float, 7> x;
 }
+
+// Don't crash, and error on invalid friend type template.
+namespace friend_type_template_no_tag {
+  template <typename T> struct S {
+    template <typename U> friend S<U>; // expected-error{{friend type templates must use an elaborated type}}
+  };
+  template struct S<int>;
+}





More information about the cfe-commits mailing list