]> granicus.if.org Git - clang/commitdiff
Workaround for friend template instantiation crash in PR5848, from Keir Mierle!
authorDouglas Gregor <dgregor@apple.com>
Sun, 7 Feb 2010 10:31:35 +0000 (10:31 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sun, 7 Feb 2010 10:31:35 +0000 (10:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95517 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaCXX/templated-friend-decl.cpp [new file with mode: 0644]

index 244b5f511b8db3cfa7ac1ef2dad50bce646a4efc..d7820bbc2e66ddf17a1500e0c1a5cacd11ef1317 100644 (file)
@@ -411,9 +411,17 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) {
     Decl *NewND;
 
     // Hack to make this work almost well pending a rewrite.
-    if (ND->getDeclContext()->isRecord())
-      NewND = SemaRef.FindInstantiatedDecl(ND, TemplateArgs);
-    else if (D->wasSpecialization()) {
+    if (ND->getDeclContext()->isRecord()) {
+      if (!ND->getDeclContext()->isDependentContext()) {
+        NewND = SemaRef.FindInstantiatedDecl(ND, TemplateArgs);
+      } else {
+        // FIXME: Hack to avoid crashing when incorrectly trying to instantiate
+        // templated friend declarations. This doesn't produce a correct AST;
+        // however this is sufficient for some AST analysis. The real solution
+        // must be put in place during the pending rewrite. See PR5848.
+        return 0;
+      }
+    } else if (D->wasSpecialization()) {
       // Totally egregious hack to work around PR5866
       return 0;
     } else
diff --git a/test/SemaCXX/templated-friend-decl.cpp b/test/SemaCXX/templated-friend-decl.cpp
new file mode 100644 (file)
index 0000000..c0034cd
--- /dev/null
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s
+
+template <typename T>
+struct Foo {
+  template <typename U>
+  struct Bar {};
+
+  // The templated declaration for class Bar should not be instantiated when
+  // Foo<int> is. This is to protect against PR5848; for now, this "parses" but
+  // requires a rewrite of the templated friend code to be properly fixed.
+  template <typename U>
+  friend struct Bar;
+};
+
+Foo<int> x;