Fix PR c++/37093
authordodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 2 Nov 2009 19:55:02 +0000 (19:55 +0000)
committerdodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 2 Nov 2009 19:55:02 +0000 (19:55 +0000)
gcc/cp/ChangeLog:

PR c++/37093
* pt.c (check_valid_ptrmem_cst_expr): New function.
(convert_nontype_argument): Use it to output an error for
illegal pointer to member expressions used as template arguments.

gcc/testsuite/ChangeLog:

PR c++/37093
* g++.dg/other/ptrmem10.C: New test.
* g++.dg/other/ptrmem11.C: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153822 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/ptrmem10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/ptrmem11.C [new file with mode: 0644]

index 1921f72..10fa16a 100644 (file)
@@ -1,3 +1,10 @@
+2009-11-02  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/37093
+       * pt.c (check_valid_ptrmem_cst_expr): New function.
+       (convert_nontype_argument): Use it to output an error for
+       illegal pointer to member expressions used as template arguments.
+
 2009-11-02  Jason Merrill  <jason@redhat.com>
 
        Restrict DR 757 change to C++0x mode.
index 2f0fa12..5af348a 100644 (file)
@@ -4686,6 +4686,22 @@ convert_nontype_argument_function (tree type, tree expr)
   return fn;
 }
 
+/* Subroutine of convert_nontype_argument.
+   Check if EXPR of type TYPE is a valid pointer-to-member constant.
+   Emit an error otherwise.  */
+
+static bool
+check_valid_ptrmem_cst_expr (tree type, tree expr)
+{
+  STRIP_NOPS (expr);
+  if (expr && (null_ptr_cst_p (expr) || TREE_CODE (expr) == PTRMEM_CST))
+    return true;
+  error ("%qE is not a valid template argument for type %qT",
+        expr, type);
+  error ("it must be a pointer-to-member of the form `&X::Y'");
+  return false;
+}
+
 /* Attempt to convert the non-type template parameter EXPR to the
    indicated TYPE.  If the conversion is successful, return the
    converted value.  If the conversion is unsuccessful, return
@@ -4985,6 +5001,11 @@ convert_nontype_argument (tree type, tree expr)
       if (expr == error_mark_node)
        return error_mark_node;
 
+      /* [temp.arg.nontype] bullet 1 says the pointer to member
+         expression must be a pointer-to-member constant.  */
+      if (!check_valid_ptrmem_cst_expr (type, expr))
+       return error_mark_node;
+
       /* There is no way to disable standard conversions in
         resolve_address_of_overloaded_function (called by
         instantiate_type). It is possible that the call succeeded by
@@ -5011,6 +5032,11 @@ convert_nontype_argument (tree type, tree expr)
      qualification conversions (_conv.qual_) are applied.  */
   else if (TYPE_PTRMEM_P (type))
     {
+      /* [temp.arg.nontype] bullet 1 says the pointer to member
+         expression must be a pointer-to-member constant.  */
+      if (!check_valid_ptrmem_cst_expr (type, expr))
+       return error_mark_node;
+
       expr = perform_qualification_conversions (type, expr);
       if (expr == error_mark_node)
        return expr;
index ace8f7e..cfc4a0a 100644 (file)
@@ -1,3 +1,9 @@
+2009-11-02  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/37093
+       * g++.dg/other/ptrmem10.C: New test.
+       * g++.dg/other/ptrmem11.C: Likewise.
+
 2009-11-02  Janis Johnson  <janis187@us.ibm.com>
 
        PR testsuite/41878
diff --git a/gcc/testsuite/g++.dg/other/ptrmem10.C b/gcc/testsuite/g++.dg/other/ptrmem10.C
new file mode 100644 (file)
index 0000000..4b8c40a
--- /dev/null
@@ -0,0 +1,29 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/37093
+
+template <class C, void (C::*M) ()>
+static
+void foo(void *obj)
+{
+  C *p = static_cast<C*>(obj);
+  (p->*M)();
+}
+
+template <class C>
+static void
+bar(C *c, void (C::*m) ())
+{
+  foo<C,m>((void *)c);// { dg-error "(not a valid template arg|pointer-to-member|no matching fun)" }
+}
+
+struct S
+{
+  void baz () {}
+};
+
+int
+main ()
+{
+  S a;
+  bar(&a, &S::baz);
+}
diff --git a/gcc/testsuite/g++.dg/other/ptrmem11.C b/gcc/testsuite/g++.dg/other/ptrmem11.C
new file mode 100644 (file)
index 0000000..a850c55
--- /dev/null
@@ -0,0 +1,21 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/37093
+
+struct A {};
+
+template <int A::* p>
+int
+foo(A* q)
+{
+  return q->*p;
+}
+
+template <typename T>
+int
+bar(int T::* p)
+{
+  return foo<p>(0);// { dg-error "(not a valid template arg|no matching func|pointer-to-member)" }
+}
+
+int i = bar<A>(0);
+