/* This file is part of the C++ front end.
It contains routines to build C++ expressions given their operands,
including computing the types of the result, C and C++ specific error
- checks, and some optimization.
-
- There are also routines to build RETURN_STMT nodes and CASE_STMT nodes,
- and to process initializations in declarations (since they work
- like a strange sort of assignment). */
+ checks, and some optimization. */
#include "config.h"
#include "system.h"
tree attributes;
/* FIXME: Attributes. */
- my_friendly_assert (ARITHMETIC_TYPE_P (t1)
- || TREE_CODE (t1) == COMPLEX_TYPE
- || TREE_CODE (t1) == ENUMERAL_TYPE,
- 19990725);
- my_friendly_assert (ARITHMETIC_TYPE_P (t2)
- || TREE_CODE (t2) == COMPLEX_TYPE
- || TREE_CODE (t2) == ENUMERAL_TYPE,
- 19990725);
+ gcc_assert (ARITHMETIC_TYPE_P (t1)
+ || TREE_CODE (t1) == COMPLEX_TYPE
+ || TREE_CODE (t1) == ENUMERAL_TYPE);
+ gcc_assert (ARITHMETIC_TYPE_P (t2)
+ || TREE_CODE (t2) == COMPLEX_TYPE
+ || TREE_CODE (t2) == ENUMERAL_TYPE);
/* In what follows, we slightly generalize the rules given in [expr] so
as to deal with `long long' and `complex'. First, merge the
return composite_pointer_type (t1, t2, error_mark_node, error_mark_node,
"conversion");
else
- abort ();
+ gcc_unreachable ();
}
\f
/* Compare two exception specifier types for exactness or subsetness, if
if (t1 == error_mark_node || t2 == error_mark_node)
return false;
- my_friendly_assert (TYPE_P (t1) && TYPE_P (t2), 20030623);
+ gcc_assert (TYPE_P (t1) && TYPE_P (t2));
/* TYPENAME_TYPEs should be resolved if the qualifying scope is the
current instantiation. */
/* Otherwise, try to find a unique baseclass of TT1
that is shared by TT2, and follow that down. */
- for (i = CLASSTYPE_N_BASECLASSES (tt1)-1; i >= 0; i--)
+ for (i = BINFO_N_BASE_BINFOS (TYPE_BINFO (tt1))-1; i >= 0; i--)
{
- tree basetype = TYPE_BINFO_BASETYPE (tt1, i);
+ tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (tt1), i));
tree trial = common_base_type (basetype, tt2);
+
if (trial)
{
if (trial == error_mark_node)
}
/* Same for TT2. */
- for (i = CLASSTYPE_N_BASECLASSES (tt2)-1; i >= 0; i--)
+ for (i = BINFO_N_BASE_BINFOS (TYPE_BINFO (tt2))-1; i >= 0; i--)
{
- tree basetype = TYPE_BINFO_BASETYPE (tt2, i);
+ tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (tt2), i));
tree trial = common_base_type (tt1, basetype);
+
if (trial)
{
if (trial == error_mark_node)
tree value;
const char *op_name;
- my_friendly_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR, 20020720);
+ gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
if (type == error_mark_node)
return error_mark_node;
if (TREE_CODE (exp) == COMPOUND_EXPR)
{
tree op1 = decay_conversion (TREE_OPERAND (exp, 1));
- return build (COMPOUND_EXPR, TREE_TYPE (op1),
- TREE_OPERAND (exp, 0), op1);
+ return build2 (COMPOUND_EXPR, TREE_TYPE (op1),
+ TREE_OPERAND (exp, 0), op1);
}
if (!lvalue_p (exp)
tree promoted_type;
type = TREE_TYPE (expr);
- my_friendly_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type), 20030703);
+ gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
promoted_type = type_promotes_to (type);
if (type != promoted_type)
expr = cp_convert (promoted_type, expr);
if (TREE_CODE (member) == PSEUDO_DTOR_EXPR)
return member;
- my_friendly_assert (DECL_P (member) || BASELINK_P (member),
- 20020801);
+ gcc_assert (DECL_P (member) || BASELINK_P (member));
/* [expr.ref]
result = member;
/* If OBJECT has side-effects, they are supposed to occur. */
if (TREE_SIDE_EFFECTS (object))
- result = build (COMPOUND_EXPR, TREE_TYPE (result), object, result);
+ result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
}
else if (TREE_CODE (member) == FIELD_DECL)
{
/*nonnull=*/1);
/* If we found the base successfully then we should be able
to convert to it successfully. */
- my_friendly_assert (object != error_mark_node,
- 20020801);
+ gcc_assert (object != error_mark_node);
}
/* Complain about other invalid uses of offsetof, even though they will
actually used the offsetof macro, since there's no way to know at this
point. So we just give a warning, instead of a pedwarn. */
if (null_object_p && warn_invalid_offsetof
- && CLASSTYPE_NON_POD_P (object_type))
+ && CLASSTYPE_NON_POD_P (object_type)
+ && ! skip_evaluation)
{
warning ("invalid access to non-static data member `%D' of NULL object",
member);
member_type = cp_build_qualified_type (member_type, type_quals);
}
- result = fold (build (COMPONENT_REF, member_type, object, member));
+ result = fold (build3 (COMPONENT_REF, member_type, object, member,
+ NULL_TREE));
/* Mark the expression const or volatile, as appropriate. Even
though we've dealt with the type above, we still have to mark the
type = unknown_type_node;
/* Note that we do not convert OBJECT to the BASELINK_BINFO
base. That will happen when the function is called. */
- result = build (COMPONENT_REF, type, object, member);
+ result = build3 (COMPONENT_REF, type, object, member, NULL_TREE);
}
else if (TREE_CODE (member) == CONST_DECL)
{
result = member;
/* If OBJECT has side-effects, they are supposed to occur. */
if (TREE_SIDE_EFFECTS (object))
- result = build (COMPOUND_EXPR, TREE_TYPE (result),
- object, result);
+ result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
+ object, result);
}
else
{
return error_mark_node;
}
if (!TYPE_HAS_DESTRUCTOR (dtor_type))
- return build (PSEUDO_DTOR_EXPR, void_type_node, object, scope,
- dtor_type);
+ return build3 (PSEUDO_DTOR_EXPR, void_type_node, object, scope,
+ dtor_type);
expr = lookup_member (dtor_type, complete_dtor_identifier,
/*protect=*/1, /*want_type=*/false);
expr = (adjust_result_of_qualified_name_lookup
|| (TREE_CODE (name) == SCOPE_REF
&& TYPE_P (TREE_OPERAND (name, 0))
&& dependent_type_p (TREE_OPERAND (name, 0))))
- return build_min_nt (COMPONENT_REF, object, name);
+ return build_min_nt (COMPONENT_REF, object, name, NULL_TREE);
object = build_non_dependent_expr (object);
}
if (BASELINK_P (name))
{
/* A member function that has already been looked up. */
- my_friendly_assert ((TREE_CODE (BASELINK_FUNCTIONS (name))
- == TEMPLATE_ID_EXPR),
- 20020805);
+ gcc_assert (TREE_CODE (BASELINK_FUNCTIONS (name)) == TEMPLATE_ID_EXPR);
member = name;
}
else
or a BIT_NOT_EXPR. */
scope = TREE_OPERAND (name, 0);
name = TREE_OPERAND (name, 1);
- my_friendly_assert ((CLASS_TYPE_P (scope)
- || TREE_CODE (scope) == NAMESPACE_DECL),
- 20020804);
- my_friendly_assert ((TREE_CODE (name) == IDENTIFIER_NODE
- || TREE_CODE (name) == BIT_NOT_EXPR),
- 20020804);
+ gcc_assert (CLASS_TYPE_P (scope)
+ || TREE_CODE (scope) == NAMESPACE_DECL);
+ gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE
+ || TREE_CODE (name) == BIT_NOT_EXPR);
/* If SCOPE is a namespace, then the qualified name does not
name a member of OBJECT_TYPE. */
/*preserve_reference=*/false);
if (processing_template_decl && expr != error_mark_node)
return build_min_non_dep (COMPONENT_REF, expr,
- orig_object, orig_name);
+ orig_object, orig_name, NULL_TREE);
return expr;
}
routine directly because it expects the object to be of class
type. */
ptrmem_type = TREE_TYPE (ptrmem);
- my_friendly_assert (TYPE_PTRMEMFUNC_P (ptrmem_type), 20020804);
+ gcc_assert (TYPE_PTRMEMFUNC_P (ptrmem_type));
member = lookup_member (ptrmem_type, member_name, /*protect=*/0,
/*want_type=*/false);
member_type = cp_build_qualified_type (TREE_TYPE (member),
cp_type_quals (ptrmem_type));
- return fold (build (COMPONENT_REF, member_type, ptrmem, member));
+ return fold (build3 (COMPONENT_REF, member_type,
+ ptrmem, member, NULL_TREE));
}
/* Given an expression PTR for a pointer, return an expression
case COMPOUND_EXPR:
{
tree value = build_array_ref (TREE_OPERAND (array, 1), idx);
- return build (COMPOUND_EXPR, TREE_TYPE (value),
- TREE_OPERAND (array, 0), value);
+ return build2 (COMPOUND_EXPR, TREE_TYPE (value),
+ TREE_OPERAND (array, 0), value);
}
case COND_EXPR:
}
type = TREE_TYPE (TREE_TYPE (array));
- rval = build (ARRAY_REF, type, array, idx);
+ rval = build4 (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
/* Array ref is const/volatile if the array elements are
or if the array is.. */
TREE_READONLY (rval)
break;
default:
- abort ();
+ gcc_unreachable ();
}
/* Convert down to the right base before using the instance. First
if (instance_ptr == error_mark_node)
return error_mark_node;
/* ...and then the delta in the PMF. */
- instance_ptr = build (PLUS_EXPR, TREE_TYPE (instance_ptr),
- instance_ptr, delta);
+ instance_ptr = build2 (PLUS_EXPR, TREE_TYPE (instance_ptr),
+ instance_ptr, delta);
/* Hand back the adjusted 'this' argument to our caller. */
*instance_ptrptr = instance_ptr;
vtbl = build_indirect_ref (vtbl, NULL);
/* Finally, extract the function pointer from the vtable. */
- e2 = fold (build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx));
+ e2 = fold (build2 (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx));
e2 = build_indirect_ref (e2, NULL);
TREE_CONSTANT (e2) = 1;
TREE_INVARIANT (e2) = 1;
/* Make sure this doesn't get evaluated first inside one of the
branches of the COND_EXPR. */
if (instance_save_expr)
- e1 = build (COMPOUND_EXPR, TREE_TYPE (e1),
- instance_save_expr, e1);
+ e1 = build2 (COMPOUND_EXPR, TREE_TYPE (e1),
+ instance_save_expr, e1);
function = e1;
}
{
tree fntype, fndecl;
tree coerced_params;
- tree result;
tree name = NULL_TREE;
int is_method;
tree original = function;
if (coerced_params == error_mark_node)
return error_mark_node;
- /* Check for errors in format strings. */
+ /* Check for errors in format strings and inappropriately
+ null parameters. */
- if (warn_format)
- check_function_format (NULL, TYPE_ATTRIBUTES (fntype), coerced_params);
-
- /* Recognize certain built-in functions so we can make tree-codes
- other than CALL_EXPR. We do this when it enables fold-const.c
- to do something useful. */
-
- if (TREE_CODE (function) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
- && DECL_BUILT_IN (TREE_OPERAND (function, 0)))
- {
- result = expand_tree_builtin (TREE_OPERAND (function, 0),
- params, coerced_params);
- if (result)
- return result;
- }
+ check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params);
- return build_cxx_call (function, params, coerced_params);
+ return build_cxx_call (function, coerced_params);
}
\f
/* Convert the actual parameter expressions in the list VALUES
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
- || code0 == COMPLEX_TYPE)
+ || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
- || code1 == COMPLEX_TYPE))
+ || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
{
if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1))
warning ("division by zero in `%E / 0'", op0);
else if (TREE_CODE (op1) == REAL_CST && real_zerop (op1))
warning ("division by zero in `%E / 0.'", op0);
+ if (code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
+ code0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
+ if (code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)
+ code1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
+
if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
resultcode = RDIV_EXPR;
else
cp_convert (TREE_TYPE (pfn0),
integer_zero_node));
e1 = cp_build_binary_op (TRUTH_ORIF_EXPR, e1, e2);
- e2 = build (EQ_EXPR, boolean_type_node, pfn0, pfn1);
+ e2 = build2 (EQ_EXPR, boolean_type_node, pfn0, pfn1);
e = cp_build_binary_op (TRUTH_ANDIF_EXPR, e2, e1);
if (code == EQ_EXPR)
return e;
return cp_build_binary_op (EQ_EXPR, e, integer_zero_node);
}
- else if ((TYPE_PTRMEMFUNC_P (type0)
- && same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type0), type1))
- || (TYPE_PTRMEMFUNC_P (type1)
- && same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type1), type0)))
- abort ();
+ else
+ {
+ gcc_assert (!TYPE_PTRMEMFUNC_P (type0)
+ || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type0),
+ type1));
+ gcc_assert (!TYPE_PTRMEMFUNC_P (type1)
+ || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type1),
+ type0));
+ }
+
break;
case MAX_EXPR:
build_type = result_type;
{
- tree result = fold (build (resultcode, build_type, op0, op1));
+ tree result = fold (build2 (resultcode, build_type, op0, op1));
if (final_type != 0)
result = cp_convert (final_type, result);
return result;
/* Do the division. */
- result = build (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1));
+ result = build2 (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1));
return fold (result);
}
\f
{
if (type_dependent_expression_p (xarg))
return build_min_nt (code, xarg, NULL_TREE);
+
+ /* For non-dependent pointer-to-member, the SCOPE_REF will be
+ processed during template substitution. Just compute the
+ right type here and build an ADDR_EXPR around it for
+ diagnostics. */
+ if (code == ADDR_EXPR && TREE_CODE (xarg) == SCOPE_REF)
+ {
+ tree type;
+ if (TREE_TYPE (xarg) == unknown_type_node)
+ type = unknown_type_node;
+ else if (TREE_CODE (TREE_TYPE (xarg)) == FUNCTION_TYPE)
+ type = build_pointer_type (TREE_TYPE (xarg));
+ else
+ type = build_ptrmem_type (TREE_OPERAND (xarg, 0),
+ TREE_TYPE (xarg));
+ return build_min (code, type, xarg, NULL_TREE);
+ }
+
xarg = build_non_dependent_expr (xarg);
}
{
/* A single non-static member, make sure we don't allow a
pointer-to-member. */
- xarg = build (OFFSET_REF, TREE_TYPE (xarg),
- TREE_OPERAND (xarg, 0),
- ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE));
+ xarg = build2 (OFFSET_REF, TREE_TYPE (xarg),
+ TREE_OPERAND (xarg, 0),
+ ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE));
PTRMEM_OK_P (xarg) = ptrmem;
}
}
arg = stabilize_reference (arg);
real = build_unary_op (REALPART_EXPR, arg, 1);
imag = build_unary_op (IMAGPART_EXPR, arg, 1);
- return build (COMPLEX_EXPR, TREE_TYPE (arg),
- build_unary_op (code, real, 1), imag);
+ return build2 (COMPLEX_EXPR, TREE_TYPE (arg),
+ build_unary_op (code, real, 1), imag);
}
/* Report invalid types. */
value = arg;
else
value = save_expr (arg);
- incremented = build (((code == PREINCREMENT_EXPR
- || code == POSTINCREMENT_EXPR)
- ? PLUS_EXPR : MINUS_EXPR),
- argtype, value, inc);
+ incremented = build2 (((code == PREINCREMENT_EXPR
+ || code == POSTINCREMENT_EXPR)
+ ? PLUS_EXPR : MINUS_EXPR),
+ argtype, value, inc);
modify = build_modify_expr (arg, NOP_EXPR, incremented);
- compound = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
+ compound = build2 (COMPOUND_EXPR, TREE_TYPE (arg),
+ modify, value);
/* Eliminate warning about unused result of + or -. */
TREE_NO_WARNING (compound) = 1;
val = boolean_increment (code, arg);
}
else
- val = build (code, TREE_TYPE (arg), arg, inc);
+ val = build2 (code, TREE_TYPE (arg), arg, inc);
TREE_SIDE_EFFECTS (val) = 1;
return cp_convert (result_type, val);
return arg;
}
- /* For &x[y], return x+y. But, in a template, ARG may be an
- ARRAY_REF representing a non-dependent expression. In that
- case, there may be an overloaded "operator []" that will be
- chosen at instantiation time; we must not try to optimize
- here. */
- if (TREE_CODE (arg) == ARRAY_REF && !processing_template_decl)
- {
- if (!cxx_mark_addressable (TREE_OPERAND (arg, 0)))
- return error_mark_node;
- return cp_build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
- TREE_OPERAND (arg, 1));
- }
-
/* Uninstantiated types are all functions. Taking the
address of a function is a no-op, so just return the
argument. */
- if (TREE_CODE (arg) == IDENTIFIER_NODE
- && IDENTIFIER_OPNAME_P (arg))
- {
- abort ();
- /* We don't know the type yet, so just work around the problem.
- We know that this will resolve to an lvalue. */
- return build1 (ADDR_EXPR, unknown_type_node, arg);
- }
+ gcc_assert (TREE_CODE (arg) != IDENTIFIER_NODE
+ || !IDENTIFIER_OPNAME_P (arg));
if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
&& !really_overloaded_fn (TREE_OPERAND (arg, 1)))
/* We can only get here with a single static member
function. */
- my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL
- && DECL_STATIC_FUNCTION_P (fn),
- 20030906);
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_STATIC_FUNCTION_P (fn));
mark_used (fn);
addr = build_address (fn);
if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
/* Do not lose object's side effects. */
- addr = build (COMPOUND_EXPR, TREE_TYPE (addr),
- TREE_OPERAND (arg, 0), addr);
+ addr = build2 (COMPOUND_EXPR, TREE_TYPE (addr),
+ TREE_OPERAND (arg, 0), addr);
}
else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
{
}
else
{
- /* Unfortunately we cannot just build an address
- expression here, because we would not handle
- address-constant-expressions or offsetof correctly. */
tree field = TREE_OPERAND (arg, 1);
tree rval = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0);
tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (rval)),
ba_check, NULL);
rval = build_base_path (PLUS_EXPR, rval, binfo, 1);
- rval = build_nop (argtype, rval);
- addr = fold (build (PLUS_EXPR, argtype, rval,
- cp_convert (argtype, byte_position (field))));
+
+ TREE_OPERAND (arg, 0) = build_indirect_ref (rval, NULL);
+ addr = build_address (arg);
}
if (TREE_CODE (argtype) == POINTER_TYPE
if (TREE_CODE (arg) == COMPOUND_EXPR)
{
tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0);
- return build (COMPOUND_EXPR, TREE_TYPE (real_result),
- TREE_OPERAND (arg, 0), real_result);
+ return build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
+ TREE_OPERAND (arg, 0), real_result);
}
/* Handle (a ? b : c) used as an "lvalue". */
if (TREE_SIDE_EFFECTS (lvalue))
{
lvalue = stabilize_reference (lvalue);
- arg = build (TREE_CODE (arg), TREE_TYPE (arg),
- lvalue, TREE_OPERAND (arg, 1));
+ arg = build2 (TREE_CODE (arg), TREE_TYPE (arg),
+ lvalue, TREE_OPERAND (arg, 1));
}
return unary_complex_lvalue
- (code, build (COMPOUND_EXPR, TREE_TYPE (lvalue), arg, lvalue));
+ (code, build2 (COMPOUND_EXPR, TREE_TYPE (lvalue), arg, lvalue));
}
if (code != ADDR_EXPR)
|| TREE_CODE (arg) == INIT_EXPR)
{
tree real_result = build_unary_op (code, TREE_OPERAND (arg, 0), 0);
- arg = build (COMPOUND_EXPR, TREE_TYPE (real_result), arg, real_result);
+ arg = build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
+ arg, real_result);
TREE_NO_WARNING (arg) = 1;
return arg;
}
{
tree t;
- my_friendly_assert (TREE_CODE (arg) != SCOPE_REF, 313);
+ gcc_assert (TREE_CODE (arg) != SCOPE_REF);
if (TREE_CODE (arg) != OFFSET_REF)
return 0;
}
if (TREE_CODE (arg) == SAVE_EXPR && TREE_CODE (targ) == INDIRECT_REF)
- return build (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
+ return build3 (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
TREE_OPERAND (targ, 0), current_function_decl, NULL);
}
case VAR_DECL:
/* Caller should not be trying to mark initialized
constant fields addressable. */
- my_friendly_assert (DECL_LANG_SPECIFIC (x) == 0
- || DECL_IN_AGGR_P (x) == 0
- || TREE_STATIC (x)
- || DECL_EXTERNAL (x), 314);
+ gcc_assert (DECL_LANG_SPECIFIC (x) == 0
+ || DECL_IN_AGGR_P (x) == 0
+ || TREE_STATIC (x)
+ || DECL_EXTERNAL (x));
/* Fall through. */
case CONST_DECL:
warning ("address requested for `%D', which is declared `register'",
x);
TREE_ADDRESSABLE (x) = 1;
- put_var_into_stack (x, /*rescan=*/true);
return true;
case FUNCTION_DECL:
TREE_ADDRESSABLE (x) = 1;
- TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
return true;
case CONSTRUCTOR:
helps the compiler to eliminate unnecessary temporaries. */
tree init = TREE_OPERAND (rhs, 1);
- init = build (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
+ init = build2 (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
TREE_OPERAND (rhs, 1) = init;
return rhs;
}
- return build (COMPOUND_EXPR, TREE_TYPE (rhs), lhs, rhs);
+ return build2 (COMPOUND_EXPR, TREE_TYPE (rhs), lhs, rhs);
}
/* Issue an error message if casting from SRC_TYPE to DEST_TYPE casts
t. */
result = perform_direct_initialization_if_possible (type, expr);
if (result)
- return convert_from_reference (result);
+ {
+ result = convert_from_reference (result);
+ /* [expr.static.cast]
+
+ If T is a reference type, the result is an lvalue; otherwise,
+ the result is an rvalue. */
+ if (TREE_CODE (type) != REFERENCE_TYPE
+ && real_lvalue_p (result))
+ result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
+ return result;
+ }
/* [expr.static.cast]
tree lhstype = TREE_TYPE (lhs);
tree olhstype = lhstype;
tree olhs = NULL_TREE;
+ bool plain_assign = (modifycode == NOP_EXPR);
/* Avoid duplicate error messages from operands that had errors. */
if (lhs == error_mark_node || rhs == error_mark_node)
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
- lhs = build (TREE_CODE (lhs), TREE_TYPE (lhs),
- stabilize_reference (TREE_OPERAND (lhs, 0)),
- TREE_OPERAND (lhs, 1));
- return build (COMPOUND_EXPR, lhstype,
- lhs,
- build_modify_expr (TREE_OPERAND (lhs, 0),
- modifycode, rhs));
+ lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
+ stabilize_reference (TREE_OPERAND (lhs, 0)),
+ TREE_OPERAND (lhs, 1));
+ return build2 (COMPOUND_EXPR, lhstype,
+ lhs,
+ build_modify_expr (TREE_OPERAND (lhs, 0),
+ modifycode, rhs));
/* Handle (a, b) used as an "lvalue". */
case COMPOUND_EXPR:
modifycode, rhs);
if (newrhs == error_mark_node)
return error_mark_node;
- return build (COMPOUND_EXPR, lhstype,
- TREE_OPERAND (lhs, 0), newrhs);
+ return build2 (COMPOUND_EXPR, lhstype,
+ TREE_OPERAND (lhs, 0), newrhs);
case MODIFY_EXPR:
if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
- lhs = build (TREE_CODE (lhs), TREE_TYPE (lhs),
- stabilize_reference (TREE_OPERAND (lhs, 0)),
- TREE_OPERAND (lhs, 1));
+ lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
+ stabilize_reference (TREE_OPERAND (lhs, 0)),
+ TREE_OPERAND (lhs, 1));
newrhs = build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs);
if (newrhs == error_mark_node)
return error_mark_node;
- return build (COMPOUND_EXPR, lhstype, lhs, newrhs);
+ return build2 (COMPOUND_EXPR, lhstype, lhs, newrhs);
/* Handle (a ? b : c) used as an "lvalue". */
case COND_EXPR:
/* Make sure the code to compute the rhs comes out
before the split. */
if (preeval)
- cond = build (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
+ cond = build2 (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
return cond;
}
if (! same_type_p (TREE_TYPE (rhs), lhstype))
/* Call convert to generate an error; see PR 11063. */
rhs = convert (lhstype, rhs);
- result = build (INIT_EXPR, lhstype, lhs, rhs);
+ result = build2 (INIT_EXPR, lhstype, lhs, rhs);
TREE_SIDE_EFFECTS (result) = 1;
return result;
}
{
result = build_special_member_call (lhs, complete_ctor_identifier,
build_tree_list (NULL_TREE, rhs),
- TYPE_BINFO (lhstype),
- LOOKUP_NORMAL);
+ lhstype, LOOKUP_NORMAL);
if (result == NULL_TREE)
return error_mark_node;
return result;
value with the RHS producing the value we should actually
store into the LHS. */
- my_friendly_assert (!PROMOTES_TO_AGGR_TYPE (lhstype, REFERENCE_TYPE),
- 978652);
+ gcc_assert (!PROMOTES_TO_AGGR_TYPE (lhstype, REFERENCE_TYPE));
lhs = stabilize_reference (lhs);
newrhs = cp_build_binary_op (modifycode, lhs, rhs);
if (newrhs == error_mark_node)
/* Now it looks like a plain assignment. */
modifycode = NOP_EXPR;
}
- my_friendly_assert (TREE_CODE (lhstype) != REFERENCE_TYPE, 20011220);
- my_friendly_assert (TREE_CODE (TREE_TYPE (newrhs)) != REFERENCE_TYPE,
- 20011220);
+ gcc_assert (TREE_CODE (lhstype) != REFERENCE_TYPE);
+ gcc_assert (TREE_CODE (TREE_TYPE (newrhs)) != REFERENCE_TYPE);
}
/* The left-hand side must be an lvalue. */
accidental self-initialization. So we force the TARGET_EXPR to be
expanded without a target. */
if (TREE_CODE (newrhs) == TARGET_EXPR)
- newrhs = build (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs,
- TREE_OPERAND (newrhs, 0));
+ newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs,
+ TREE_OPERAND (newrhs, 0));
}
if (newrhs == error_mark_node)
return error_mark_node;
- result = build (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
- lhstype, lhs, newrhs);
+ result = build2 (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
+ lhstype, lhs, newrhs);
TREE_SIDE_EFFECTS (result) = 1;
+ if (!plain_assign)
+ TREE_NO_WARNING (result) = 1;
/* If we got the LHS in a different type for storing in,
convert the result back to the nominal type of LHS
return result;
if (olhs)
{
- result = build (COMPOUND_EXPR, olhstype, result, olhs);
+ result = build2 (COMPOUND_EXPR, olhstype, result, olhs);
TREE_NO_WARNING (result) = 1;
return result;
}
make_node (modifycode),
/*overloaded_p=*/NULL);
if (rval)
- return rval;
+ {
+ TREE_NO_WARNING (rval) = 1;
+ return rval;
+ }
}
return build_modify_expr (lhs, modifycode, rhs);
}
}
/* Just adjust the DELTA field. */
- my_friendly_assert (TREE_TYPE (delta) == ptrdiff_type_node, 20030727);
+ gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (delta), ptrdiff_type_node));
if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
n = cp_build_binary_op (LSHIFT_EXPR, n, integer_one_node);
delta = cp_build_binary_op (PLUS_EXPR, delta, n);
return instantiate_type (type, pfn, tf_error | tf_warning);
fn = TREE_OPERAND (pfn, 0);
- my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
return make_ptrmem_cst (to_type, fn);
}
tree fn = PTRMEM_CST_MEMBER (cst);
tree ptr_class, fn_class;
- my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
/* The class that the function belongs to. */
fn_class = DECL_CONTEXT (fn);
fn; the call will do the opposite adjustment. */
tree orig_class = DECL_CONTEXT (fn);
tree binfo = binfo_or_else (orig_class, fn_class);
- *delta = fold (build (PLUS_EXPR, TREE_TYPE (*delta),
- *delta, BINFO_OFFSET (binfo)));
+ *delta = fold (build2 (PLUS_EXPR, TREE_TYPE (*delta),
+ *delta, BINFO_OFFSET (binfo)));
/* We set PFN to the vtable offset at which the function can be
found, plus one (unless ptrmemfunc_vbit_in_delta, in which
case delta is shifted left, and then incremented). */
*pfn = DECL_VINDEX (fn);
- *pfn = fold (build (MULT_EXPR, integer_type_node, *pfn,
- TYPE_SIZE_UNIT (vtable_entry_type)));
+ *pfn = fold (build2 (MULT_EXPR, integer_type_node, *pfn,
+ TYPE_SIZE_UNIT (vtable_entry_type)));
switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
{
case ptrmemfunc_vbit_in_pfn:
- *pfn = fold (build (PLUS_EXPR, integer_type_node, *pfn,
- integer_one_node));
+ *pfn = fold (build2 (PLUS_EXPR, integer_type_node, *pfn,
+ integer_one_node));
break;
case ptrmemfunc_vbit_in_delta:
- *delta = fold (build (LSHIFT_EXPR, TREE_TYPE (*delta),
- *delta, integer_one_node));
- *delta = fold (build (PLUS_EXPR, TREE_TYPE (*delta),
- *delta, integer_one_node));
+ *delta = fold (build2 (LSHIFT_EXPR, TREE_TYPE (*delta),
+ *delta, integer_one_node));
+ *delta = fold (build2 (PLUS_EXPR, TREE_TYPE (*delta),
+ *delta, integer_one_node));
break;
default:
- abort ();
+ gcc_unreachable ();
}
*pfn = fold (build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type),
return convert_for_assignment (type, rhs, errtype, fndecl, parmnum);
}
\f
-/* Expand an ASM statement with operands, handling output operands
- that are not variables or INDIRECT_REFS by transforming such
- cases into cases that expand_asm_operands can handle.
-
- Arguments are same as for expand_asm_operands.
-
- We don't do default conversions on all inputs, because it can screw
- up operands that are expected to be in memory. */
-
-void
-c_expand_asm_operands (tree string, tree outputs, tree inputs, tree clobbers,
- int vol, location_t locus)
-{
- int noutputs = list_length (outputs);
- int i;
- /* o[I] is the place that output number I should be written. */
- tree *o = alloca (noutputs * sizeof (tree));
- tree tail;
-
- /* Record the contents of OUTPUTS before it is modified. */
- for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
- o[i] = TREE_VALUE (tail);
-
- /* Generate the ASM_OPERANDS insn;
- store into the TREE_VALUEs of OUTPUTS some trees for
- where the values were actually stored. */
- expand_asm_operands (string, outputs, inputs, clobbers, vol, locus);
-
- /* Copy all the intermediate outputs into the specified outputs. */
- for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
- {
- if (o[i] != TREE_VALUE (tail))
- {
- expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)),
- const0_rtx, VOIDmode, EXPAND_NORMAL);
- free_temp_slots ();
-
- /* Restore the original value so that it's correct the next
- time we expand this function. */
- TREE_VALUE (tail) = o[i];
- }
- /* Detect modification of read-only values.
- (Otherwise done by build_modify_expr.) */
- else
- {
- tree type = TREE_TYPE (o[i]);
- if (type != error_mark_node
- && (CP_TYPE_CONST_P (type)
- || (CLASS_TYPE_P (type) && C_TYPE_FIELDS_READONLY (type))))
- readonly_error (o[i], "modification by `asm'", 1);
- }
- }
-
- /* Those MODIFY_EXPRs could do autoincrements. */
- emit_queue ();
-}
-\f
/* If RETVAL is the address of, or a reference to, a local variable or
temporary give an appropriate warning. */
return value, the named return value is used. */
result = DECL_RESULT (current_function_decl);
valtype = TREE_TYPE (result);
- my_friendly_assert (valtype != NULL_TREE, 19990924);
+ gcc_assert (valtype != NULL_TREE);
fn_returns_value_p = !VOID_TYPE_P (valtype);
if (!retval && DECL_NAME (result) && fn_returns_value_p)
retval = result;
/* Effective C++ rule 15. See also start_function. */
if (warn_ecpp
- && DECL_NAME (current_function_decl) == ansi_assopname(NOP_EXPR)
- && retval != current_class_ref)
- warning ("`operator=' should return a reference to `*this'");
+ && DECL_NAME (current_function_decl) == ansi_assopname(NOP_EXPR))
+ {
+ bool warn = true;
+
+ /* The function return type must be a reference to the current
+ class. */
+ if (TREE_CODE (valtype) == REFERENCE_TYPE
+ && same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (valtype), TREE_TYPE (current_class_ref)))
+ {
+ /* Returning '*this' is obviously OK. */
+ if (retval == current_class_ref)
+ warn = false;
+ /* If we are calling a function whose return type is the same of
+ the current class reference, it is ok. */
+ else if (TREE_CODE (retval) == INDIRECT_REF
+ && TREE_CODE (TREE_OPERAND (retval, 0)) == CALL_EXPR)
+ warn = false;
+ }
+
+ if (warn)
+ warning ("`operator=' should return a reference to `*this'");
+ }
/* The fabled Named Return Value optimization, as per [class.copy]/15:
else if (! current_function_returns_struct
&& TREE_CODE (retval) == TARGET_EXPR
&& TREE_CODE (TREE_OPERAND (retval, 1)) == AGGR_INIT_EXPR)
- retval = build (COMPOUND_EXPR, TREE_TYPE (retval), retval,
- TREE_OPERAND (retval, 0));
+ retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
+ TREE_OPERAND (retval, 0));
else
maybe_warn_about_returning_address_of_local (retval);
}
/* Actually copy the value returned into the appropriate location. */
if (retval && retval != result)
- retval = build (INIT_EXPR, TREE_TYPE (result), result, retval);
+ retval = build2 (INIT_EXPR, TREE_TYPE (result), result, retval);
return retval;
}