This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR 11962


PR c++/11962 is yet another PR caused by ill-advised extensions; this
time, the fact that G++ permits the omission of the second operand to
a conditional.

There were two bugs here:

(1) In templates, we didn't handle computations of type-dependency
    correctly, and

(2) We crashed when trying to mangle such an expression.

I fixed (1) and made (2) an error.  There's just no reason spending
any effort trying to think about how to mangle these expressions; it
would be better to spend the same time arguing for the removal of the
extension.

Tested on i686-pc-linux-gnu, applied on the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-10-21  Mark Mitchell  <mark@codesourcery.com>

	PR c++/11962
	* typeck.c (build_x_conditional_expr): Handle missing middle
	operands in templates.
	* mangle.c (write_expression): Issue errors about attempts to
	mangle a non-existant middle operator to the ?: operator.

2003-10-21  Mark Mitchell  <mark@codesourcery.com>

	PR c++/11962
	* g++.dg/template/cond2.C: New test.

Index: cp/mangle.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/mangle.c,v
retrieving revision 1.87
diff -c -5 -p -r1.87 mangle.c
*** cp/mangle.c	21 Oct 2003 02:16:13 -0000	1.87
--- cp/mangle.c	21 Oct 2003 23:40:25 -0000
*************** write_expression (tree expr)
*** 2039,2049 ****
  	    }
  	  break;
  
  	default:
  	  for (i = 0; i < TREE_CODE_LENGTH (code); ++i)
! 	    write_expression (TREE_OPERAND (expr, i));
  	}
      }
  }
  
  /* Literal subcase of non-terminal <template-arg>.  
--- 2039,2063 ----
  	    }
  	  break;
  
  	default:
  	  for (i = 0; i < TREE_CODE_LENGTH (code); ++i)
! 	    {
! 	      tree operand = TREE_OPERAND (expr, i);
! 	      /* As a GNU expression, the middle operand of a
! 		 conditional may be omitted.  Since expression
! 		 manglings are supposed to represent the input token
! 		 stream, there's no good way to mangle such an
! 		 expression without extending the C++ ABI.  */
! 	      if (code == COND_EXPR && i == 1 && !operand)
! 		{
! 		  error ("omitted middle operand to `?:' operand "
! 			 "cannot be mangled");
! 		  continue;
! 		}
! 	      write_expression (operand);
! 	    }
  	}
      }
  }
  
  /* Literal subcase of non-terminal <template-arg>.  
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.508
diff -c -5 -p -r1.508 typeck.c
*** cp/typeck.c	21 Oct 2003 02:16:17 -0000	1.508
--- cp/typeck.c	21 Oct 2003 23:40:28 -0000
*************** build_x_conditional_expr (tree ifexp, tr
*** 4282,4296 ****
      {
        /* The standard says that the expression is type-dependent if
  	 IFEXP is type-dependent, even though the eventual type of the
  	 expression doesn't dependent on IFEXP.  */
        if (type_dependent_expression_p (ifexp)
! 	  || type_dependent_expression_p (op1)
  	  || type_dependent_expression_p (op2))
  	return build_min_nt (COND_EXPR, ifexp, op1, op2);
        ifexp = build_non_dependent_expr (ifexp);
!       op1 = build_non_dependent_expr (op1);
        op2 = build_non_dependent_expr (op2);
      }
  
    expr = build_conditional_expr (ifexp, op1, op2);
    if (processing_template_decl && expr != error_mark_node)
--- 4282,4298 ----
      {
        /* The standard says that the expression is type-dependent if
  	 IFEXP is type-dependent, even though the eventual type of the
  	 expression doesn't dependent on IFEXP.  */
        if (type_dependent_expression_p (ifexp)
! 	  /* As a GNU extension, the middle operand may be omitted.  */
! 	  || (op1 && type_dependent_expression_p (op1))
  	  || type_dependent_expression_p (op2))
  	return build_min_nt (COND_EXPR, ifexp, op1, op2);
        ifexp = build_non_dependent_expr (ifexp);
!       if (op1)
! 	op1 = build_non_dependent_expr (op1);
        op2 = build_non_dependent_expr (op2);
      }
  
    expr = build_conditional_expr (ifexp, op1, op2);
    if (processing_template_decl && expr != error_mark_node)
Index: testsuite/g++.dg/template/cond2.C
===================================================================
RCS file: testsuite/g++.dg/template/cond2.C
diff -N testsuite/g++.dg/template/cond2.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/cond2.C	21 Oct 2003 23:40:35 -0000
***************
*** 0 ****
--- 1,10 ----
+ // PR c++/11962
+ // { dg-options "" }
+ 
+ template<int X> class c;
+ 
+ template<int X, int Y> int test(c<X ? : Y>&);
+ 
+ void test(c<2>*c2) {
+ 	test<0, 2>(*c2); // { dg-error "omitted" }
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]