]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/69323 - errors
authorJason Merrill <jason@redhat.com>
Wed, 24 Feb 2016 19:56:09 +0000 (14:56 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 24 Feb 2016 19:56:09 +0000 (14:56 -0500)
* friend.c (make_friend_class): Likewise.
* decl.c (lookup_and_check_tag): Diagnose invalid dependent friend.

From-SVN: r233682

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/friend.c
gcc/testsuite/g++.dg/template/crash34.C
gcc/testsuite/g++.dg/template/friend61a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/friend61b.C [new file with mode: 0644]

index 8fe43069e737f306f4c991df8f84521f868a210c..897c28fe4ff1ac6fc2c48bd4de092d0ea87c5876 100644 (file)
@@ -1,3 +1,9 @@
+2016-02-24  Jason Merrill  <jason@redhat.com>
+
+       PR c++/69323
+       * friend.c (make_friend_class): Likewise.
+       * decl.c (lookup_and_check_tag): Diagnose invalid dependent friend.
+
 2016-02-24  Jason Merrill  <jason@redhat.com>
 
        PR c++/69323
index 2df3398d6c03e2d8a0c9ffb507a6f32c06b2c6f7..5ec65892e68df0e30499612dc2be45e9ed32978d 100644 (file)
@@ -12590,6 +12590,20 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
                                           decl,
                                           template_header_p
                                           | DECL_SELF_REFERENCE_P (decl));
+      if (template_header_p && t && CLASS_TYPE_P (t)
+         && (!CLASSTYPE_TEMPLATE_INFO (t)
+             || (!PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))))
+       {
+         error ("%qT is not a template", t);
+         inform (location_of (t), "previous declaration here");
+         if (TYPE_CLASS_SCOPE_P (t)
+             && CLASSTYPE_TEMPLATE_INFO (TYPE_CONTEXT (t)))
+           inform (input_location,
+                   "perhaps you want to explicitly add %<%T::%>",
+                   TYPE_CONTEXT (t));
+         t = error_mark_node;
+       }
+
       return t;
     }
   else if (decl && TREE_CODE (decl) == TREE_LIST)
index 36b000fb34ec55e45f76b53e5c0fd21eec361577..5e4b2d18bf74dfa8dd25da8457a168d2e3c2f8f5 100644 (file)
@@ -255,6 +255,18 @@ make_friend_class (tree type, tree friend_type, bool complain)
                 friend_type);
          return;
        }
+      if (TYPE_TEMPLATE_INFO (friend_type)
+         && !PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (friend_type)))
+       {
+         error ("%qT is not a template", friend_type);
+         inform (location_of (friend_type), "previous declaration here");
+         if (TYPE_CLASS_SCOPE_P (friend_type)
+             && CLASSTYPE_TEMPLATE_INFO (TYPE_CONTEXT (friend_type))
+             && currently_open_class (TYPE_CONTEXT (friend_type)))
+           inform (input_location, "perhaps you need explicit template "
+                   "arguments in your nested-name-specifier");
+         return;
+       }
     }
   else if (same_type_p (type, friend_type))
     {
index ef4d21b60d84749967456d85763b05394c3efd15..83dcc78f37fe041c1c8aef5c1cdf7be7131f6053 100644 (file)
@@ -7,6 +7,6 @@
 
 class Foo;
 
-template <typename T> class Foo { }; // { dg-error "not a template type" }
+template <typename T> class Foo { }; // { dg-error "not a template" }
 
 Foo<int> x; // { dg-error "not a template|incomplete type" }
diff --git a/gcc/testsuite/g++.dg/template/friend61a.C b/gcc/testsuite/g++.dg/template/friend61a.C
new file mode 100644 (file)
index 0000000..d38e53a
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/69323
+
+template<int VALUE>
+struct Outer
+{
+  struct StupidValueTrick
+  {
+    template<int VAL> friend struct StupidValueTrick; // { dg-error "not a template" }
+  };
+};
+typedef Outer<42>::StupidValueTrick GoodValue;
+GoodValue good;
diff --git a/gcc/testsuite/g++.dg/template/friend61b.C b/gcc/testsuite/g++.dg/template/friend61b.C
new file mode 100644 (file)
index 0000000..2da5d60
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/69323
+
+template<int VALUE>
+struct Outer
+{
+  struct StupidValueTrick
+  {
+    template<int VAL> friend struct Outer::StupidValueTrick; // { dg-error "not a template" }
+  };
+};
+typedef Outer<42>::StupidValueTrick GoodValue;
+GoodValue good;