https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126881
Bug ID: 126881
Summary: [contracts] ICE/wrong code when calling function with
precondition/postcondition that uses a parameter pack
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: waffl3x at gcc dot gnu.org
Target Milestone: ---
Forcing code generation ICEs.
https://godbolt.org/z/fxPPfcrPe
With -O1
```
template <typename... Ts>
void f(Ts... args)
pre((... && args)) {}
template void f<int>(int);
```
With -O1, postcondition (workaround for an unrelated bug.)
```
template <typename... Ts>
[[gnu::noinline]] void f(Ts const... args)
post((... && args)) {}
void go()
{
f(42);
}
```
If you allow them to inline it successfully compiles, but execution
always emits a contract violation when called. These cases do not
require -O1.
https://godbolt.org/z/dzGbh5831
```
template<typename... Args>
void f(Args... args)
pre((... && args)) {}
int main()
{
f(42);
}
```
And with a postcondition.
```
template<typename... Args>
void f(Args const... args)
post((... && args)) {}
int main()
{
f(42);
}
```
Note that reference parameters do compile in my local branch with
PR126878 fixed.
Execution works as expected when compiling with -O0 but segfaults with -O1.
The behavior is the same when called with an lvalue int.
```
template<typename... Args>
void f(Args&&... args)
pre((... && args)) {}
int main()
{
f(42);
}
```
And with a postcondition.
```
template<typename... Args>
void f(Args&&... args)
post((... && args)) {}
int main()
{
f(42);
}
```
Surprisingly, the behavior is not the same when calling f with bool or
bool&, emitting a contract violation on -O0, and segfaulting on -O1.
I suspect the behavior is the same when using a pack expansion and pack
index, but I'm not testing each permutation as this has already melted
my brain. I will (hopefully) add a bunch of test cases later.