This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/70074] New: [C++14] Wrong array write access in constexpr evaluation


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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]