tree pointed_to_1 = TREE_TYPE (t1);
tree pointed_to_2 = TREE_TYPE (t2);
tree target = composite_type (pointed_to_1, pointed_to_2);
- t1 = build_pointer_type (target);
+ t1 = build_pointer_type_for_mode (target, TYPE_MODE (t1), false);
t1 = build_type_attribute_variant (t1, attributes);
return qualify_type (t1, t2);
}
compatible integer type, then this sets *ENUM_AND_INT_P to true;
*ENUM_AND_INT_P is never set to false. If DIFFERENT_TYPES_P is not
NULL, and the types are compatible but different enough not to be
- permitted in C1X typedef redeclarations, then this sets
+ permitted in C11 typedef redeclarations, then this sets
*DIFFERENT_TYPES_P to true; *DIFFERENT_TYPES_P is never set to
false, but may or may not be set if the types are incompatible.
This differs from comptypes, in that we don't free the seen
if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE)
{
- error_at (loc,
+ error_at (loc,
"subscripted value is neither array nor pointer nor vector");
return error_mark_node;
index = default_conversion (index);
gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE);
-
- /* For vector[index], convert the vector to a
+
+ /* For vector[index], convert the vector to a
pointer of the underlying type. */
if (TREE_CODE (TREE_TYPE (array)) == VECTOR_TYPE)
{
tree type1;
if (TREE_CODE (index) == INTEGER_CST)
- if (!host_integerp (index, 1)
- || ((unsigned HOST_WIDE_INT) tree_low_cst (index, 1)
+ if (!host_integerp (index, 1)
+ || ((unsigned HOST_WIDE_INT) tree_low_cst (index, 1)
>= TYPE_VECTOR_SUBPARTS (TREE_TYPE (array))))
warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
-
+
c_common_mark_addressable_vec (array);
type = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
type = build_pointer_type (type);
return tem;
name = DECL_NAME (function);
+
+ if (flag_tm)
+ tm_malloc_replacement (function);
fundecl = function;
+ /* Atomic functions have type checking/casting already done. They are
+ often rewritten and don't match the original parameter list. */
+ if (name && !strncmp (IDENTIFIER_POINTER (name), "__atomic_", 9))
+ origtypes = NULL;
}
if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)
function = function_to_pointer_conversion (loc, function);
&& !comptypes (fntype, TREE_TYPE (tem)))
{
tree return_type = TREE_TYPE (fntype);
- tree trap = build_function_call (loc, built_in_decls[BUILT_IN_TRAP],
+ tree trap = build_function_call (loc,
+ builtin_decl_explicit (BUILT_IN_TRAP),
NULL_TREE);
int i;
}
return require_complete_type (result);
}
+
+/* Build a VEC_PERM_EXPR if V0, V1 and MASK are not error_mark_nodes
+ and have vector types, V0 has the same type as V1, and the number of
+ elements of V0, V1, MASK is the same.
+
+ In case V1 is a NULL_TREE it is assumed that __builtin_shuffle was
+ called with two arguments. In this case implementation passes the
+ first argument twice in order to share the same tree code. This fact
+ could enable the mask-values being twice the vector length. This is
+ an implementation accident and this semantics is not guaranteed to
+ the user. */
+tree
+c_build_vec_perm_expr (location_t loc, tree v0, tree v1, tree mask)
+{
+ tree ret;
+ bool wrap = true;
+ bool maybe_const = false;
+ bool two_arguments = false;
+
+ if (v1 == NULL_TREE)
+ {
+ two_arguments = true;
+ v1 = v0;
+ }
+
+ if (v0 == error_mark_node || v1 == error_mark_node
+ || mask == error_mark_node)
+ return error_mark_node;
+
+ if (TREE_CODE (TREE_TYPE (mask)) != VECTOR_TYPE
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (mask))) != INTEGER_TYPE)
+ {
+ error_at (loc, "__builtin_shuffle last argument must "
+ "be an integer vector");
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (TREE_TYPE (v0)) != VECTOR_TYPE
+ || TREE_CODE (TREE_TYPE (v1)) != VECTOR_TYPE)
+ {
+ error_at (loc, "__builtin_shuffle arguments must be vectors");
+ return error_mark_node;
+ }
+
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (v0)) != TYPE_MAIN_VARIANT (TREE_TYPE (v1)))
+ {
+ error_at (loc, "__builtin_shuffle argument vectors must be of "
+ "the same type");
+ return error_mark_node;
+ }
+
+ if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (v0))
+ != TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask))
+ && TYPE_VECTOR_SUBPARTS (TREE_TYPE (v1))
+ != TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask)))
+ {
+ error_at (loc, "__builtin_shuffle number of elements of the "
+ "argument vector(s) and the mask vector should "
+ "be the same");
+ return error_mark_node;
+ }
+
+ if (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (v0))))
+ != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (mask)))))
+ {
+ error_at (loc, "__builtin_shuffle argument vector(s) inner type "
+ "must have the same size as inner type of the mask");
+ return error_mark_node;
+ }
+
+ /* Avoid C_MAYBE_CONST_EXPRs inside VEC_PERM_EXPR. */
+ v0 = c_fully_fold (v0, false, &maybe_const);
+ wrap &= maybe_const;
+
+ if (two_arguments)
+ v1 = v0 = save_expr (v0);
+ else
+ {
+ v1 = c_fully_fold (v1, false, &maybe_const);
+ wrap &= maybe_const;
+ }
+
+ mask = c_fully_fold (mask, false, &maybe_const);
+ wrap &= maybe_const;
+
+ ret = build3_loc (loc, VEC_PERM_EXPR, TREE_TYPE (v0), v0, v1, mask);
+
+ if (!wrap)
+ ret = c_wrap_maybe_const (ret, true);
+
+ return ret;
+}
\f
/* Convert the argument expressions in the vector VALUES
to the types in the list TYPELIST.
if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
{
- error_at (input_location,
+ error_at (input_location,
"too few arguments to function %qE", function);
if (fundecl && !DECL_BUILT_IN (fundecl))
inform (DECL_SOURCE_LOCATION (fundecl), "declared here");
/* Complain about anything that is not a true lvalue. In
Objective-C, skip this check for property_refs. */
- if (!objc_is_property_ref (arg)
+ if (!objc_is_property_ref (arg)
&& !lvalue_or_else (location,
arg, ((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
need to ask Objective-C to build the increment or decrement
expression for it. */
if (objc_is_property_ref (arg))
- return objc_build_incr_expr_for_property_ref (location, code,
+ return objc_build_incr_expr_for_property_ref (location, code,
arg, inc);
/* Report a read-only lvalue. */
if (val && TREE_CODE (val) == INDIRECT_REF
&& TREE_CONSTANT (TREE_OPERAND (val, 0)))
{
- tree op0 = fold_offsetof (arg, val), op1;
-
- op1 = fold_convert_loc (location, argtype, TREE_OPERAND (val, 0));
- ret = fold_build_pointer_plus_loc (location, op1, op0);
+ ret = fold_convert_loc (location, argtype, fold_offsetof_1 (arg));
goto return_build_unary_op;
}
pedwarn_init (location_t location, int opt, const char *gmsgid)
{
char *ofwhat;
-
+
/* The gmsgid may be a format string with %< and %>. */
pedwarn (location, opt, gmsgid);
ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
tree type1 = TREE_TYPE (op1);
bool integer_only_op = false;
enum stv_conv ret = stv_firstarg;
-
- gcc_assert (TREE_CODE (type0) == VECTOR_TYPE
+
+ gcc_assert (TREE_CODE (type0) == VECTOR_TYPE
|| TREE_CODE (type1) == VECTOR_TYPE);
switch (code)
{
case BIT_AND_EXPR:
integer_only_op = true;
/* ... fall through ... */
-
+
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
}
if (TREE_CODE (type0) == INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
+ && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
{
if (unsafe_conversion_p (TREE_TYPE (type1), op0, false))
{
}
else if (!integer_only_op
/* Allow integer --> real conversion if safe. */
- && (TREE_CODE (type0) == REAL_TYPE
+ && (TREE_CODE (type0) == REAL_TYPE
|| TREE_CODE (type0) == INTEGER_TYPE)
&& SCALAR_FLOAT_TYPE_P (TREE_TYPE (type1)))
{
default:
break;
}
-
+
return stv_nothing;
}
\f
int_const = int_const_or_overflow = false;
/* Do not apply default conversion in mixed vector/scalar expression. */
- if (convert_p
- && !((TREE_CODE (TREE_TYPE (op0)) == VECTOR_TYPE)
+ if (convert_p
+ && !((TREE_CODE (TREE_TYPE (op0)) == VECTOR_TYPE)
!= (TREE_CODE (TREE_TYPE (op1)) == VECTOR_TYPE)))
{
op0 = default_conversion (op0);
if ((code0 == VECTOR_TYPE) != (code1 == VECTOR_TYPE))
{
enum stv_conv convert_flag = scalar_to_vector (location, code, op0, op1);
-
+
switch (convert_flag)
{
case stv_error:
{
if (code == EQ_EXPR)
warning_at (location,
- OPT_Waddress,
+ OPT_Waddress,
"the comparison will always evaluate as %<false%> "
"for the address of %qD will never be NULL",
TREE_OPERAND (op1, 0));
return clauses;
}
+/* Create a transaction node. */
+
+tree
+c_finish_transaction (location_t loc, tree block, int flags)
+{
+ tree stmt = build_stmt (loc, TRANSACTION_EXPR, block);
+ if (flags & TM_STMT_ATTR_OUTER)
+ TRANSACTION_EXPR_OUTER (stmt) = 1;
+ if (flags & TM_STMT_ATTR_RELAXED)
+ TRANSACTION_EXPR_RELAXED (stmt) = 1;
+ return add_stmt (stmt);
+}
+
/* Make a variant type in the proper way for C/C++, propagating qualifiers
down to the element type of an array. */