diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
| -rw-r--r-- | gcc/cp/mangle.c | 19 | ||||
| -rw-r--r-- | gcc/testsuite/g++.dg/template/non-type1.C | 49 | 
3 files changed, 64 insertions, 10 deletions
| diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 632a257..94682bc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 623fc3d..a71cc00 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -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 index 0000000..70e81d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-type1.C @@ -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 ); +} | 
