re PR c++/4377 (more errors with multiple non-type template parameters)
authorJason Merrill <jason@redhat.com>
Mon, 18 Mar 2002 13:38:00 +0000 (08:38 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 18 Mar 2002 13:38:00 +0000 (08:38 -0500)
        PR c++/4377
        * mangle.c (write_expression): Strip NOP_EXPRs sooner.  Also strip
        NON_LVALUE_EXPRs.

From-SVN: r50967

gcc/cp/ChangeLog
gcc/cp/mangle.c
gcc/testsuite/g++.dg/template/non-type1.C [new file with mode: 0644]

index 632a25726a8d8a96446062a897599d6276f58db5..94682bcf31735bf99c33ce3f507d9e4611c31376 100644 (file)
@@ -1,6 +1,10 @@
 2002-03-18  Jason Merrill  <jason@redhat.com>
 
-       PR c++/4003 - template/friend.C
+       PR c++/4377
+       * mangle.c (write_expression): Strip NOP_EXPRs sooner.  Also strip
+       NON_LVALUE_EXPRs.
+
+       PR c++/4003
        * pt.c (tsubst_friend_function): Use decl_namespace_context.
 
        PR c++/3948 -- C++ ABI change, followup to 2001-12-18 patch.
index 623fc3d35044808ba26733a0ed56550e28d6d911..a71cc006525709850010cbcf419b3bc43b938e9c 100644 (file)
@@ -1788,6 +1788,16 @@ write_expression (expr)
       code = TREE_CODE (expr);
     }
 
+  /* Skip NOP_EXPRs.  They can occur when (say) a pointer argument
+     is converted (via qualification conversions) to another
+     type.  */
+  while (TREE_CODE (expr) == NOP_EXPR
+        || TREE_CODE (expr) == NON_LVALUE_EXPR)
+    {
+      expr = TREE_OPERAND (expr, 0);
+      code = TREE_CODE (expr);
+    }
+
   /* Handle template parameters. */
   if (code == TEMPLATE_TYPE_PARM 
       || code == TEMPLATE_TEMPLATE_PARM
@@ -1807,15 +1817,6 @@ write_expression (expr)
     {
       int i;
 
-      /* Skip NOP_EXPRs.  They can occur when (say) a pointer argument
-        is converted (via qualification conversions) to another
-        type.  */
-      while (TREE_CODE (expr) == NOP_EXPR)
-       {
-         expr = TREE_OPERAND (expr, 0);
-         code = TREE_CODE (expr);
-       }
-
       /* When we bind a variable or function to a non-type template
         argument with reference type, we create an ADDR_EXPR to show
         the fact that the entity's address has been taken.  But, we
diff --git a/gcc/testsuite/g++.dg/template/non-type1.C b/gcc/testsuite/g++.dg/template/non-type1.C
new file mode 100644 (file)
index 0000000..70e81d3
--- /dev/null
@@ -0,0 +1,49 @@
+// PR c++/4377
+
+template < int I1, int I2 >
+class unit
+{
+public:
+  typedef unit<I1,I2> my_type;
+
+  unit() {}
+  unit( const unit<I1,I2>& ) {}
+
+   template< int Q1, int Q2 >
+   unit< I1 + Q1, I2 + Q2 > operator * ( const unit< Q1, Q2 >& rhs ) const {
+     return unit< I1 + Q1, I2 + Q2 >();
+   }
+  template< int Q1, int Q2 >
+  unit< I1 - Q1, I2 - Q2 > operator / ( const unit< Q1, Q2 >& rhs ) const {
+    return unit< I1 - Q1, I2 - Q2 >();
+  }
+};
+
+// specialization added to first test
+//
+template <>
+class unit<0,0> {
+public:
+  typedef unit<0,0> my_type;
+
+  unit() {}
+  
+   friend unit<0,0> operator*( const unit<0,0>& lhs, const unit<0,0>& rhs ) {
+     return unit<0,0>();
+   }
+   friend unit<0,0> operator/( const unit<0,0>& lhs, const unit<0,0>& rhs ) {
+     return unit<0,0>();
+   }
+
+};
+
+
+int main()
+{
+  const unit<1,0> u1;
+  const unit<2,0> u2;
+  unit<-1,0> u3( u1 / u2 );
+  unit< 3,0> u4( u1 * u2 );
+}