Commit 0f184800 by Marek Polacek Committed by Marek Polacek

PR c++/91548 - fix detecting modifying const objects for ARRAY_REF.

This fixes a bogus "modifying a const object" error for an array that actually
isn't declared const.  The problem was how I handled ARRAY_REFs here; we
shouldn't look at the ARRAY_REF itself, but at the array its accessing.

	* constexpr.c (cxx_eval_store_expression): Don't call
	modifying_const_object_p for ARRAY_REF.

	* g++.dg/cpp1y/constexpr-tracking-const15.C: New test.
	* g++.dg/cpp1y/constexpr-tracking-const16.C: New test.
	* g++.dg/cpp1z/constexpr-tracking-const1.C: New test.

From-SVN: r277591
parent 6cd96bad
2019-10-29 Marek Polacek <polacek@redhat.com>
PR c++/91548 - fix detecting modifying const objects for ARRAY_REF.
* constexpr.c (cxx_eval_store_expression): Don't call
modifying_const_object_p for ARRAY_REF.
2019-10-29 Richard Sandiford <richard.sandiford@arm.com>
* cp-objcp-common.h (cxx_simulate_enum_decl): Declare.
......
......@@ -3910,10 +3910,6 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
tree elt = TREE_OPERAND (probe, 1);
if (TREE_CODE (elt) == FIELD_DECL && DECL_MUTABLE_P (elt))
mutable_p = true;
if (evaluated
&& modifying_const_object_p (TREE_CODE (t), probe, mutable_p)
&& const_object_being_modified == NULL_TREE)
const_object_being_modified = probe;
if (TREE_CODE (probe) == ARRAY_REF)
{
elt = eval_and_check_array_index (ctx, probe, false,
......@@ -3921,6 +3917,15 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
if (*non_constant_p)
return t;
}
/* We don't check modifying_const_object_p for ARRAY_REFs. Given
"int a[10]", an ARRAY_REF "a[2]" can be "const int", even though
the array isn't const. Instead, check "a" in the next iteration;
that will detect modifying "const int a[10]". */
else if (evaluated
&& modifying_const_object_p (TREE_CODE (t), probe,
mutable_p)
&& const_object_being_modified == NULL_TREE)
const_object_being_modified = probe;
vec_safe_push (refs, elt);
vec_safe_push (refs, TREE_TYPE (probe));
probe = ob;
......
2019-10-29 Marek Polacek <polacek@redhat.com>
PR c++/91548 - fix detecting modifying const objects for ARRAY_REF.
* g++.dg/cpp1y/constexpr-tracking-const15.C: New test.
* g++.dg/cpp1y/constexpr-tracking-const16.C: New test.
* g++.dg/cpp1z/constexpr-tracking-const1.C: New test.
2019-10-29 Martin Sebor <msebor@redhat.com>
PR testsuite/92144
......
// PR c++/91548 - fix detecting modifying const objects for ARRAY_REF.
// { dg-do compile { target c++14 } }
constexpr int& impl(const int (&array)[10], int index) {
return const_cast<int&>(array[index]);
}
struct A {
constexpr int& operator[](int i) { return impl(elems, i); }
int elems[10];
};
constexpr bool
f()
{
A arr = {};
arr[2] = true;
return false;
}
constexpr bool b = f();
// PR c++/91548 - fix detecting modifying const objects for ARRAY_REF.
// { dg-do compile { target c++14 } }
constexpr int& impl(const int (&array)[10], int index) {
return const_cast<int&>(array[index]);
}
struct A {
constexpr int& operator[](int i) { return impl(elems, i); }
const int elems[10];
};
constexpr bool
f()
{
A arr = {};
arr[2] = 1; // { dg-error "modifying a const object" }
return false;
}
constexpr bool b = f(); // { dg-message "in .constexpr. expansion of " }
// { dg-message "originally declared" "" { target *-*-* } .-1 }
// PR c++/91548 - fix detecting modifying const objects for ARRAY_REF.
// { dg-do compile { target c++17 } }
using size_t = decltype(sizeof(0));
template <typename T, size_t N>
constexpr T& impl(T const (&array)[N], size_t index) {
return const_cast<T&>(array[index]);
}
template <typename T, size_t N>
struct my_array {
constexpr T& operator[](size_t i) { return impl(elems, i); }
constexpr T const& operator[](size_t i) const { return elems[i]; }
T elems[N];
};
bool f(int i) {
static constexpr auto table = []() {
my_array<bool, 256> arr = {};
arr[2] = true;
return arr;
}();
return table[i];
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment