Patch for internal error with static_cast and templates

Mark Mitchell mmitchell@usa.net
Sun Dec 7 14:58:00 GMT 1997


Carl --

  On 11/13 you reported an internal error on code like this:

    template <class InputIterator, class BinaryOperation>
    void accumulate(InputIterator first, 
		     BinaryOperation binary_op) {
    }


    template<class R> int p( int val, R& r )
    {
       return val + r;
    }

    template<class R> void f(R)
    {
       accumulate(0, static_cast<int (*)(int, R&)>(p) );
    }

    main()
    {
       f(0);
    }

  The problem here was that the type being cast to in the static cast
was obliterated later.  A fix is attached.

-- 
Mark Mitchell		mmitchell@usa.net
Stanford University	http://www.stanford.edu

1997-12-07  Mark Mitchell  <mmitchell@usa.net>

	* rtti.c (build_dynamic_cast): Copy the cast-to type to the
	permanent obstack if we are processing a template decl.
	* typeck.c (build_static_cast): Likewise.
	(build_const_cast): Likewise.
	(build_reinterpret_cast): Likewise.

Index: gcc/cp/rtti.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/rtti.c,v
retrieving revision 1.1.1.2
diff -c -p -r1.1.1.2 rtti.c
*** rtti.c	1997/11/28 05:05:33	1.1.1.2
--- rtti.c	1997/12/07 22:45:11
*************** build_dynamic_cast (type, expr)
*** 642,648 ****
      return error_mark_node;
    
    if (processing_template_decl)
!     return build_min (DYNAMIC_CAST_EXPR, type, expr);
  
    return convert_from_reference (build_dynamic_cast_1 (type, expr));
  }
--- 642,648 ----
      return error_mark_node;
    
    if (processing_template_decl)
!     return build_min (DYNAMIC_CAST_EXPR, copy_to_permanent (type), expr);
  
    return convert_from_reference (build_dynamic_cast_1 (type, expr));
  }
Index: gcc/cp/typeck.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/typeck.c,v
retrieving revision 1.1.1.3
diff -c -p -r1.1.1.3 typeck.c
*** typeck.c	1997/11/25 00:49:43	1.1.1.3
--- typeck.c	1997/12/07 22:44:49
*************** build_static_cast (type, expr)
*** 5242,5248 ****
  
    if (processing_template_decl)
      {
!       tree t = build_min (STATIC_CAST_EXPR, type, expr);
        return t;
      }
  
--- 5242,5249 ----
  
    if (processing_template_decl)
      {
!       tree t = build_min (STATIC_CAST_EXPR, copy_to_permanent (type),
! 			  expr); 
        return t;
      }
  
*************** build_reinterpret_cast (type, expr)
*** 5334,5340 ****
  
    if (processing_template_decl)
      {
!       tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
        return t;
      }
  
--- 5335,5342 ----
  
    if (processing_template_decl)
      {
!       tree t = build_min (REINTERPRET_CAST_EXPR, 
! 			  copy_to_permanent (type), expr);
        return t;
      }
  
*************** build_const_cast (type, expr)
*** 5434,5440 ****
  
    if (processing_template_decl)
      {
!       tree t = build_min (CONST_CAST_EXPR, type, expr);
        return t;
      }
  
--- 5436,5443 ----
  
    if (processing_template_decl)
      {
!       tree t = build_min (CONST_CAST_EXPR, copy_to_permanent (type),
! 			  expr);
        return t;
      }
  
Index: gcc/testsuite/g++.old-deja/g++.pt/static_cast.C
===================================================================
RCS file: static_cast.C
diff -N static_cast.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- static_cast.C	Sun Dec  7 14:48:44 1997
***************
*** 0 ****
--- 1,22 ----
+ // Build don't link:
+ 
+ template <class InputIterator, class BinaryOperation>
+ void accumulate(InputIterator first, 
+     	         BinaryOperation binary_op) {
+ }
+ 
+ 
+ template<class R> int p( int val, R& r )
+ {
+    return val + r;
+ }
+ 
+ template<class R> void f(R)
+ {
+    accumulate(0, static_cast<int (*)(int, R&)>(p) );
+ }
+ 
+ main()
+ {
+    f(0);
+ }



More information about the Gcc-bugs mailing list