File revert-pr25950.diff of Package gcc43

Index: gcc/cp/call.c
===================================================================
*** gcc/cp/call.c.orig	2007-11-27 14:27:45.000000000 +0100
--- gcc/cp/call.c	2007-11-28 11:57:06.000000000 +0100
*************** struct conversion {
*** 89,94 ****
--- 89,98 ----
       temporary should be created to hold the result of the
       conversion.  */
    BOOL_BITFIELD need_temporary_p : 1;
+   /* If KIND is ck_identity or ck_base_conv, true to indicate that the
+      copy constructor must be accessible, even though it is not being
+      used.  */
+   BOOL_BITFIELD check_copy_constructor_p : 1;
    /* If KIND is ck_ptr or ck_pmem, true to indicate that a conversion
       from a pointer-to-derived to pointer-to-base is being performed.  */
    BOOL_BITFIELD base_p : 1;
*************** static conversion *merge_conversion_sequ
*** 197,202 ****
--- 201,207 ----
  static bool magic_varargs_p (tree);
  typedef void (*diagnostic_fn_t) (const char *, ...) ATTRIBUTE_GCC_CXXDIAG(1,2);
  static tree build_temp (tree, tree, int, diagnostic_fn_t *);
+ static void check_constructor_callable (tree, tree);
  
  /* Returns nonzero iff the destructor name specified in NAME matches BASETYPE.
     NAME can take many forms...  */
*************** standard_conversion (tree to, tree from,
*** 861,873 ****
    else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
  	   && vector_types_convertible_p (from, to, false))
      return build_conv (ck_std, to, conv);
!   /* A derived-to-base conversion sequence is a user-defined conversion
!      because it involves a constructor call, even though it has the rank of
!      a standard conversion, so we don't consider it if we aren't allowing
!      user-defined conversions.  But if we're binding directly to a
!      reference, it's only a pointer conversion.  */
!   else if ((!(flags & LOOKUP_NO_CONVERSION)
! 	    || (flags & LOOKUP_NO_TEMP_BIND))
  	   && IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
  	   && is_properly_derived_from (from, to))
      {
--- 866,872 ----
    else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
  	   && vector_types_convertible_p (from, to, false))
      return build_conv (ck_std, to, conv);
!   else if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE)
  	   && IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
  	   && is_properly_derived_from (from, to))
      {
*************** standard_conversion (tree to, tree from,
*** 877,884 ****
        /* The derived-to-base conversion indicates the initialization
  	 of a parameter with base type from an object of a derived
  	 type.  A temporary object is created to hold the result of
! 	 the conversion unless we're binding directly to a reference.  */
!       conv->need_temporary_p = !(flags & LOOKUP_NO_TEMP_BIND);
      }
    else
      return NULL;
--- 876,883 ----
        /* The derived-to-base conversion indicates the initialization
  	 of a parameter with base type from an object of a derived
  	 type.  A temporary object is created to hold the result of
! 	 the conversion.  */
!       conv->need_temporary_p = true;
      }
    else
      return NULL;
*************** reference_binding (tree rto, tree rfrom,
*** 1154,1165 ****
    compatible_p = reference_compatible_p (to, from);
  
    /* Directly bind reference when target expression's type is compatible with
!      the reference and expression is an lvalue. In DR391, the wording in
!      [8.5.3/5 dcl.init.ref] is changed to also require direct bindings for
!      const and rvalue references to rvalues of compatible class type. */
    if (compatible_p
        && (lvalue_p
! 	  || ((CP_TYPE_CONST_NON_VOLATILE_P(to) || TYPE_REF_IS_RVALUE (rto))
  	      && CLASS_TYPE_P (from))))
      {
        /* [dcl.init.ref]
--- 1153,1166 ----
    compatible_p = reference_compatible_p (to, from);
  
    /* Directly bind reference when target expression's type is compatible with
!      the reference and expression is an lvalue. In C++0x, the wording in
!      [8.5.3/5 dcl.init.ref] is changed to also allow direct bindings for const
!      and rvalue references to rvalues of compatible class type, as part of
!      DR391. */
    if (compatible_p
        && (lvalue_p
! 	  || ((cxx_dialect != cxx98)
! 	      && (CP_TYPE_CONST_NON_VOLATILE_P(to) || TYPE_REF_IS_RVALUE (rto))
  	      && CLASS_TYPE_P (from))))
      {
        /* [dcl.init.ref]
*************** reference_binding (tree rto, tree rfrom,
*** 1170,1183 ****
  	    is reference-compatible with "cv2 T2,"
  
  	 the reference is bound directly to the initializer expression
! 	 lvalue.
! 
! 	 [...]
! 	 If the initializer expression is an rvalue, with T2 a class type,
! 	 and "cv1 T1" is reference-compatible with "cv2 T2", the reference
! 	 is bound to the object represented by the rvalue or to a sub-object
! 	 within that object.  */
! 
        conv = build_identity_conv (from, expr);
        conv = direct_reference_binding (rto, conv);
  
--- 1171,1177 ----
  	    is reference-compatible with "cv2 T2,"
  
  	 the reference is bound directly to the initializer expression
! 	 lvalue.  */
        conv = build_identity_conv (from, expr);
        conv = direct_reference_binding (rto, conv);
  
*************** reference_binding (tree rto, tree rfrom,
*** 1257,1262 ****
--- 1251,1282 ----
  
    /* [dcl.init.ref]
  
+      If the initializer expression is an rvalue, with T2 a class type,
+      and "cv1 T1" is reference-compatible with "cv2 T2", the reference
+      is bound in one of the following ways:
+ 
+      -- The reference is bound to the object represented by the rvalue
+ 	or to a sub-object within that object.
+ 
+      -- ...
+ 
+      We use the first alternative.  The implicit conversion sequence
+      is supposed to be same as we would obtain by generating a
+      temporary.  Fortunately, if the types are reference compatible,
+      then this is either an identity conversion or the derived-to-base
+      conversion, just as for direct binding.  */
+   if (CLASS_TYPE_P (from) && compatible_p)
+     {
+       conv = build_identity_conv (from, expr);
+       conv = direct_reference_binding (rto, conv);
+       conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
+       if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE))
+ 	conv->u.next->check_copy_constructor_p = true;
+       return conv;
+     }
+ 
+   /* [dcl.init.ref]
+ 
       Otherwise, a temporary of type "cv1 T1" is created and
       initialized from the initializer expression using the rules for a
       non-reference copy initialization.  If T1 is reference-related to
*************** reference_binding (tree rto, tree rfrom,
*** 1265,1275 ****
    if (related_p && !at_least_as_qualified_p (to, from))
      return NULL;
  
-   /* We're generating a temporary now, but don't bind any more in the
-      conversion (specifically, don't slice the temporary returned by a
-      conversion operator).  */
-   flags |= LOOKUP_NO_TEMP_BIND;
- 
    conv = implicit_conversion (to, from, expr, c_cast_p,
  			      flags);
    if (!conv)
--- 1285,1290 ----
*************** implicit_conversion (tree to, tree from,
*** 1314,1323 ****
        && (flags & LOOKUP_NO_CONVERSION) == 0)
      {
        struct z_candidate *cand;
-       int convflags = ((flags & LOOKUP_NO_TEMP_BIND)
- 		       |LOOKUP_ONLYCONVERTING);
  
!       cand = build_user_type_conversion_1 (to, expr, convflags);
        if (cand)
  	conv = cand->second_conv;
  
--- 1329,1337 ----
        && (flags & LOOKUP_NO_CONVERSION) == 0)
      {
        struct z_candidate *cand;
  
!       cand = build_user_type_conversion_1
! 	(to, expr, LOOKUP_ONLYCONVERTING);
        if (cand)
  	conv = cand->second_conv;
  
*************** build_user_type_conversion_1 (tree totyp
*** 2576,2582 ****
    conversion *conv = NULL;
    tree args = NULL_TREE;
    bool any_viable_p;
-   int convflags;
  
    /* We represent conversion within a hierarchy using RVALUE_CONV and
       BASE_CONV, as specified by [over.best.ics]; these become plain
--- 2590,2595 ----
*************** build_user_type_conversion_1 (tree totyp
*** 2607,2617 ****
    candidates = 0;
    flags |= LOOKUP_NO_CONVERSION;
  
-   /* It's OK to bind a temporary for converting constructor arguments, but
-      not in converting the return value of a conversion operator.  */
-   convflags = ((flags & LOOKUP_NO_TEMP_BIND) | LOOKUP_NO_CONVERSION);
-   flags &= ~LOOKUP_NO_TEMP_BIND;
- 
    if (ctors)
      {
        tree t;
--- 2620,2625 ----
*************** build_user_type_conversion_1 (tree totyp
*** 2656,2661 ****
--- 2664,2670 ----
      {
        tree fns;
        tree conversion_path = TREE_PURPOSE (conv_fns);
+       int convflags = LOOKUP_NO_CONVERSION;
  
        /* If we are called to convert to a reference type, we are trying to
  	 find an lvalue binding, so don't even consider temporaries.  If
*************** enforce_access (tree basetype_path, tree
*** 4264,4269 ****
--- 4273,4293 ----
    return true;
  }
  
+ /* Check that a callable constructor to initialize a temporary of
+    TYPE from an EXPR exists.  */
+ 
+ static void
+ check_constructor_callable (tree type, tree expr)
+ {
+   build_special_member_call (NULL_TREE,
+ 			     complete_ctor_identifier,
+ 			     build_tree_list (NULL_TREE, expr),
+ 			     type,
+ 			     LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING
+ 			     | LOOKUP_NO_CONVERSION
+ 			     | LOOKUP_CONSTRUCTOR_CALLABLE);
+ }
+ 
  /* Initialize a temporary of type TYPE with EXPR.  The FLAGS are a
     bitwise or of LOOKUP_* values.  If any errors are warnings are
     generated, set *DIAGNOSTIC_FN to "error" or "warning",
*************** convert_like_real (conversion *convs, tr
*** 4422,4427 ****
--- 4446,4453 ----
        if (inner >= 0)
          {   
            expr = decl_constant_value (expr);
+ 	  if (convs->check_copy_constructor_p)
+ 	    check_constructor_callable (totype, expr);
            if (expr == null_node && INTEGRAL_TYPE_P (totype))
              /* If __null has been converted to an integer type, we do not
                 want to warn about uses of EXPR as an integer, rather than
*************** convert_like_real (conversion *convs, tr
*** 4457,4462 ****
--- 4483,4490 ----
  	{
  	  /* We are going to bind a reference directly to a base-class
  	     subobject of EXPR.  */
+ 	  if (convs->check_copy_constructor_p)
+ 	    check_constructor_callable (TREE_TYPE (expr), expr);
  	  /* Build an expression for `*((base*) &expr)'.  */
  	  expr = build_unary_op (ADDR_EXPR, expr, 0);
  	  expr = convert_to_base (expr, build_pointer_type (totype),
*************** initialize_reference (tree type, tree ex
*** 6800,6805 ****
--- 6828,6835 ----
  	 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;
  	}
Index: gcc/cp/cp-tree.h
===================================================================
*** gcc/cp/cp-tree.h.orig	2007-11-19 11:36:02.000000000 +0100
--- gcc/cp/cp-tree.h	2007-11-28 11:53:41.000000000 +0100
*************** enum overload_flags { NO_SPECIAL = 0, DT
*** 3698,3707 ****
  #define LOOKUP_PREFER_NAMESPACES (1 << 9)
  /* Accept types or namespaces.  */
  #define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES)
  /* Return friend declarations and un-declared builtin functions.
     (Normally, these entities are registered in the symbol table, but
     not found by lookup.)  */
! #define LOOKUP_HIDDEN (LOOKUP_PREFER_NAMESPACES << 1)
  /* Prefer that the lvalue be treated as an rvalue.  */
  #define LOOKUP_PREFER_RVALUE (LOOKUP_HIDDEN << 1)
  
--- 3698,3710 ----
  #define LOOKUP_PREFER_NAMESPACES (1 << 9)
  /* Accept types or namespaces.  */
  #define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES)
+ /* We are checking that a constructor can be called -- but we do not
+    actually plan to call it.  */
+ #define LOOKUP_CONSTRUCTOR_CALLABLE (1 << 10)
  /* Return friend declarations and un-declared builtin functions.
     (Normally, these entities are registered in the symbol table, but
     not found by lookup.)  */
! #define LOOKUP_HIDDEN (LOOKUP_CONSTRUCTOR_CALLABLE << 1)
  /* Prefer that the lvalue be treated as an rvalue.  */
  #define LOOKUP_PREFER_RVALUE (LOOKUP_HIDDEN << 1)
  
openSUSE Build Service is sponsored by