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