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]

[C++ PATCH] Fix bug 3416


Mark,
This fixes a 2.95 regression. We allowed unresolved overloaded
functions as _both_ choices of a conditional expr. This later
blows things up - in the PR's case during assoc_args. I don't think
we should allow unknown type expressions into decay_conversion, so
I now issue an error if they get there - that catches the conditional
expr bug. Some other places were calling decay_conversion and
default_conversion, expecting overloaded functions to pass through.
I fixed those to not expect that.

Interesting point that sort of caused this. same_type_p will accept
unknown_type_node which compares unequal to other types, but equal to
itself. Shouldn't it behave more like an IEEE infinity (different to
everything, including itself)?

booted & tested on i686-pc-linux-gnu, ok for mainline & branch?

nathan
-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2001-07-24  Nathan Sidwell  <nathan@codesourcery.com>

	* call.c (build_conditional_expr): Recheck args after
	conversions.
	* cp-tree.h (build_conditional_expr): Move to correct file.
	* typeck.c (decay_conversion): Diagnos any unknown types
	reaching here.
	(build_binary_op): Don't do initial decay or default
	conversions on overloaded functions.
	(build_static_cast): Don't do a decay conversion here.

Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.275
diff -c -3 -p -r1.275 call.c
*** call.c	2001/07/21 09:42:17	1.275
--- call.c	2001/07/24 16:17:12
*************** build_conditional_expr (arg1, arg2, arg3
*** 3092,3097 ****
--- 3092,3100 ----
      arg3 = decay_conversion (arg3);
    arg3_type = TREE_TYPE (arg3);
  
+   if (arg2 == error_mark_node || arg3 == error_mark_node)
+     return error_mark_node;
+   
    /* [expr.cond]
       
       After those conversions, one of the following shall hold:
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.630
diff -c -3 -p -r1.630 cp-tree.h
*** cp-tree.h	2001/07/24 08:56:11	1.630
--- cp-tree.h	2001/07/24 16:17:16
*************** extern int get_arglist_len_in_bytes		PAR
*** 3545,3550 ****
--- 3545,3551 ----
  
  extern tree build_vfield_ref			PARAMS ((tree, tree));
  extern tree build_scoped_method_call		PARAMS ((tree, tree, tree, tree));
+ extern tree build_conditional_expr		PARAMS ((tree, tree, tree));
  extern tree build_addr_func			PARAMS ((tree));
  extern tree build_call				PARAMS ((tree, tree));
  extern tree build_method_call			PARAMS ((tree, tree, tree, tree, int));
*************** extern tree build_x_binary_op			PARAMS (
*** 4305,4311 ****
  extern tree build_x_unary_op			PARAMS ((enum tree_code, tree));
  extern tree unary_complex_lvalue		PARAMS ((enum tree_code, tree));
  extern tree build_x_conditional_expr		PARAMS ((tree, tree, tree));
- extern tree build_conditional_expr		PARAMS ((tree, tree, tree));
  extern tree build_x_compound_expr		PARAMS ((tree));
  extern tree build_compound_expr			PARAMS ((tree));
  extern tree build_static_cast			PARAMS ((tree, tree));
--- 4306,4311 ----
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.359
diff -c -3 -p -r1.359 typeck.c
*** typeck.c	2001/07/21 09:42:18	1.359
--- typeck.c	2001/07/24 16:17:19
*************** decay_conversion (exp)
*** 1729,1734 ****
--- 1729,1740 ----
    if (type == error_mark_node)
      return error_mark_node;
  
+   if (type_unknown_p (exp))
+     {
+       incomplete_type_error (exp, TREE_TYPE (exp));
+       return error_mark_node;
+     }
+   
    /* Constants can be used directly unless they're not loadable.  */
    if (TREE_CODE (exp) == CONST_DECL)
      exp = DECL_INITIAL (exp);
*************** build_binary_op (code, orig_op0, orig_op
*** 3365,3381 ****
    int common = 0;
  
    /* Apply default conversions.  */
    if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
        || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
        || code == TRUTH_XOR_EXPR)
      {
!       op0 = decay_conversion (orig_op0);
!       op1 = decay_conversion (orig_op1);
      }
    else
      {
!       op0 = default_conversion (orig_op0);
!       op1 = default_conversion (orig_op1);
      }
  
    /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
--- 3371,3394 ----
    int common = 0;
  
    /* Apply default conversions.  */
+   op0 = orig_op0;
+   op1 = orig_op1;
+   
    if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
        || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
        || code == TRUTH_XOR_EXPR)
      {
!       if (!really_overloaded_fn (op0))
! 	op0 = decay_conversion (op0);
!       if (!really_overloaded_fn (op1))
! 	op1 = decay_conversion (op1);
      }
    else
      {
!       if (!really_overloaded_fn (op0))
! 	op0 = default_conversion (op0);
!       if (!really_overloaded_fn (op1))
! 	op1 = default_conversion (op1);
      }
  
    /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
*************** build_static_cast (type, expr)
*** 5098,5104 ****
  				    build_tree_list (NULL_TREE, expr),
  				    TYPE_BINFO (type), LOOKUP_NORMAL)));
    
-   expr = decay_conversion (expr);
    intype = TREE_TYPE (expr);
  
    /* FIXME handle casting to array type.  */
--- 5111,5116 ----
// Build don't link:
// 
// Copyright (C) 2001 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 24 Jul 2001 <nathan@codesourcery.com>

// Bug 3416. We left some unchecked overloaded functions lying around.

struct X
{
  void operator << (int);
  void operator << (float);
};

void OVL1 (int);
void OVL1 (float);

void OVL2 (int);
void OVL2 (float);

X x;

void foo (bool a)
{
  x << (a ? OVL1 : OVL2);	// ERROR - incomplete type
  a ? OVL1 : OVL2;              // ERROR - incomplete type
}

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