This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/70074] New: [C++14] Wrong array write access in constexpr evaluation
- From: "olegendo at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 04 Mar 2016 01:59:31 +0000
- Subject: [Bug c++/70074] New: [C++14] Wrong array write access in constexpr evaluation
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70074
Bug ID: 70074
Summary: [C++14] Wrong array write access in constexpr
evaluation
Product: gcc
Version: 5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: olegendo at gcc dot gnu.org
Target Milestone: ---
The the following program compiled with 'g++ -std=c++14 -O2 -Wall' prints:
table0: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
table1: 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15
table2: 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15
... which is a silent wrong-code bug. The numbers of all tables should be the
same.
I ran into this with gcc version 5.2.1 20151010 (Ubuntu 5.2.1-22ubuntu2). I
haven't checked with trunk or newer version of GCC 5.
#include <iostream>
#include <array>
#include <utility>
template <typename T, size_t N, size_t... I> constexpr inline std::array<T, N>
make_array_1 (const T (&chr)[N], std::index_sequence<I...>)
{
return {{ (chr[I])... }};
}
template <typename T, size_t N> constexpr inline std::array<T, N>
make_array (const T (&chr)[N])
{
return make_array_1 (chr, std::make_index_sequence<N> ());
}
template < unsigned int N, typename T > constexpr inline T reverse_bits (T val)
{
T out = 0;
for (unsigned int i = 0; i < N; ++i)
if (val & (T (1) << i))
out |= T (1) << (N - i - 1);
return out;
}
// --------------------------------------------------------------------------
constexpr inline std::array<unsigned int, 16> make_table_0 (void)
{
unsigned int result[16] = { };
for (unsigned int i = 0; i < 16; ++i)
result[reverse_bits<4> (i) & 15] = i;
return make_array (result);
}
inline std::array<unsigned int, 16> make_table_1 (void)
{
unsigned int result[16] = { };
for (unsigned int i = 0; i < 16; ++i)
result[reverse_bits<4> (i) & 15] = i;
return make_array (result);
}
constexpr inline std::array<unsigned int, 16> make_table_2 (void)
{
unsigned int result[16] = { };
for (unsigned int i = 0; i < 16; ++i)
result[i] = i;
unsigned int tmp[16] = { };
for (unsigned int i = 0; i < 16; ++i)
tmp[i] = result[i];
for (unsigned int i = 0; i < 16; ++i)
result[i] = tmp[reverse_bits<4> (i) & 15];
return make_array (result);
}
static const auto table0 = make_table_0 ();
static const auto table1 = make_table_1 ();
static const auto table2 = make_table_2 ();
int main (void)
{
std::cout << "table0: ";
for (auto&& x : table0)
std::cout << x << " ";
std::cout << std::endl;
std::cout << "table1: ";
for (auto&& x : table1)
std::cout << x << " ";
std::cout << std::endl;
std::cout << "table2: ";
for (auto&& x : table2)
std::cout << x << " ";
std::cout << std::endl;
return 0;
}