mirror of git://gcc.gnu.org/git/gcc.git
re PR c++/77830 (internal compiler error: in output_constructor_regular_field, at varasm.c:4968, when using constexpr (with testcase))
PR c++/77830 * constexpr.c (cxx_eval_array_reference): Perform out of bounds verification even if lval is true, just allow one past the last element in that case. (cxx_eval_store_expression): Detect stores to out of bound ARRAY_REF. * g++.dg/cpp1y/pr77830.C: New test. * g++.dg/cpp0x/pr65398.C: Adjust expected diagnostics. From-SVN: r243873
This commit is contained in:
parent
31bfc9b9dd
commit
bc2a38dff8
|
|
@ -1,3 +1,12 @@
|
||||||
|
2016-12-21 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR c++/77830
|
||||||
|
* constexpr.c (cxx_eval_array_reference): Perform out of bounds
|
||||||
|
verification even if lval is true, just allow one past the last
|
||||||
|
element in that case.
|
||||||
|
(cxx_eval_store_expression): Detect stores to out of bound
|
||||||
|
ARRAY_REF.
|
||||||
|
|
||||||
2016-12-21 Jason Merrill <jason@redhat.com>
|
2016-12-21 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
Implement P0522R0, matching of template template arguments.
|
Implement P0522R0, matching of template template arguments.
|
||||||
|
|
|
||||||
|
|
@ -2183,9 +2183,9 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
|
||||||
lval,
|
lval,
|
||||||
non_constant_p, overflow_p);
|
non_constant_p, overflow_p);
|
||||||
tree index, oldidx;
|
tree index, oldidx;
|
||||||
HOST_WIDE_INT i;
|
HOST_WIDE_INT i = 0;
|
||||||
tree elem_type;
|
tree elem_type = NULL_TREE;
|
||||||
unsigned len, elem_nchars = 1;
|
unsigned len = 0, elem_nchars = 1;
|
||||||
if (*non_constant_p)
|
if (*non_constant_p)
|
||||||
return t;
|
return t;
|
||||||
oldidx = TREE_OPERAND (t, 1);
|
oldidx = TREE_OPERAND (t, 1);
|
||||||
|
|
@ -2193,10 +2193,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
|
||||||
false,
|
false,
|
||||||
non_constant_p, overflow_p);
|
non_constant_p, overflow_p);
|
||||||
VERIFY_CONSTANT (index);
|
VERIFY_CONSTANT (index);
|
||||||
if (lval && ary == oldary && index == oldidx)
|
if (!lval)
|
||||||
return t;
|
{
|
||||||
else if (lval)
|
|
||||||
return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
|
|
||||||
elem_type = TREE_TYPE (TREE_TYPE (ary));
|
elem_type = TREE_TYPE (TREE_TYPE (ary));
|
||||||
if (TREE_CODE (ary) == VIEW_CONVERT_EXPR
|
if (TREE_CODE (ary) == VIEW_CONVERT_EXPR
|
||||||
&& VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
|
&& VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
|
||||||
|
|
@ -2227,6 +2225,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
|
||||||
*non_constant_p = true;
|
*non_constant_p = true;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tree nelts;
|
tree nelts;
|
||||||
if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
|
if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
|
||||||
|
|
@ -2240,13 +2239,20 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
|
||||||
nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
|
nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
|
||||||
overflow_p);
|
overflow_p);
|
||||||
VERIFY_CONSTANT (nelts);
|
VERIFY_CONSTANT (nelts);
|
||||||
if (!tree_int_cst_lt (index, nelts))
|
if (lval
|
||||||
|
? !tree_int_cst_le (index, nelts)
|
||||||
|
: !tree_int_cst_lt (index, nelts))
|
||||||
{
|
{
|
||||||
diag_array_subscript (ctx, ary, index);
|
diag_array_subscript (ctx, ary, index);
|
||||||
*non_constant_p = true;
|
*non_constant_p = true;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lval && ary == oldary && index == oldidx)
|
||||||
|
return t;
|
||||||
|
else if (lval)
|
||||||
|
return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
|
||||||
|
|
||||||
bool found;
|
bool found;
|
||||||
if (TREE_CODE (ary) == CONSTRUCTOR)
|
if (TREE_CODE (ary) == CONSTRUCTOR)
|
||||||
{
|
{
|
||||||
|
|
@ -3281,6 +3287,47 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
|
||||||
if (*non_constant_p)
|
if (*non_constant_p)
|
||||||
return t;
|
return t;
|
||||||
|
|
||||||
|
/* cxx_eval_array_reference for lval = true allows references one past
|
||||||
|
end of array, because it does not know if it is just taking address
|
||||||
|
(which is valid), or actual dereference. Here we know it is
|
||||||
|
a dereference, so diagnose it here. */
|
||||||
|
for (tree probe = target; probe; )
|
||||||
|
{
|
||||||
|
switch (TREE_CODE (probe))
|
||||||
|
{
|
||||||
|
case ARRAY_REF:
|
||||||
|
tree nelts, ary;
|
||||||
|
ary = TREE_OPERAND (probe, 0);
|
||||||
|
if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
|
||||||
|
nelts = array_type_nelts_top (TREE_TYPE (ary));
|
||||||
|
else if (VECTOR_TYPE_P (TREE_TYPE (ary)))
|
||||||
|
nelts = size_int (TYPE_VECTOR_SUBPARTS (TREE_TYPE (ary)));
|
||||||
|
else
|
||||||
|
gcc_unreachable ();
|
||||||
|
nelts = cxx_eval_constant_expression (ctx, nelts, false,
|
||||||
|
non_constant_p, overflow_p);
|
||||||
|
VERIFY_CONSTANT (nelts);
|
||||||
|
gcc_assert (TREE_CODE (nelts) == INTEGER_CST
|
||||||
|
&& TREE_CODE (TREE_OPERAND (probe, 1)) == INTEGER_CST);
|
||||||
|
if (wi::eq_p (TREE_OPERAND (probe, 1), nelts))
|
||||||
|
{
|
||||||
|
diag_array_subscript (ctx, ary, TREE_OPERAND (probe, 1));
|
||||||
|
*non_constant_p = true;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
/* FALLTHRU */
|
||||||
|
|
||||||
|
case BIT_FIELD_REF:
|
||||||
|
case COMPONENT_REF:
|
||||||
|
probe = TREE_OPERAND (probe, 0);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
default:
|
||||||
|
probe = NULL_TREE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (target), type))
|
if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (target), type))
|
||||||
{
|
{
|
||||||
/* For initialization of an empty base, the original target will be
|
/* For initialization of an empty base, the original target will be
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
2016-12-21 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR c++/77830
|
||||||
|
* g++.dg/cpp1y/pr77830.C: New test.
|
||||||
|
* g++.dg/cpp0x/pr65398.C: Adjust expected diagnostics.
|
||||||
|
|
||||||
2016-12-21 Bernd Schmidt <bschmidt@redhat.com>
|
2016-12-21 Bernd Schmidt <bschmidt@redhat.com>
|
||||||
|
|
||||||
PR target/71321
|
PR target/71321
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ constexpr char d5 = *(&s[4] - 4);
|
||||||
constexpr char d6 = *(&s[4] - 5); // { dg-error "array subscript" }
|
constexpr char d6 = *(&s[4] - 5); // { dg-error "array subscript" }
|
||||||
|
|
||||||
/* Don't accept invalid stuff. */
|
/* Don't accept invalid stuff. */
|
||||||
constexpr char e1 = *(&s[5] - 1); // { dg-error "is not a constant expression" }
|
constexpr char e1 = *(&s[5] - 1); // { dg-error "array subscript" }
|
||||||
constexpr char e2 = *(&s[5] - 2); // { dg-error "is not a constant expression" }
|
constexpr char e2 = *(&s[5] - 2); // { dg-error "array subscript" }
|
||||||
constexpr char e3 = *(&s[5] - 3); // { dg-error "is not a constant expression" }
|
constexpr char e3 = *(&s[5] - 3); // { dg-error "array subscript" }
|
||||||
|
|
||||||
SA (c1 == 'a');
|
SA (c1 == 'a');
|
||||||
SA (c2 == 'b');
|
SA (c2 == 'b');
|
||||||
|
|
@ -53,9 +53,9 @@ constexpr char j5 = *(&l[4] - 4);
|
||||||
constexpr char j6 = *(&l[4] - 5); // { dg-error "array subscript" }
|
constexpr char j6 = *(&l[4] - 5); // { dg-error "array subscript" }
|
||||||
|
|
||||||
/* Don't accept invalid stuff. */
|
/* Don't accept invalid stuff. */
|
||||||
constexpr char k1 = *(&l[5] - 1); // { dg-error "is not a constant expression" }
|
constexpr char k1 = *(&l[5] - 1); // { dg-error "array subscript" }
|
||||||
constexpr char k2 = *(&l[5] - 2); // { dg-error "is not a constant expression" }
|
constexpr char k2 = *(&l[5] - 2); // { dg-error "array subscript" }
|
||||||
constexpr char k3 = *(&l[5] - 3); // { dg-error "is not a constant expression" }
|
constexpr char k3 = *(&l[5] - 3); // { dg-error "array subscript" }
|
||||||
|
|
||||||
SA (i1 == 'c');
|
SA (i1 == 'c');
|
||||||
SA (i2 == 'd');
|
SA (i2 == 'd');
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
// PR c++/77830
|
||||||
|
// { dg-do compile { target c++14 } }
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
struct P
|
||||||
|
{
|
||||||
|
char arr[N][1];
|
||||||
|
constexpr void foo (const char *, int);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
constexpr void
|
||||||
|
P<N>::foo (const char *, int i)
|
||||||
|
{
|
||||||
|
for (auto j = 0; j < 2; ++j)
|
||||||
|
arr[i][j] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
constexpr auto
|
||||||
|
bar (T... a)
|
||||||
|
{
|
||||||
|
const char *s[]{a...};
|
||||||
|
P<sizeof...(a)> p{};
|
||||||
|
for (auto i = 0; i < sizeof...(a); ++i)
|
||||||
|
p.foo (s[i], i);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
constexpr auto a = bar ("", ""); // { dg-error "outside the bounds of array type" }
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue