if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
return 1;
- if (strict & COMPARE_NO_ATTRIBUTES)
- attrval = 1;
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
- else if (! (attrval = (*targetm.comp_type_attributes) (t1, t2)))
- return 0;
+ if (! (attrval = (*targetm.comp_type_attributes) (t1, t2)))
+ return 0;
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
val = 0;
&& integer_zerop (TREE_OPERAND (object, 0)));
/* Convert OBJECT to the type of MEMBER. */
- if (!same_type_p (object_type, member_scope))
+ if (!same_type_p (TYPE_MAIN_VARIANT (object_type),
+ TYPE_MAIN_VARIANT (member_scope)))
{
tree binfo;
base_kind kind;
if (binfo == error_mark_node)
return error_mark_node;
- /* It is invalid to use to try to get to a virtual base of a
+ /* It is invalid to try to get to a virtual base of a
NULL object. The most common cause is invalid use of
offsetof macro. */
if (null_object_p && kind == bk_via_virtual)
give the right answer. Note that we complain whether or not they
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 && CLASSTYPE_NON_POD_P (object_type))
+ if (null_object_p && warn_invalid_offsetof
+ && CLASSTYPE_NON_POD_P (object_type))
{
warning ("invalid access to non-static data member `%D' of NULL object",
member);
}
tree
-build_function_call_real (function, params, require_complete, flags)
+build_function_call (function, params)
tree function, params;
- int require_complete, flags;
{
register tree fntype, fndecl;
- register tree value_type;
register tree coerced_params;
tree result;
tree name = NULL_TREE, assembler_name = NULL_TREE;
/* Convert the parameters to the types declared in the
function prototype, or apply default promotions. */
- if (flags & LOOKUP_COMPLAIN)
- coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
- params, fndecl, LOOKUP_NORMAL);
- else
- coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
- params, fndecl, 0);
-
+ coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
+ params, fndecl, LOOKUP_NORMAL);
if (coerced_params == error_mark_node)
- {
- if (flags & LOOKUP_SPECULATIVELY)
- return NULL_TREE;
- else
- return error_mark_node;
- }
+ return error_mark_node;
/* Check for errors in format strings. */
return result;
}
- /* Some built-in function calls will be evaluated at
- compile-time in fold (). */
- result = fold (build_call (function, coerced_params));
- value_type = TREE_TYPE (result);
-
- if (require_complete)
- {
- if (TREE_CODE (value_type) == VOID_TYPE)
- return result;
- result = require_complete_type (result);
- }
- if (IS_AGGR_TYPE (value_type))
- result = build_cplus_new (value_type, result);
- return convert_from_reference (result);
-}
-
-tree
-build_function_call (function, params)
- tree function, params;
-{
- return build_function_call_real (function, params, 1, LOOKUP_NORMAL);
+ return build_cxx_call (function, params, coerced_params);
}
\f
/* Convert the actual parameter expressions in the list VALUES
t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t));
return t;
}
-
+
+/* Return an ADDR_EXPR giving the address of T. This function
+ attempts no optimizations or simplifications; it is a low-level
+ primitive. */
+
+tree
+build_address (tree t)
+{
+ tree addr;
+
+ if (error_operand_p (t) || !cxx_mark_addressable (t))
+ return error_mark_node;
+
+ addr = build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (t)),
+ t);
+ if (staticp (t))
+ TREE_CONSTANT (addr) = 1;
+
+ return addr;
+}
+
+/* Return a NOP_EXPR converting EXPR to TYPE. */
+
+tree
+build_nop (tree type, tree expr)
+{
+ tree nop;
+
+ if (type == error_mark_node || error_operand_p (expr))
+ return expr;
+
+ nop = build1 (NOP_EXPR, type, expr);
+ if (TREE_CONSTANT (expr))
+ TREE_CONSTANT (nop) = 1;
+
+ return nop;
+}
+
/* C++: Must handle pointers to members.
Perhaps type instantiation should be extended to handle conversion
We could defer this in non-MS mode, but it's easier to give
a useful error here. */
- tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
+ /* Inside constant member functions, the `this' pointer
+ contains an extra const qualifier. TYPE_MAIN_VARIANT
+ is used here to remove this const from the diagnostics
+ and the created OFFSET_REF. */
+ tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg, 0)));
tree name = DECL_NAME (get_first_fn (TREE_OPERAND (arg, 1)));
if (! flag_ms_extensions)
if (current_class_type
&& TREE_OPERAND (arg, 0) == current_class_ref)
/* An expression like &memfn. */
- pedwarn ("ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say `&%T::%D'", base, name);
+ pedwarn ("ISO C++ forbids taking the address of an unqualified"
+ " or parenthesized non-static member function to form"
+ " a pointer to member function. Say `&%T::%D'",
+ base, name);
else
- pedwarn ("ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say `&%T::%D'", base, name);
+ pedwarn ("ISO C++ forbids taking the address of a bound member"
+ " function to form a pointer to member function."
+ " Say `&%T::%D'",
+ base, name);
}
arg = build_offset_ref (base, name);
}
if (argtype != error_mark_node)
argtype = build_pointer_type (argtype);
- if (!cxx_mark_addressable (arg))
- return error_mark_node;
-
{
tree addr;
&& TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
arg = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
- if (TREE_CODE (arg) == COMPONENT_REF
- && DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
+ if (TREE_CODE (arg) != COMPONENT_REF)
+ addr = build_address (arg);
+ else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
{
error ("attempt to take address of bit-field structure member `%D'",
TREE_OPERAND (arg, 1));
return error_mark_node;
}
- else if (TREE_CODE (arg) == COMPONENT_REF
- && TREE_CODE (TREE_OPERAND (arg, 0)) == INDIRECT_REF
- && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg, 0), 0))
- == INTEGER_CST))
+ else
{
- /* offsetof idiom, fold it. */
+ /* 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)),
addr = fold (build (PLUS_EXPR, argtype, rval,
cp_convert (argtype, byte_position (field))));
}
- else
- addr = build1 (ADDR_EXPR, argtype, arg);
-
- /* Address of a static or external variable or
- function counts as a constant */
- if (staticp (arg))
- TREE_CONSTANT (addr) = 1;
if (TREE_CODE (argtype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
warning ("address requested for `%D', which is declared `register'",
x);
TREE_ADDRESSABLE (x) = 1;
- put_var_into_stack (x);
+ put_var_into_stack (x, /*rescan=*/true);
return true;
case FUNCTION_DECL:
/* the left-hand operand of a comma expression is like an expression
statement: we should warn if it doesn't have any side-effects,
unless it was explicitly cast to (void). */
- if ((extra_warnings || warn_unused_value)
+ if (warn_unused_value
&& !(TREE_CODE (TREE_VALUE(list)) == CONVERT_EXPR
&& VOID_TYPE_P (TREE_TYPE (TREE_VALUE(list)))))
warning("left-hand operand of comma expression has no effect");
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));
newrhs = build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs);
if (newrhs == error_mark_node)
return error_mark_node;
}
}
- if (TREE_CODE (lhstype) != REFERENCE_TYPE)
- {
- if (TREE_SIDE_EFFECTS (lhs))
- lhs = stabilize_reference (lhs);
- if (TREE_SIDE_EFFECTS (newrhs))
- newrhs = stabilize_reference (newrhs);
- }
-
/* Convert new value to destination type. */
if (TREE_CODE (lhstype) == ARRAY_TYPE)
/* Finish creating the initializer. */
u = tree_cons (pfn_field, pfn,
build_tree_list (delta_field, delta));
- u = build (CONSTRUCTOR, type, NULL_TREE, u);
+ u = build_constructor (type, u);
TREE_CONSTANT (u) = TREE_CONSTANT (pfn) && TREE_CONSTANT (delta);
TREE_STATIC (u) = (TREE_CONSTANT (u)
&& (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
int force;
{
tree fn;
- tree pfn_type = TREE_TYPE (pfn);
- tree to_type = build_ptrmemfunc_type (type);
+ tree pfn_type;
+ tree to_type;
+
+ if (error_operand_p (pfn))
+ return error_mark_node;
+
+ pfn_type = TREE_TYPE (pfn);
+ to_type = build_ptrmemfunc_type (type);
/* Handle multiple conversions of pointer to member functions. */
- if (TYPE_PTRMEMFUNC_P (TREE_TYPE (pfn)))
+ if (TYPE_PTRMEMFUNC_P (pfn_type))
{
tree delta = NULL_TREE;
tree npfn = NULL_TREE;
if (fndecl)
savew = warningcount, savee = errorcount;
- rhs = initialize_reference (type, rhs);
+ rhs = initialize_reference (type, rhs, /*decl=*/NULL_TREE);
if (fndecl)
{
if (warningcount > savew)
}
if (TREE_CODE (to) != POINTER_TYPE)
- return
- same_type_ignoring_top_level_qualifiers_p (to, from)
- && (constp >= 0 || to_more_cv_qualified);
+ return ((constp >= 0 || to_more_cv_qualified)
+ && same_type_ignoring_top_level_qualifiers_p (to, from));
}
}
-/* When comparing, say, char ** to char const **, this function takes the
- 'char *' and 'char const *'. Do not pass non-pointer types to this
- function. */
+/* When comparing, say, char ** to char const **, this function takes
+ the 'char *' and 'char const *'. Do not pass non-pointer/reference
+ types to this function. */
int
comp_ptr_ttypes (to, from)