pt.c (convert_nontype_argument): Don't create things that aren't PTRMEM_CSTs when...
authorMark Mitchell <mark@codesourcery.com>
Tue, 23 Mar 1999 16:13:44 +0000 (16:13 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 23 Mar 1999 16:13:44 +0000 (16:13 +0000)
* pt.c (convert_nontype_argument): Don't create things that aren't
PTRMEM_CSTs when applying a qualification conversion to a
PTRMEM_CST.

From-SVN: r25929

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.pt/ptrmem7.C [new file with mode: 0644]

index e189f6db7b23526a08ace142b36931e21829bc83..3bac892ca8e576de998086079a6eef16979cf770 100644 (file)
@@ -1,3 +1,9 @@
+1999-03-23  Mark Mitchell  <mark@codesourcery.com>
+
+       * pt.c (convert_nontype_argument): Don't create things that aren't
+       PTRMEM_CSTs when applying a qualification conversion to a
+       PTRMEM_CST.
+
 1999-03-23  Mark Mitchell  <mark@codesourcery.com>
 
        * Makefile.in (OBJS): Don't mention hash.o.
index 38e317c5468cd76284fcee29cf9c7c0515d4c6c6..aa8c9e99c102deebfb85b9563cf7875cf4f74655 100644 (file)
@@ -2703,10 +2703,28 @@ convert_nontype_argument (type, expr)
        tree type_pointed_to = TREE_TYPE (type);
  
        if (TYPE_PTRMEM_P (type))
-         /* For a non-type template-parameter of type pointer to data
-            member, qualification conversions (_conv.qual_) are
-            applied.  */
-         return perform_qualification_conversions (type, expr);
+         {
+           tree e;
+
+           /* For a non-type template-parameter of type pointer to data
+              member, qualification conversions (_conv.qual_) are
+              applied.  */
+           e = perform_qualification_conversions (type, expr);
+           if (TREE_CODE (e) == NOP_EXPR)
+             {
+               /* The call to perform_qualification_conversions will
+                  insert a NOP_EXPR over EXPR to do express
+                  conversion, if necessary.  But, that will confuse
+                  us if we use this (converted) template parameter to
+                  instantiate another template; then the thing will
+                  not look like a valid template argument.  So, just
+                  make a new constant, of the appropriate type.  */
+               e = make_node (PTRMEM_CST);
+               TREE_TYPE (e) = type;
+               PTRMEM_CST_MEMBER (e) = PTRMEM_CST_MEMBER (expr);
+             }
+           return e;
+         }
        else if (TREE_CODE (type_pointed_to) == FUNCTION_TYPE)
          { 
            /* For a non-type template-parameter of type pointer to
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem7.C b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem7.C
new file mode 100644 (file)
index 0000000..4c01056
--- /dev/null
@@ -0,0 +1,21 @@
+// Build don't link:
+// Origin: Jason Merrill <jason@cygnus.com>
+
+struct A
+{
+  A() : x(123) { }
+  int x;
+};
+A a;
+
+template<const int A::*PX>
+struct B
+{
+  static int g() { return a.*PX; }
+};
+
+
+int main(int argc, char *argv[])
+{
+  int n = B<&A::x>::g();
+}