aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog18
-rw-r--r--gcc/c/c-convert.c16
-rw-r--r--gcc/c/c-typeck.c71
3 files changed, 74 insertions, 31 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index f1d73e4..8cea3f5 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,21 @@
+2019-11-08 Richard Sandiford <richard.sandiford@arm.com>
+
+ * c-convert.c (convert): Only handle vector conversions if one of
+ the types satisfies gnu_vector_type_p or if -flax-vector-conversions
+ allows it.
+ * c-typeck.c (build_array_ref): Only allow vector indexing if the
+ vectors satisfy gnu_vector_type_p.
+ (build_unary_op): Only allow unary operators to be applied to
+ vectors if they satisfy gnu_vector_type_p.
+ (digest_init): Only allow by-element initialization of vectors
+ if they satisfy gnu_vector_type_p.
+ (really_start_incremental_init): Likewise.
+ (push_init_level): Likewise.
+ (pop_init_level): Likewise.
+ (process_init_element): Likewise.
+ (build_binary_op): Only allow binary operators to be applied to
+ vectors if they satisfy gnu_vector_type_p.
+
2019-11-08 Joseph Myers <joseph@codesourcery.com>
* c-decl.c (grokparms): Convert () in a function definition to
diff --git a/gcc/c/c-convert.c b/gcc/c/c-convert.c
index f0f8460..21b127d 100644
--- a/gcc/c/c-convert.c
+++ b/gcc/c/c-convert.c
@@ -147,8 +147,20 @@ convert (tree type, tree expr)
goto maybe_fold;
case VECTOR_TYPE:
- ret = convert_to_vector (type, e);
- goto maybe_fold;
+ if (gnu_vector_type_p (type)
+ || gnu_vector_type_p (TREE_TYPE (e))
+ /* Allow conversions between compatible non-GNU vector types
+ when -flax-vector-conversions is passed. The whole purpose
+ of the option is to bend the normal type rules and accept
+ nonconforming code. */
+ || (flag_lax_vector_conversions
+ && VECTOR_TYPE_P (TREE_TYPE (e))
+ && vector_types_convertible_p (type, TREE_TYPE (e), false)))
+ {
+ ret = convert_to_vector (type, e);
+ goto maybe_fold;
+ }
+ break;
case RECORD_TYPE:
case UNION_TYPE:
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index c733950..793d10e 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -2610,7 +2610,7 @@ build_array_ref (location_t loc, tree array, tree index)
if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE
/* Allow vector[index] but not index[vector]. */
- && !VECTOR_TYPE_P (TREE_TYPE (array)))
+ && !gnu_vector_type_p (TREE_TYPE (array)))
{
if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE)
@@ -4360,7 +4360,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
associativity, but won't generate any code. */
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE
- || typecode == VECTOR_TYPE))
+ || gnu_vector_type_p (TREE_TYPE (arg))))
{
error_at (location, "wrong type argument to unary plus");
return error_mark_node;
@@ -4373,7 +4373,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
case NEGATE_EXPR:
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE
- || typecode == VECTOR_TYPE))
+ || gnu_vector_type_p (TREE_TYPE (arg))))
{
error_at (location, "wrong type argument to unary minus");
return error_mark_node;
@@ -4385,7 +4385,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
case BIT_NOT_EXPR:
/* ~ works on integer types and non float vectors. */
if (typecode == INTEGER_TYPE
- || (typecode == VECTOR_TYPE
+ || (gnu_vector_type_p (TREE_TYPE (arg))
&& !VECTOR_FLOAT_TYPE_P (TREE_TYPE (arg))))
{
tree e = arg;
@@ -4571,7 +4571,8 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
if (typecode != POINTER_TYPE && typecode != FIXED_POINT_TYPE
&& typecode != INTEGER_TYPE && typecode != REAL_TYPE
- && typecode != COMPLEX_TYPE && typecode != VECTOR_TYPE)
+ && typecode != COMPLEX_TYPE
+ && !gnu_vector_type_p (TREE_TYPE (arg)))
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
error_at (location, "wrong type argument to increment");
@@ -7858,7 +7859,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
TYPE_MAIN_VARIANT (type))
|| (code == ARRAY_TYPE
&& comptypes (TREE_TYPE (inside_init), type))
- || (code == VECTOR_TYPE
+ || (gnu_vector_type_p (type)
&& comptypes (TREE_TYPE (inside_init), type))
|| (code == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
@@ -8356,7 +8357,7 @@ really_start_incremental_init (tree type)
constructor_unfilled_index = constructor_index;
}
- else if (VECTOR_TYPE_P (constructor_type))
+ else if (gnu_vector_type_p (constructor_type))
{
/* Vectors are like simple fixed-size arrays. */
constructor_max_index =
@@ -8530,7 +8531,7 @@ push_init_level (location_t loc, int implicit,
constructor_unfilled_fields = constructor_fields;
constructor_bit_index = bitsize_zero_node;
}
- else if (VECTOR_TYPE_P (constructor_type))
+ else if (gnu_vector_type_p (constructor_type))
{
/* Vectors are like simple fixed-size arrays. */
constructor_max_index =
@@ -8719,7 +8720,7 @@ pop_init_level (location_t loc, int implicit,
;
else if (!RECORD_OR_UNION_TYPE_P (constructor_type)
&& TREE_CODE (constructor_type) != ARRAY_TYPE
- && !VECTOR_TYPE_P (constructor_type))
+ && !gnu_vector_type_p (constructor_type))
{
/* A nonincremental scalar initializer--just return
the element, after verifying there is just one. */
@@ -9945,7 +9946,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
last_init_list_comma),
true, braced_init_obstack);
else if ((TREE_CODE (constructor_type) == ARRAY_TYPE
- || VECTOR_TYPE_P (constructor_type))
+ || gnu_vector_type_p (constructor_type))
&& constructor_max_index
&& tree_int_cst_lt (constructor_max_index,
constructor_index))
@@ -10046,7 +10047,8 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
&& value.value != error_mark_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
- || fieldcode == UNION_TYPE || fieldcode == VECTOR_TYPE))
+ || fieldcode == UNION_TYPE
+ || gnu_vector_type_p (fieldtype)))
{
push_init_level (loc, 1, braced_init_obstack);
continue;
@@ -10137,7 +10139,8 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
&& value.value != error_mark_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
- || fieldcode == UNION_TYPE || fieldcode == VECTOR_TYPE))
+ || fieldcode == UNION_TYPE
+ || gnu_vector_type_p (fieldtype)))
{
push_init_level (loc, 1, braced_init_obstack);
continue;
@@ -10179,7 +10182,8 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
&& value.value != error_mark_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != elttype
&& (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
- || eltcode == UNION_TYPE || eltcode == VECTOR_TYPE))
+ || eltcode == UNION_TYPE
+ || gnu_vector_type_p (elttype)))
{
push_init_level (loc, 1, braced_init_obstack);
continue;
@@ -10215,7 +10219,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
constructor_unfilled_index. */
constructor_unfilled_index = constructor_index;
}
- else if (VECTOR_TYPE_P (constructor_type))
+ else if (gnu_vector_type_p (constructor_type))
{
tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
@@ -11559,7 +11563,8 @@ build_binary_op (location_t location, enum tree_code code,
/* In case when one of the operands of the binary operation is
a vector and another is a scalar -- convert scalar to vector. */
- if ((code0 == VECTOR_TYPE) != (code1 == VECTOR_TYPE))
+ if ((gnu_vector_type_p (type0) && code1 != VECTOR_TYPE)
+ || (gnu_vector_type_p (type1) && code0 != VECTOR_TYPE))
{
enum stv_conv convert_flag = scalar_to_vector (location, code, op0, op1,
true);
@@ -11654,10 +11659,12 @@ build_binary_op (location_t location, enum tree_code code,
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
|| code0 == FIXED_POINT_TYPE
- || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
+ || code0 == COMPLEX_TYPE
+ || gnu_vector_type_p (type0))
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|| code1 == FIXED_POINT_TYPE
- || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
+ || code1 == COMPLEX_TYPE
+ || gnu_vector_type_p (type1)))
{
enum tree_code tcode0 = code0, tcode1 = code1;
@@ -11688,8 +11695,8 @@ build_binary_op (location_t location, enum tree_code code,
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
shorten = -1;
/* Allow vector types which are not floating point types. */
- else if (code0 == VECTOR_TYPE
- && code1 == VECTOR_TYPE
+ else if (gnu_vector_type_p (type0)
+ && gnu_vector_type_p (type1)
&& !VECTOR_FLOAT_TYPE_P (type0)
&& !VECTOR_FLOAT_TYPE_P (type1))
common = 1;
@@ -11700,7 +11707,8 @@ build_binary_op (location_t location, enum tree_code code,
doing_div_or_mod = true;
warn_for_div_by_zero (location, op1);
- if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ if (gnu_vector_type_p (type0)
+ && gnu_vector_type_p (type1)
&& TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
&& TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
common = 1;
@@ -11779,7 +11787,8 @@ build_binary_op (location_t location, enum tree_code code,
Also set SHORT_SHIFT if shifting rightward. */
case RSHIFT_EXPR:
- if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ if (gnu_vector_type_p (type0)
+ && gnu_vector_type_p (type1)
&& TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
&& TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
&& known_eq (TYPE_VECTOR_SUBPARTS (type0),
@@ -11789,7 +11798,7 @@ build_binary_op (location_t location, enum tree_code code,
converted = 1;
}
else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE
- || (code0 == VECTOR_TYPE
+ || (gnu_vector_type_p (type0)
&& TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE))
&& code1 == INTEGER_TYPE)
{
@@ -11838,7 +11847,8 @@ build_binary_op (location_t location, enum tree_code code,
break;
case LSHIFT_EXPR:
- if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ if (gnu_vector_type_p (type0)
+ && gnu_vector_type_p (type1)
&& TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
&& TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
&& known_eq (TYPE_VECTOR_SUBPARTS (type0),
@@ -11848,7 +11858,7 @@ build_binary_op (location_t location, enum tree_code code,
converted = 1;
}
else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE
- || (code0 == VECTOR_TYPE
+ || (gnu_vector_type_p (type0)
&& TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE))
&& code1 == INTEGER_TYPE)
{
@@ -11907,7 +11917,7 @@ build_binary_op (location_t location, enum tree_code code,
case EQ_EXPR:
case NE_EXPR:
- if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
+ if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
{
tree intt;
if (!vector_types_compatible_elements_p (type0, type1))
@@ -12075,7 +12085,7 @@ build_binary_op (location_t location, enum tree_code code,
case GE_EXPR:
case LT_EXPR:
case GT_EXPR:
- if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
+ if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
{
tree intt;
if (!vector_types_compatible_elements_p (type0, type1))
@@ -12222,7 +12232,8 @@ build_binary_op (location_t location, enum tree_code code,
if (code0 == ERROR_MARK || code1 == ERROR_MARK)
return error_mark_node;
- if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ if (gnu_vector_type_p (type0)
+ && gnu_vector_type_p (type1)
&& (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
|| !vector_types_compatible_elements_p (type0, type1)))
{
@@ -12237,10 +12248,12 @@ build_binary_op (location_t location, enum tree_code code,
}
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
- || code0 == FIXED_POINT_TYPE || code0 == VECTOR_TYPE)
+ || code0 == FIXED_POINT_TYPE
+ || gnu_vector_type_p (type0))
&&
(code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE
- || code1 == FIXED_POINT_TYPE || code1 == VECTOR_TYPE))
+ || code1 == FIXED_POINT_TYPE
+ || gnu_vector_type_p (type1)))
{
bool first_complex = (code0 == COMPLEX_TYPE);
bool second_complex = (code1 == COMPLEX_TYPE);