aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c72
1 files changed, 31 insertions, 41 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 383b47d29ed..675342efcd9 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8589,33 +8589,24 @@ stabilize_vla_size (tree size)
cp_walk_tree (&size, stabilize_save_expr_r, &pset, &pset);
}
-/* Helper function for compute_array_index_type. Look for SIZEOF_EXPR
- not inside of SAVE_EXPR and fold them. */
+/* Reduce a SIZEOF_EXPR to its value. */
-static tree
-fold_sizeof_expr_r (tree *expr_p, int *walk_subtrees, void *data)
-{
- tree expr = *expr_p;
- if (TREE_CODE (expr) == SAVE_EXPR || TYPE_P (expr))
- *walk_subtrees = 0;
- else if (TREE_CODE (expr) == SIZEOF_EXPR)
- {
- *(bool *)data = true;
- if (SIZEOF_EXPR_TYPE_P (expr))
- expr = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (expr, 0)),
- SIZEOF_EXPR, false);
- else if (TYPE_P (TREE_OPERAND (expr, 0)))
- expr = cxx_sizeof_or_alignof_type (TREE_OPERAND (expr, 0), SIZEOF_EXPR,
- false);
- else
- expr = cxx_sizeof_or_alignof_expr (TREE_OPERAND (expr, 0), SIZEOF_EXPR,
- false);
- if (expr == error_mark_node)
- expr = size_one_node;
- *expr_p = expr;
- *walk_subtrees = 0;
- }
- return NULL;
+tree
+fold_sizeof_expr (tree t)
+{
+ tree r;
+ if (SIZEOF_EXPR_TYPE_P (t))
+ r = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (t, 0)),
+ SIZEOF_EXPR, false);
+ else if (TYPE_P (TREE_OPERAND (t, 0)))
+ r = cxx_sizeof_or_alignof_type (TREE_OPERAND (t, 0), SIZEOF_EXPR,
+ false);
+ else
+ r = cxx_sizeof_or_alignof_expr (TREE_OPERAND (t, 0), SIZEOF_EXPR,
+ false);
+ if (r == error_mark_node)
+ r = size_one_node;
+ return r;
}
/* Given the SIZE (i.e., number of elements) in an array, compute an
@@ -8708,7 +8699,18 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
SET_TYPE_STRUCTURAL_EQUALITY (itype);
return itype;
}
-
+
+ if (TREE_CODE (size) != INTEGER_CST)
+ {
+ tree folded = cp_fully_fold (size);
+ if (TREE_CODE (folded) == INTEGER_CST)
+ pedwarn (location_of (size), OPT_Wpedantic,
+ "size of array is not an integral constant-expression");
+ /* Use the folded result for VLAs, too; it will have resolved
+ SIZEOF_EXPR. */
+ size = folded;
+ }
+
/* Normally, the array-bound will be a constant. */
if (TREE_CODE (size) == INTEGER_CST)
{
@@ -8795,7 +8797,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
cp_convert (ssizetype, integer_one_node,
complain),
complain);
- itype = fold (itype);
+ itype = maybe_constant_value (itype);
processing_template_decl = saved_processing_template_decl;
if (!TREE_CONSTANT (itype))
@@ -8803,18 +8805,6 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
/* A variable sized array. */
itype = variable_size (itype);
- if (TREE_CODE (itype) != SAVE_EXPR)
- {
- /* Look for SIZEOF_EXPRs in itype and fold them, otherwise
- they might survive till gimplification. */
- tree newitype = itype;
- bool found = false;
- cp_walk_tree_without_duplicates (&newitype,
- fold_sizeof_expr_r, &found);
- if (found)
- itype = variable_size (fold (newitype));
- }
-
stabilize_vla_size (itype);
if (flag_sanitize & SANITIZE_VLA
@@ -13514,7 +13504,7 @@ incremented enumerator value is too large for %<long%>");
"type %<%T%>", value, ENUM_UNDERLYING_TYPE (enumtype));
/* Convert the value to the appropriate type. */
- value = convert (ENUM_UNDERLYING_TYPE (enumtype), value);
+ value = fold_convert (ENUM_UNDERLYING_TYPE (enumtype), value);
}
}