FreeBSD/contrib/gcc/cp/typeck.c
/* Perform the conversions in [expr] that apply when an lvalue appears
   in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
   function-to-pointer conversions.  In addition, manifest constants
   are replaced by their values, and bitfield references are converted
   to their declared types.

   Although the returned value is being used as an rvalue, this
   function does not wrap the returned expression in a
   NON_LVALUE_EXPR; the caller is expected to be mindful of the fact
   that the return value is no longer an lvalue.  */


Although the returned value is being used as an rvalue, this
function does not wrap the returned expression in a
NON_LVALUE_EXPR; the caller is expected to be mindful of the fact
that the return value is no longer an lvalue.
Although the returned value is being used as an rvalue this function does not wrap the returned expression in a NON_LVALUE_EXPR ; the caller is expected to be mindful of the fact that the return value is no longer an lvalue .
tree
decay_conversion (tree exp)
{
  tree type;
  enum tree_code code;
  type = TREE_TYPE (exp);
  if (type == error_mark_node)
    return error_mark_node;
  if (type_unknown_p (exp))
    {
      cxx_incomplete_type_error (exp, TREE_TYPE (exp));
      return error_mark_node;
    }
  exp = decl_constant_value (exp);
  if (error_operand_p (exp))
    return error_mark_node;
  code = TREE_CODE (type);
  if (code == VOID_TYPE)
    {
      error ("void value not ignored as it ought to be");
      return error_mark_node;
    }
  if (invalid_nonstatic_memfn_p (exp))
    return error_mark_node;
  if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
    return build_unary_op (ADDR_EXPR, exp, 0);
  if (code == ARRAY_TYPE)
    {
      tree adr;
      tree ptrtype;
      if (TREE_CODE (exp) == INDIRECT_REF)
	return build_nop (build_pointer_type (TREE_TYPE (type)),
			  TREE_OPERAND (exp, 0));
      if (TREE_CODE (exp) == COMPOUND_EXPR)
	{
	  tree op1 = decay_conversion (TREE_OPERAND (exp, 1));
	  return build2 (COMPOUND_EXPR, TREE_TYPE (op1),
			 TREE_OPERAND (exp, 0), op1);
	}
      if (!lvalue_p (exp)
	  && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))
	{
	  error ("invalid use of non-lvalue array");
	  return error_mark_node;
	}
      ptrtype = build_pointer_type (TREE_TYPE (type));
      if (TREE_CODE (exp) == VAR_DECL)
	{
	  if (!cxx_mark_addressable (exp))
	    return error_mark_node;
	  adr = build_nop (ptrtype, build_address (exp));
	  return adr;
	}
      adr = build_unary_op (ADDR_EXPR, exp, 1);
      return cp_convert (ptrtype, adr);
    }
  exp = convert_bitfield_to_declared_type (exp);
  type = TREE_TYPE (exp);
  if (!CLASS_TYPE_P (type) && cp_type_quals (type))
    exp = build_nop (TYPE_MAIN_VARIANT (type), exp);
  return exp;
}
tree decay_conversion ( tree exp ) { tree type ; enum tree_code code ; type = TREE_TYPE ( exp ) ; if ( type == error_mark_node ) return error_mark_node ; if ( type_unknown_p ( exp ) ) { cxx_incomplete_type_error ( exp , TREE_TYPE ( exp ) ) ; return error_mark_node ; } exp = decl_constant_value ( exp ) ; if ( error_operand_p ( exp ) ) return error_mark_node ; code = TREE_CODE ( type ) ; if ( code == VOID_TYPE ) { error ( " " ) ; return error_mark_node ; } if ( invalid_nonstatic_memfn_p ( exp ) ) return error_mark_node ; if ( code == FUNCTION_TYPE || is_overloaded_fn ( exp ) ) return build_unary_op ( ADDR_EXPR , exp , 0 ) ; if ( code == ARRAY_TYPE ) { tree adr ; tree ptrtype ; if ( TREE_CODE ( exp ) == INDIRECT_REF ) return build_nop ( build_pointer_type ( TREE_TYPE ( type ) ) , TREE_OPERAND ( exp , 0 ) ) ; if ( TREE_CODE ( exp ) == COMPOUND_EXPR ) { tree op1 = decay_conversion ( TREE_OPERAND ( exp , 1 ) ) ; return build2 ( COMPOUND_EXPR , TREE_TYPE ( op1 ) , TREE_OPERAND ( exp , 0 ) , op1 ) ; } if ( ! lvalue_p ( exp ) && ! ( TREE_CODE ( exp ) == CONSTRUCTOR && TREE_STATIC ( exp ) ) ) { error ( " " ) ; return error_mark_node ; } ptrtype = build_pointer_type ( TREE_TYPE ( type ) ) ; if ( TREE_CODE ( exp ) == VAR_DECL ) { if ( ! cxx_mark_addressable ( exp ) ) return error_mark_node ; adr = build_nop ( ptrtype , build_address ( exp ) ) ; return adr ; } adr = build_unary_op ( ADDR_EXPR , exp , 1 ) ; return cp_convert ( ptrtype , adr ) ; } exp = convert_bitfield_to_declared_type ( exp ) ; type = TREE_TYPE ( exp ) ; if ( ! CLASS_TYPE_P ( type ) && cp_type_quals ( type ) ) exp = build_nop ( TYPE_MAIN_VARIANT ( type ) , exp ) ; return exp ; }
Perform the conversions in [expr] that apply when an lvalue appears
in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
function-to-pointer conversions.
Perform the conversions in [ expr ] that apply when an lvalue appears in an rvalue context : the lvalue - to - rvalue array - to - pointer and function - to - pointer conversions .
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
     Leave such NOP_EXPRs, since RHS is being used in non-lvalue context.  */ /* This way is better for a COMPONENT_REF since it can
	 simplify the offset for a component.  */ /* If a bitfield is used in a context where integral promotion
     applies, then the caller is expected to have used
     default_conversion.  That function promotes bitfields correctly
     before calling this function.  At this point, if we have a
     bitfield referenced, we may assume that is not subject to
     promotion, and that, therefore, the type of the resulting rvalue
     is the declared type of the bitfield.  */ /* We do not call rvalue() here because we do not want to wrap EXP
     in a NON_LVALUE_EXPR.  */ /* [basic.lval]

     Non-class rvalues always have cv-unqualified types.  */