Open llvmbot opened 7 years ago
Reduced testcase:
void f(int i) {
[&](auto) { static_assert(&i != nullptr); }(0);
}
It appears that the problem is that we do not capture i
when processing the generic lambda. Then when we come to instantiate it, we instantiate a reference to i
which is invalid because i
was not captured.
It looks like the problem is that we never do "full expression" checking on the operand of static_assert
, so we don't ever promote the list of "potential ODR uses" from the expression into captures. That in turn means that even trivial perturbations of the source will make the bug go away by triggering the pending capture, such as:
[&](auto) { static_assert(&i != nullptr); 0; }(0);
Extended Description
I originally posted this as a question on Stack Overflow and it was suggested to me to file this as a bug here (https://stackoverflow.com/questions/44355720).
The following program compiles successfully using Clang versions
3.8.0-2ubuntu4
,4.0.1-svn304242-1~exp1
and5.0.0-svn304672-1~exp1
using-std=c++14
. The Boost library version is 1.61.0.========== BEGIN SOURCE 1 ==========
========== END SOURCE 1 ==========
The test is quite non-sensical but that is not the point. Consider now an alternative version where the test is put inside the static_assert:
========== BEGIN SOURCE 2 ==========
========== END SOURCE 2 ==========
I get a bunch of compile errors saying:
The curious thing is, that when accessing i before the
static_assert
, everything compiles again:========== BEGIN SOURCE 3 ==========
========== END SOURCE 3 ==========
Note in particular that the added statement is unrelated to the
static_assert
.