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 c++/17435, c++/18140


This patch fixes two more C++ regressions:

* 17435

  This PR concerns one of the very tricky bits of C++, both from the
  point of view of the specification and the implementation.  In
  particular, the fact that binding a reference to a temporary can
  extend the lifetime of the temporary.  (This results in object
  lifetimes for automatic variables that do not nest; weird.)  We were
  copying just the base class portion of a derived class object when
  doing this, which is not correct; fixed by finding the base class
  object later in the game.

* 18140

  This was a rejects-valid PR caused by Giovanni's patch to make ">>"
  be treated as the end of a template argument, as an attempt at
  better error-recovery.  That did not work in the case that the ">>"
  was actually legitimately interpreted as a shift operator.  A
  consequence is that one of the tests in g++.dg/template/error10.C
  now issues marginally inferior error messages, but correctness
  first.

Tested on i686-pc-linux-gnu, applied on the mainline.  The c++/18140
fix will also be applied to the 3.4 branch shortly.

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

2004-10-27  Mark Mitchell  <mark@codesourcery.com>

	PR c++/17435
	* call.c (convert_like_real): Fix formatting.
	(initialize_reference): When binding a temporary to a base class,
	ensure that the nominal copy made is to the derived class, not the
	base class.

	PR c++/18140
	* parser.c (cp_parser_next_token_ends_template_argument_p): Do not
	include ">>".

2004-10-27  Mark Mitchell  <mark@codesourcery.com>

	PR c++/17435
	* g++.dg/init/ref12.C: New test.

	PR c++/18140
	* g++.dg/template/shift1.C: New test.
	* g++.dg/template/error10.C: Adjust error markers.

Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.516
diff -c -5 -p -r1.516 call.c
*** cp/call.c	21 Oct 2004 21:23:38 -0000	1.516
--- cp/call.c	28 Oct 2004 05:03:52 -0000
*************** convert_like_real (conversion *convs, tr
*** 4237,4247 ****
        if (inner >= 0
  	  && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
  	expr = decl_constant_value (expr);
        if (convs->check_copy_constructor_p)
  	check_constructor_callable (totype, expr);
! 	return expr;
      case ck_ambig:
        /* Call build_user_type_conversion again for the error.  */
        return build_user_type_conversion
  	(totype, convs->u.expr, LOOKUP_NORMAL);
  
--- 4237,4247 ----
        if (inner >= 0
  	  && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
  	expr = decl_constant_value (expr);
        if (convs->check_copy_constructor_p)
  	check_constructor_callable (totype, expr);
!       return expr;
      case ck_ambig:
        /* Call build_user_type_conversion again for the error.  */
        return build_user_type_conversion
  	(totype, convs->u.expr, LOOKUP_NORMAL);
  
*************** initialize_reference (tree type, tree ex
*** 6465,6475 ****
  
        /* Skip over the REF_BIND.  */
        conv = conv->u.next;
        /* If the next conversion is a BASE_CONV, skip that too -- but
  	 remember that the conversion was required.  */
!       if (conv->kind == ck_base && conv->need_temporary_p)
  	{
  	  if (conv->check_copy_constructor_p)
   	    check_constructor_callable (TREE_TYPE (expr), expr);
  	  base_conv_type = conv->type;
  	  conv = conv->u.next;
--- 6465,6475 ----
  
        /* Skip over the REF_BIND.  */
        conv = conv->u.next;
        /* If the next conversion is a BASE_CONV, skip that too -- but
  	 remember that the conversion was required.  */
!       if (conv->kind == ck_base)
  	{
  	  if (conv->check_copy_constructor_p)
   	    check_constructor_callable (TREE_TYPE (expr), expr);
  	  base_conv_type = conv->type;
  	  conv = conv->u.next;
*************** initialize_reference (tree type, tree ex
*** 6535,6544 ****
--- 6535,6549 ----
  		static_aggregates = tree_cons (NULL_TREE, var,
  					       static_aggregates);
  	    }
  	  /* Use its address to initialize the reference variable.  */
  	  expr = build_address (var);
+ 	  if (base_conv_type)
+ 	    expr = convert_to_base (expr, 
+ 				    build_pointer_type (base_conv_type),
+ 				    /*check_access=*/true,
+ 				    /*nonnull=*/true);
  	  expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
  	}
        else
  	/* Take the address of EXPR.  */
  	expr = build_unary_op (ADDR_EXPR, expr, 0);
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.271
diff -c -5 -p -r1.271 parser.c
*** cp/parser.c	27 Oct 2004 02:23:12 -0000	1.271
--- cp/parser.c	28 Oct 2004 05:03:54 -0000
*************** cp_parser_next_token_starts_class_defini
*** 15472,15493 ****
    token = cp_lexer_peek_token (parser->lexer);
    return (token->type == CPP_OPEN_BRACE || token->type == CPP_COLON);
  }
  
  /* Returns TRUE iff the next token is the "," or ">" ending a
!    template-argument. ">>" is also accepted (after the full
!    argument was parsed) because it's probably a typo for "> >",
!    and there is a specific diagnostic for this.  */
  
  static bool
  cp_parser_next_token_ends_template_argument_p (cp_parser *parser)
  {
    cp_token *token;
  
    token = cp_lexer_peek_token (parser->lexer);
!   return (token->type == CPP_COMMA || token->type == CPP_GREATER
! 	  || token->type == CPP_RSHIFT);
  }
  
  /* Returns TRUE iff the n-th token is a ">", or the n-th is a "[" and the
     (n+1)-th is a ":" (which is a possible digraph typo for "< ::").  */
  
--- 15472,15490 ----
    token = cp_lexer_peek_token (parser->lexer);
    return (token->type == CPP_OPEN_BRACE || token->type == CPP_COLON);
  }
  
  /* Returns TRUE iff the next token is the "," or ">" ending a
!    template-argument.   */
  
  static bool
  cp_parser_next_token_ends_template_argument_p (cp_parser *parser)
  {
    cp_token *token;
  
    token = cp_lexer_peek_token (parser->lexer);
!   return (token->type == CPP_COMMA || token->type == CPP_GREATER);
  }
  
  /* Returns TRUE iff the n-th token is a ">", or the n-th is a "[" and the
     (n+1)-th is a ":" (which is a possible digraph typo for "< ::").  */
  
Index: testsuite/g++.dg/init/ref12.C
===================================================================
RCS file: testsuite/g++.dg/init/ref12.C
diff -N testsuite/g++.dg/init/ref12.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/init/ref12.C	28 Oct 2004 05:03:54 -0000
***************
*** 0 ****
--- 1,29 ----
+ // PR c++/17435
+ 
+ extern "C" void abort ();
+ 
+ bool ok;
+  
+ struct A  
+ { 
+   void func() const 
+   { 
+     ok = 1;
+   } 
+   
+   ~A() 
+   { 
+     if (!ok)
+       abort ();
+   } 
+ }; 
+ 
+ struct B : public A  
+ { 
+ }; 
+  
+ int main() 
+ { 
+   A const& r1 = B(); 
+   r1.func(); 
+ } 
Index: testsuite/g++.dg/template/error10.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/error10.C,v
retrieving revision 1.2
diff -c -5 -p -r1.2 error10.C
*** testsuite/g++.dg/template/error10.C	23 Sep 2004 21:27:17 -0000	1.2
--- testsuite/g++.dg/template/error10.C	28 Oct 2004 05:03:54 -0000
*************** L<H() >> 5> l;  // { dg-error "" "non-co
*** 64,70 ****
  template <void (*)(void)>
  struct K {};
  
  void KFunc(void);
  
! A<K<&KFunc>> k1;  // { dg-error "should be '> >' within" }
! K<&KFunc>> k2; // { dg-error "spurious '>>'" }
--- 64,70 ----
  template <void (*)(void)>
  struct K {};
  
  void KFunc(void);
  
! A<K<&KFunc>> k1;  // { dg-error "" }
! K<&KFunc>> k2; // { dg-error "" }
Index: testsuite/g++.dg/template/shift1.C
===================================================================
RCS file: testsuite/g++.dg/template/shift1.C
diff -N testsuite/g++.dg/template/shift1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/shift1.C	28 Oct 2004 05:03:54 -0000
***************
*** 0 ****
--- 1,10 ----
+ // PR c++/18140
+ 
+ template <int N> struct IntHolder {
+   static const int value = N;
+ };
+ 
+ template <int N, int S> struct ShrIntHolder {
+   static const int value = IntHolder< N>>S >::value;
+ };
+ 


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