/* Build expressions with type checking for C++ compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2011, 2012
Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
index1 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t1));
index2 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t2));
- /* If T1 and T2 belong to template parm lists of different size,
- let's assume they are different. */
- if (TEMPLATE_PARM_NUM_SIBLINGS (index1)
- != TEMPLATE_PARM_NUM_SIBLINGS (index2))
- return false;
-
/* Then compare their relative position. */
if (TEMPLATE_PARM_IDX (index1) != TEMPLATE_PARM_IDX (index2)
|| TEMPLATE_PARM_LEVEL (index1) != TEMPLATE_PARM_LEVEL (index2)
break;
case TYPE_PACK_EXPANSION:
- return same_type_p (PACK_EXPANSION_PATTERN (t1),
- PACK_EXPANSION_PATTERN (t2));
+ return (same_type_p (PACK_EXPANSION_PATTERN (t1),
+ PACK_EXPANSION_PATTERN (t2))
+ && comp_template_args (PACK_EXPANSION_EXTRA_ARGS (t1),
+ PACK_EXPANSION_EXTRA_ARGS (t2)));
case DECLTYPE_TYPE:
if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t1)
if (error_operand_p (exp))
return error_mark_node;
- if (NULLPTR_TYPE_P (type))
+ if (NULLPTR_TYPE_P (type) && !TREE_SIDE_EFFECTS (exp))
return nullptr_node;
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
return error_mark_node;
}
+ /* Don't let an array compound literal decay to a pointer. It can
+ still be used to initialize an array or bind to a reference. */
+ if (TREE_CODE (exp) == TARGET_EXPR)
+ {
+ error ("taking address of temporary array");
+ return error_mark_node;
+ }
+
ptrtype = build_pointer_type (TREE_TYPE (type));
if (TREE_CODE (exp) == VAR_DECL)
tree object_type;
tree member_scope;
tree result = NULL_TREE;
+ tree using_decl = NULL_TREE;
if (error_operand_p (object) || error_operand_p (member))
return error_mark_node;
result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
object, result);
}
+ else if ((using_decl = strip_using_decl (member)) != member)
+ result = build_class_member_access_expr (object,
+ using_decl,
+ access_path, preserve_reference,
+ complain);
else
{
if (complain & tf_error)
tf_warning_or_error);
expr = (adjust_result_of_qualified_name_lookup
(expr, dtor_type, object_type));
+ if (scope == NULL_TREE)
+ /* We need to call adjust_result_of_qualified_name_lookup in case the
+ destructor names a base class, but we unset BASELINK_QUALIFIED_P so
+ that we still get virtual function binding. */
+ BASELINK_QUALIFIED_P (expr) = false;
return expr;
}
return error_mark_node;
}
/* ...and then the delta in the PMF. */
- instance_ptr = fold_build_pointer_plus (instance_ptr, delta);
+ instance_ptr = build2 (POINTER_PLUS_EXPR, TREE_TYPE (instance_ptr),
+ instance_ptr, fold_convert (sizetype, delta));
/* Hand back the adjusted 'this' argument to our caller. */
*instance_ptrptr = instance_ptr;
return expr;
}
+/* Return whether OP is an expression of enum type cast to integer
+ type. In C++ even unsigned enum types are cast to signed integer
+ types. We do not want to issue warnings about comparisons between
+ signed and unsigned types when one of the types is an enum type.
+ Those warnings are always false positives in practice. */
+
+static bool
+enum_cast_to_int (tree op)
+{
+ if (TREE_CODE (op) == NOP_EXPR
+ && TREE_TYPE (op) == integer_type_node
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == ENUMERAL_TYPE
+ && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 0))))
+ return true;
+
+ /* The cast may have been pushed into a COND_EXPR. */
+ if (TREE_CODE (op) == COND_EXPR)
+ return (enum_cast_to_int (TREE_OPERAND (op, 1))
+ || enum_cast_to_int (TREE_OPERAND (op, 2)));
+
+ return false;
+}
+
/* For the c-common bits. */
tree
build_binary_op (location_t location, enum tree_code code, tree op0, tree op1,
delta0,
integer_one_node,
complain);
+
+ if ((complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0
+ && !NULLPTR_TYPE_P (TREE_TYPE (op1)))
+ warning (OPT_Wzero_as_null_pointer_constant,
+ "zero as null pointer constant");
+
e2 = cp_build_binary_op (location,
EQ_EXPR, e2, integer_zero_node,
complain);
if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
&& warn_sign_compare
- && !TREE_NO_WARNING (orig_op0)
- && !TREE_NO_WARNING (orig_op1)
/* Do not warn until the template is instantiated; we cannot
bound the ranges of the arguments until that point. */
&& !processing_template_decl
&& (complain & tf_warning)
- && c_inhibit_evaluation_warnings == 0)
+ && c_inhibit_evaluation_warnings == 0
+ /* Even unsigned enum types promote to signed int. We don't
+ want to issue -Wsign-compare warnings for this case. */
+ && !enum_cast_to_int (orig_op0)
+ && !enum_cast_to_int (orig_op1))
{
warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1,
result_type, resultcode);
{
tree min = build_min_non_dep (COND_EXPR, expr,
orig_ifexp, orig_op1, orig_op2);
- /* Remember that the result is an lvalue or xvalue. */
- if (lvalue_or_rvalue_with_address_p (expr)
+ /* In C++11, remember that the result is an lvalue or xvalue.
+ In C++98, lvalue_kind can just assume lvalue in a template. */
+ if (cxx_dialect >= cxx0x
+ && lvalue_or_rvalue_with_address_p (expr)
&& !lvalue_or_rvalue_with_address_p (min))
TREE_TYPE (min) = cp_build_reference_type (TREE_TYPE (min),
!real_lvalue_p (expr));
{
tree intype;
tree result;
+ cp_lvalue_kind clk;
/* Assume the cast is valid. */
*valid_p = true;
- intype = TREE_TYPE (expr);
+ intype = unlowered_expr_type (expr);
/* Save casted types in the function's used types hash table. */
used_types_insert (type);
cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)." */
if (TREE_CODE (type) == REFERENCE_TYPE
&& TYPE_REF_IS_RVALUE (type)
- && lvalue_or_rvalue_with_address_p (expr)
+ && (clk = real_lvalue_p (expr))
&& reference_related_p (TREE_TYPE (type), intype)
&& (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype)))
{
- expr = build_typed_address (expr, type);
- return convert_from_reference (expr);
+ if (clk == clk_ordinary)
+ {
+ /* Handle the (non-bit-field) lvalue case here by casting to
+ lvalue reference and then changing it to an rvalue reference.
+ Casting an xvalue to rvalue reference will be handled by the
+ main code path. */
+ tree lref = cp_build_reference_type (TREE_TYPE (type), false);
+ result = (perform_direct_initialization_if_possible
+ (lref, expr, c_cast_p, complain));
+ result = cp_fold_convert (type, result);
+ /* Make sure we don't fold back down to a named rvalue reference,
+ because that would be an lvalue. */
+ if (DECL_P (result))
+ result = build1 (NON_LVALUE_EXPR, type, result);
+ return convert_from_reference (result);
+ }
+ else
+ /* For a bit-field or packed field, bind to a temporary. */
+ expr = rvalue (expr);
}
/* Resolve overloaded address here rather than once in
else if (TYPE_PTR_P (type) && INTEGRAL_OR_ENUMERATION_TYPE_P (intype))
/* OK */
;
+ else if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
+ || TYPE_PTR_P (type) || TYPE_PTR_TO_MEMBER_P (type))
+ && same_type_p (type, intype))
+ /* DR 799 */
+ return fold_if_not_in_template (build_nop (type, expr));
else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
|| (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
return fold_if_not_in_template (build_nop (type, expr));
/* Handle null pointer to member function conversions. */
if (null_ptr_cst_p (pfn))
{
- pfn = build_c_cast (input_location, type, nullptr_node);
+ pfn = build_c_cast (input_location, type, pfn);
return build_ptrmemfunc1 (to_type,
integer_zero_node,
pfn);
&& TREE_CODE (retval) == VAR_DECL
&& DECL_CONTEXT (retval) == current_function_decl
&& ! TREE_STATIC (retval)
- && ! DECL_ANON_UNION_VAR_P (retval)
+ /* And not a lambda or anonymous union proxy. */
+ && !DECL_HAS_VALUE_EXPR_P (retval)
&& (DECL_ALIGN (retval)
>= DECL_ALIGN (DECL_RESULT (current_function_decl)))
/* The cv-unqualified type of the returned value must be the
Note that these conditions are similar to, but not as strict as,
the conditions for the named return value optimization. */
if ((cxx_dialect != cxx98)
- && (TREE_CODE (retval) == VAR_DECL
+ && ((TREE_CODE (retval) == VAR_DECL
+ && !DECL_HAS_VALUE_EXPR_P (retval))
|| TREE_CODE (retval) == PARM_DECL)
&& DECL_CONTEXT (retval) == current_function_decl
&& !TREE_STATIC (retval)
constructor can produce constant init, so rely on cp_finish_decl to
clear TREE_READONLY if the variable has non-constant init. */
- /* If the type has a mutable component, that component might be
- modified. */
- if (TYPE_HAS_MUTABLE_P (type))
+ /* If the type has (or might have) a mutable component, that component
+ might be modified. */
+ if (TYPE_HAS_MUTABLE_P (type) || !COMPLETE_TYPE_P (type))
type_quals &= ~TYPE_QUAL_CONST;
c_apply_type_quals_to_decl (type_quals, decl);
bool *long_long_unsigned_p, bool *long_double_p)
{
tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
- if (processing_template_decl)
- return (argtypes == NULL_TREE
- || same_type_p (TREE_VALUE (argtypes), void_type_node));
+
+ *long_long_unsigned_p = false;
+ *long_double_p = false;
+ if (processing_template_decl || processing_specialization)
+ return argtypes == void_list_node;
else
{
tree argtype;
int arity;
int max_arity = 2;
- *long_long_unsigned_p = false;
- *long_double_p = false;
-
/* Count the number and type of arguments and check for ellipsis. */
for (argtype = argtypes, arity = 0;
argtype && argtype != void_list_node;
if (!argtype)
return false; /* Found ellipsis. */
- if (arity > max_arity)
+ if (arity != max_arity)
return false;
return true;
}
}
-