<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Bad diagnostics/possible over-aggressive bounds checking during initialization of a constexpr array in C++11"
   href="https://bugs.llvm.org/show_bug.cgi?id=32783">32783</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Bad diagnostics/possible over-aggressive bounds checking during initialization of a constexpr array in C++11
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++11
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>brycelelbach@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=18347" name="attach_18347" title="Reduced Test Case">attachment 18347</a> <a href="attachment.cgi?id=18347&action=edit" title="Reduced Test Case">[details]</a></span>
Reduced Test Case

This is a tad obscure.

In the attached code, I have a constexpr array member of a class, and a static
constexpr function that I use to initialize the array - the static constexpr
function returns the value of a single element of the array and I expand a
parameter pack into it in the array initializer.

The static constexpr function will access elements of the array that it has
previously initialized, excluding the first element. A conditional expression
is used to protect against out-of-bounds access for the first element case. I
am not 100% confident that accessing previously-initialized elements of the
array when the array itself is only partially initialized is okay in a
constexpr context (I was thinking such accesses might be UB), although I will
pout very loudly if this is not supposed to be allowed. 

Clang fails to compile this code (versions 3.9 up to current trunk as of
04/24/2017) in -std=c++11 mode and -std=c++14 mode. The error message produced
is cryptic and unhelpful to regular humans. It merely states that the constexpr
array must be initialized by a constant expression and gives no indication why
the static constexpr function is not suitable.

GCC accepts this code without issue and Clang accepts it with -std=c++1z. If
the size of the constexpr array is explicitly specified, Clang accepts the code
in -std=c++11 and -std=c++14 mode.

Based on prior experience with constexpr array operations, I suspect that the
underlying reason for the error is that Clang believes that the static
constexpr function makes an out-of-bounds array access, which is UB and not
allowed in constexpr contexts. I attempted to coax Clang into accepting this
code by SFINAEing out the initial element case, a trick I have used to fix
similar issues with constexpr out-of-bounds accesses in GCC, but had no luck
(see attached code).

There are two issues here:

(a) Clang did a poor job of explaining the cause for the error. I suspect that
this could be improved - in similar circumstances with GCC, GCC has told me why
a particular function marked constexpr is not usable in a particular constexpr
context (pointing to a particular out-of-bound access). Clang should provide
similar diagnostics.
(b) IMHO Clang should accept this code.

The attached test cases have all the relevant information for reproduction.

-- Bryce, occasional-reporter-of-obscure-C++-bugs</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>