(C++) small patches

Jason Merrill jason@cygnus.com
Mon Apr 10 17:37:00 GMT 2000


Fixing various Perennial failures.

2000-04-10  Jason Merrill  <jason@casey.cygnus.com>

	* class.c (instantiate_type): Handle object-relative template-id.
To avoid crashing on 'void (A::*p)() = f<int>;'

	* semantics.c (finish_expr_stmt): Call convert_to_void here.
	* decl.c (cplus_expand_expr_stmt): Not here.
So we complain properly for functions that aren't expanded.

	* rtti.c (build_dynamic_cast_1): Call non_lvalue.
	Initialize exprtype earlier.
So dynamic_cast to a pointer type is never an lvalue.

	* parse.y (fn.def1): Check for defining types in return types.

	* decl.c (check_tag_decl): Notice extra fundamental types.
	Diagnose empty decls in classes, too.

	* decl.c (grokdeclarator): Don't override an anonymous name if no 
	declarator was given.
Don't crash on 'typedef class {};'.

	* cvt.c (convert_to_void): Call resolve_offset_ref.

	* typeck.c (build_x_function_call): Abort if we get an OFFSET_REF.
We currently don't.

	* decl2.c (decl_namespace): Handle getting a type.

	* typeck.c (build_c_cast): Re-enable warning for cast between
	pointer and integer of different size.

Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.285
diff -c -p -r1.285 class.c
*** class.c	2000/04/04 18:13:19	1.285
--- class.c	2000/04/10 21:40:51
*************** resolve_address_of_overloaded_function (
*** 5441,5446 ****
--- 5441,5449 ----
  			&& (TREE_CODE (TREE_TYPE (target_type)) 
  			    == METHOD_TYPE)), 0);
  
+   if (TREE_CODE (overload) == COMPONENT_REF)
+     overload = TREE_OPERAND (overload, 1);
+ 
    /* Check that the TARGET_TYPE is reasonable.  */
    if (TYPE_PTRFN_P (target_type))
      /* This is OK.  */
*************** instantiate_type (lhstype, rhs, flags)
*** 5650,5655 ****
--- 5653,5659 ----
  {
    int complain = (flags & 1);
    int strict = (flags & 2) ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT;
+   tree r;
  
    if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
      {
*************** instantiate_type (lhstype, rhs, flags)
*** 5710,5717 ****
  
      case COMPONENT_REF:
        {
! 	tree r = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
  
  	if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype)
  	    && complain && !flag_ms_extensions)
  	  {
--- 5714,5722 ----
  
      case COMPONENT_REF:
        {
! 	r = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
  
+       comp:
  	if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype)
  	    && complain && !flag_ms_extensions)
  	  {
*************** instantiate_type (lhstype, rhs, flags)
*** 5746,5757 ****
        /* Fall through.  */
  
      case TEMPLATE_ID_EXPR:
!       return 
! 	resolve_address_of_overloaded_function (lhstype,
! 						TREE_OPERAND (rhs, 0),
! 						complain,
! 						/*template_only=*/1,
! 						TREE_OPERAND (rhs, 1));
  
      case OVERLOAD:
        return 
--- 5751,5773 ----
        /* Fall through.  */
  
      case TEMPLATE_ID_EXPR:
!       {
! 	tree fns = TREE_OPERAND (rhs, 0);
! 	tree args = TREE_OPERAND (rhs, 1);
! 
! 	r =
! 	  resolve_address_of_overloaded_function (lhstype,
! 						  fns,
! 						  complain,
! 						  /*template_only=*/1,
! 						  args);
! 	if (TREE_CODE (fns) == COMPONENT_REF)
! 	  {
! 	    rhs = fns;
! 	    goto comp;
! 	  }
! 	return r;
!       }
  
      case OVERLOAD:
        return 
Index: cvt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cvt.c,v
retrieving revision 1.79
diff -c -p -r1.79 cvt.c
*** cvt.c	2000/03/21 18:10:42	1.79
--- cvt.c	2000/04/10 21:40:52
*************** convert_to_void (expr, implicit)
*** 927,933 ****
                        expr, type, implicit ? implicit : "void context");
          break;
        }
!     
      default:;
      }
    {
--- 927,937 ----
                        expr, type, implicit ? implicit : "void context");
          break;
        }
! 
!     case OFFSET_REF:
!       expr = resolve_offset_ref (expr);
!       break;
! 
      default:;
      }
    {
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.581
diff -c -p -r1.581 decl.c
*** decl.c	2000/04/06 16:30:44	1.581
--- decl.c	2000/04/10 21:41:02
*************** check_tag_decl (declspecs)
*** 6753,6758 ****
--- 6753,6759 ----
       tree declspecs;
  {
    int found_type = 0;
+   int saw_friend = 0;
    tree ob_modifier = NULL_TREE;
    register tree link;
    register tree t = NULL_TREE;
*************** check_tag_decl (declspecs)
*** 6761,6767 ****
      {
        register tree value = TREE_VALUE (link);
  
!       if (TYPE_P (value))
  	{
  	  ++found_type;
  
--- 6762,6771 ----
      {
        register tree value = TREE_VALUE (link);
  
!       if (TYPE_P (value)
! 	  || (TREE_CODE (value) == IDENTIFIER_NODE
! 	      && IDENTIFIER_GLOBAL_VALUE (value)
! 	      && TYPE_P (IDENTIFIER_GLOBAL_VALUE (value))))
  	{
  	  ++found_type;
  
*************** check_tag_decl (declspecs)
*** 6776,6781 ****
--- 6780,6787 ----
  	  if (current_class_type == NULL_TREE
  	      || current_scope () != current_class_type)
  	    ob_modifier = value;
+ 	  else
+ 	    saw_friend = 1;
  	}
        else if (value == ridpointers[(int) RID_STATIC]
  	       || value == ridpointers[(int) RID_EXTERN]
*************** check_tag_decl (declspecs)
*** 6792,6800 ****
    if (found_type > 1)
      error ("multiple types in one declaration");
  
!   /* Inside a class, we might be in a friend or access declaration.
!      Until we have a good way of detecting the latter, don't warn.  */
!   if (t == NULL_TREE && ! current_class_type)
      pedwarn ("declaration does not declare anything");
  
    /* Check for an anonymous union.  We're careful
--- 6798,6804 ----
    if (found_type > 1)
      error ("multiple types in one declaration");
  
!   if (t == NULL_TREE && ! saw_friend)
      pedwarn ("declaration does not declare anything");
  
    /* Check for an anonymous union.  We're careful
*************** grokdeclarator (declarator, declspecs, d
*** 10876,10881 ****
--- 10880,10886 ----
  	 Nothing can refer to it, so nothing needs know about the name
  	 change.  */
        if (type != error_mark_node
+ 	  && declarator
  	  && TYPE_NAME (type)
  	  && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
  	  && ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))
*************** void
*** 14549,14557 ****
  cplus_expand_expr_stmt (exp)
       tree exp;
  {
-   if (stmts_are_full_exprs_p)
-     exp = convert_to_void (exp, "statement");
- 
  #if 0
    /* We should do this eventually, but right now this causes regex.o from
       libg++ to miscompile, and tString to core dump.  */
--- 14554,14559 ----
Index: decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.327
diff -c -p -r1.327 decl2.c
*** decl2.c	2000/04/06 16:30:44	1.327
--- decl2.c	2000/04/10 21:41:05
*************** static tree
*** 4473,4478 ****
--- 4473,4480 ----
  decl_namespace (decl)
       tree decl;
  {
+   if (TYPE_P (decl))
+     decl = TYPE_STUB_DECL (decl);
    while (DECL_CONTEXT (decl))
      {
        decl = DECL_CONTEXT (decl);
Index: parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/parse.y,v
retrieving revision 1.171
diff -c -p -r1.171 parse.y
*** parse.y	2000/03/23 00:41:04	1.171
--- parse.y	2000/04/10 21:41:12
*************** constructor_declarator:
*** 776,782 ****
  
  fn.def1:
  	  typed_declspecs declarator
! 		{ if (!begin_function_definition ($1.t, $2))
  		    YYERROR1; }
  	| declmods notype_declarator
  		{ if (!begin_function_definition ($1.t, $2))
--- 776,783 ----
  
  fn.def1:
  	  typed_declspecs declarator
! 		{ check_for_new_type ("return type", $1);
! 		  if (!begin_function_definition ($1.t, $2))
  		    YYERROR1; }
  	| declmods notype_declarator
  		{ if (!begin_function_definition ($1.t, $2))
Index: rtti.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/rtti.c,v
retrieving revision 1.83
diff -c -p -r1.83 rtti.c
*** rtti.c	2000/04/06 16:30:45	1.83
--- rtti.c	2000/04/10 21:41:14
*************** build_dynamic_cast_1 (type, expr)
*** 558,564 ****
       tree type, expr;
  {
    enum tree_code tc = TREE_CODE (type);
!   tree exprtype;
    tree dcast_fn;
    tree old_expr = expr;
    const char *errstr = NULL;
--- 558,564 ----
       tree type, expr;
  {
    enum tree_code tc = TREE_CODE (type);
!   tree exprtype = TREE_TYPE (expr);
    tree dcast_fn;
    tree old_expr = expr;
    const char *errstr = NULL;
*************** build_dynamic_cast_1 (type, expr)
*** 589,598 ****
      }
  
    if (TREE_CODE (expr) == OFFSET_REF)
!     expr = resolve_offset_ref (expr);
! 
!   exprtype = TREE_TYPE (expr);
!   assert (exprtype != NULL_TREE);
  
    if (tc == POINTER_TYPE)
      expr = convert_from_reference (expr);
--- 589,598 ----
      }
  
    if (TREE_CODE (expr) == OFFSET_REF)
!     {
!       expr = resolve_offset_ref (expr);
!       exprtype = TREE_TYPE (expr);
!     }
  
    if (tc == POINTER_TYPE)
      expr = convert_from_reference (expr);
*************** build_dynamic_cast_1 (type, expr)
*** 676,682 ****
        }
  
      if (distance >= 0)
!       return build_vbase_path (PLUS_EXPR, type, expr, path, 0);
    }
  
    /* Otherwise *exprtype must be a polymorphic class (have a vtbl).  */
--- 676,687 ----
        }
  
      if (distance >= 0)
!       {
! 	expr = build_vbase_path (PLUS_EXPR, type, expr, path, 0);
! 	if (TREE_CODE (exprtype) == POINTER_TYPE)
! 	  expr = non_lvalue (expr);
! 	return expr;
!       }
    }
  
    /* Otherwise *exprtype must be a polymorphic class (have a vtbl).  */
Index: semantics.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/semantics.c,v
retrieving revision 1.134
diff -c -p -r1.134 semantics.c
*** semantics.c	2000/04/06 16:30:45	1.134
--- semantics.c	2000/04/10 21:41:15
*************** finish_expr_stmt (expr)
*** 141,146 ****
--- 141,149 ----
  		  || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE))
  	    expr = default_conversion (expr);
  
+ 	  if (stmts_are_full_exprs_p)
+ 	    expr = convert_to_void (expr, "statement");
+ 
  	  if (!processing_template_decl)
  	    expr = break_out_cleanups (expr);
  
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.272
diff -c -p -r1.272 typeck.c
*** typeck.c	2000/03/27 01:26:18	1.272
--- typeck.c	2000/04/10 21:41:20
*************** build_x_function_call (function, params,
*** 2669,2674 ****
--- 2669,2676 ----
        return build_method_call (decl, function, params,
  				NULL_TREE, LOOKUP_NORMAL);
      }
+   else if (TREE_CODE (function) == OFFSET_REF)
+     my_friendly_abort (20000406);
    else if (TREE_CODE (function) == COMPONENT_REF
  	   && type == unknown_type_node)
      {
*************** build_c_cast (type, expr)
*** 5476,5484 ****
      cp_warning ("cast from `%T' to `%T' discards qualifiers from pointer target type",
                  otype, type);
  
- #if 0
-   /* We should see about re-enabling these, they seem useful to
-      me.  */
    if (TREE_CODE (type) == INTEGER_TYPE
        && TREE_CODE (otype) == POINTER_TYPE
        && TYPE_PRECISION (type) != TYPE_PRECISION (otype))
--- 5478,5483 ----
*************** build_c_cast (type, expr)
*** 5491,5497 ****
  	 provided the 0 was explicit--not cast or made by folding.  */
        && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value)))
      warning ("cast to pointer from integer of different size");
- #endif
  
    if (TREE_CODE (type) == REFERENCE_TYPE)
      value = (convert_from_reference
--- 5490,5495 ----


More information about the Gcc-patches mailing list