Bootstrapped and regression tested on x86_64.
c: harmonize handling of arrays
This code harmonizes the handling of arrays in C by consistently
using build_index_type instead of build_range_type when creating
arrays and using top_array_vla_pp to detect top-level VLAs.
gcc/c-family/ChangeLog:
* c-common.cc (complete_array_type): Use build_index_type.
* c-ubsan.cc (ubsan_instrument_bounds_pointer_address):
Likewise.
gcc/c/ChangeLog:
* c-decl.cc (grokdeclarator): Likewise.
* c-typeck.cc (c_verify_type,c_build_array_type,
c_expr_countof_expr,comptypes_internal): Use top_array_vla_p.
(top_array_vla_p): Rename to use _p convention and simplify.
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index a98f9b50ece..8904913c82f 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -7455,9 +7455,7 @@ complete_array_type (tree *ptype, tree initial_value,
bool do_default)
TYPE_LANG_FLAG_? bits that the front end may have set. */
main_type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
TREE_TYPE (main_type) = unqual_elt;
- TYPE_DOMAIN (main_type)
- = build_range_type (TREE_TYPE (maxindex),
- build_int_cst (TREE_TYPE (maxindex), 0), maxindex);
+ TYPE_DOMAIN (main_type) = build_index_type (maxindex);
TYPE_TYPELESS_STORAGE (main_type) = TYPE_TYPELESS_STORAGE (type);
layout_type (main_type);
diff --git a/gcc/c-family/c-ubsan.cc b/gcc/c-family/c-ubsan.cc
index c466f01c4b6..83c6e27d614 100644
--- a/gcc/c-family/c-ubsan.cc
+++ b/gcc/c-family/c-ubsan.cc
@@ -597,7 +597,7 @@ ubsan_instrument_bounds_pointer_address (location_t loc,
tree pointer_addr,
*index = save_expr (*index);
/* Create an array_type for the corresponding pointer array. */
- tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
+ tree itype = build_index_type (NULL_TREE);
/* The array's element type can be get from the return type of the call to
.ACCESS_WITH_SIZE. */
tree element_type = TREE_TYPE (TREE_TYPE (call));
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 60660a7f329..1b2f2b4edec 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -7470,7 +7470,7 @@ grokdeclarator (const struct c_declarator *declarator,
an unsigned index type, which is what we'll
get with build_index_type. Create an
open-ended range instead. */
- itype = build_range_type (sizetype, size, NULL_TREE);
+ itype = build_index_type (NULL_TREE);
}
else
{
@@ -8154,8 +8154,7 @@ grokdeclarator (const struct c_declarator *declarator,
pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not "
"support flexible array members");
type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
- TYPE_DOMAIN (type) = build_range_type (sizetype, size_zero_node,
- NULL_TREE);
+ TYPE_DOMAIN (type) = build_index_type (NULL_TREE);
if (orig_qual_indirect == 0)
orig_qual_type = NULL_TREE;
}
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index fade28a392b..d32d3c6025e 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -141,6 +141,8 @@ static bool comptypes_internal (const_tree, const_tree,
struct comptypes_data *data);
static bool comptypes_check_for_composite (tree t1, tree t2);
static bool handle_counted_by_p (tree);
+static bool top_array_vla_p (const_tree type);
+
/* Return true if EXP is a null pointer constant, false otherwise. */
@@ -407,9 +409,7 @@ c_verify_type (tree type)
/* An array has variable size if and only if it has a non-constant
dimensions or its element type has variable size. */
if ((C_TYPE_VARIABLE_SIZE (TREE_TYPE (type))
- || (TYPE_DOMAIN (type) && TYPE_MAX_VALUE (TYPE_DOMAIN (type))
- && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
- != INTEGER_CST))
+ || top_array_vla_p (type))
!= C_TYPE_VARIABLE_SIZE (type))
return false;
/* If the element type or the array has variable size, then the
@@ -498,8 +498,7 @@ c_build_array_type (tree type, tree domain)
tree ret = build_array_type (type, domain, typeless);
- if (domain && TYPE_MAX_VALUE (domain)
- && TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST)
+ if (top_array_vla_p (ret))
{
C_TYPE_VARIABLE_SIZE (ret) = 1;
C_TYPE_VARIABLY_MODIFIED (ret) = 1;
@@ -824,14 +823,8 @@ composite_type_internal (tree t1, tree t2, tree cond,
bool d1_zero = d1 == NULL_TREE || !TYPE_MAX_VALUE (d1);
bool d2_zero = d2 == NULL_TREE || !TYPE_MAX_VALUE (d2);
- bool d1_variable, d2_variable;
-
- d1_variable = (!d1_zero
- && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
- || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST));
- d2_variable = (!d2_zero
- && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
- || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST));
+ bool d1_variable = top_array_vla_p (t1);
+ bool d2_variable = top_array_vla_p (t2);
bool use1 = d1 && (d2_variable || d2_zero || !d1_variable);
bool use2 = d2 && (d1_variable || d1_zero || !d2_variable);
@@ -1795,8 +1788,6 @@ comptypes_internal (const_tree type1, const_tree type2,
{
tree d1 = TYPE_DOMAIN (t1);
tree d2 = TYPE_DOMAIN (t2);
- bool d1_variable, d2_variable;
- bool d1_zero, d2_zero;
/* Target types must match incl. qualifiers. */
if (!comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2), data))
@@ -1811,15 +1802,11 @@ comptypes_internal (const_tree type1, const_tree type2,
if (d1 == NULL_TREE || d2 == NULL_TREE || d1 == d2)
return true;
- d1_zero = !TYPE_MAX_VALUE (d1);
- d2_zero = !TYPE_MAX_VALUE (d2);
+ bool d1_zero = !TYPE_MAX_VALUE (d1);
+ bool d2_zero = !TYPE_MAX_VALUE (d2);
- d1_variable = (!d1_zero
- && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
- || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST));
- d2_variable = (!d2_zero
- && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
- || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST));
+ bool d1_variable = top_array_vla_p (t1);
+ bool d2_variable = top_array_vla_p (t2);
if (d1_variable != d2_variable)
data->different_types_p = true;
@@ -4088,24 +4075,22 @@ c_expr_sizeof_type (location_t loc, struct c_type_name
*t)
}
static bool
-is_top_array_vla (tree type)
+top_array_vla_p (const_tree type)
{
- bool zero, var;
- tree d;
-
if (TREE_CODE (type) != ARRAY_TYPE)
return false;
if (!COMPLETE_TYPE_P (type))
return false;
- d = TYPE_DOMAIN (type);
- zero = !TYPE_MAX_VALUE (d);
- if (zero)
+ tree d = TYPE_DOMAIN (type);
+
+ if (!d)
+ return false;
+ if (!TYPE_MAX_VALUE (d))
return false;
- var = (TREE_CODE (TYPE_MIN_VALUE (d)) != INTEGER_CST
- || TREE_CODE (TYPE_MAX_VALUE (d)) != INTEGER_CST);
- return var;
+ return TREE_CODE (TYPE_MAX_VALUE (d)) != INTEGER_CST
+ || TREE_CODE (TYPE_MIN_VALUE (d)) != INTEGER_CST;
}
/* Return the result of countof applied to EXPR. */
@@ -4134,7 +4119,7 @@ c_expr_countof_expr (location_t loc, struct c_expr expr)
ret.original_code = COUNTOF_EXPR;
ret.original_type = NULL;
ret.m_decimal = 0;
- if (is_top_array_vla (TREE_TYPE (folded_expr)))
+ if (top_array_vla_p (TREE_TYPE (folded_expr)))
{
/* countof is evaluated when given a vla. */
ret.value = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret.value),
@@ -4142,7 +4127,7 @@ c_expr_countof_expr (location_t loc, struct c_expr expr)
C_MAYBE_CONST_EXPR_NON_CONST (ret.value) = !expr_const_operands;
SET_EXPR_LOCATION (ret.value, loc);
}
- pop_maybe_used (is_top_array_vla (TREE_TYPE (folded_expr)));
+ pop_maybe_used (top_array_vla_p (TREE_TYPE (folded_expr)));
}
return ret;
}
@@ -4172,7 +4157,7 @@ c_expr_countof_type (location_t loc, struct c_type_name
*t)
}
else
if ((type_expr || TREE_CODE (ret.value) == INTEGER_CST)
- && is_top_array_vla (type))
+ && top_array_vla_p (type))
{
/* If the type is a [*] array, it is a VLA but is represented as
having a size of zero. In such a case we must ensure that
@@ -4187,7 +4172,7 @@ c_expr_countof_type (location_t loc, struct c_type_name
*t)
type_expr, ret.value);
C_MAYBE_CONST_EXPR_NON_CONST (ret.value) = !type_expr_const;
}
- pop_maybe_used (type != error_mark_node ? is_top_array_vla (type) : false);
+ pop_maybe_used (type != error_mark_node ? top_array_vla_p (type) : false);
return ret;
}