[llvm-bugs] [Bug 32783] New: Bad diagnostics/possible over-aggressive bounds checking during initialization of a constexpr array in C++11

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Apr 24 23:57:45 PDT 2017


            Bug ID: 32783
           Summary: Bad diagnostics/possible over-aggressive bounds
                    checking during initialization of a constexpr array in
           Product: clang
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++11
          Assignee: unassignedclangbugs at nondot.org
          Reporter: brycelelbach at gmail.com
                CC: dgregor at apple.com, llvm-bugs at lists.llvm.org

Created attachment 18347
  --> https://bugs.llvm.org/attachment.cgi?id=18347&action=edit
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

You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170425/8d62a9a3/attachment.html>

More information about the llvm-bugs mailing list