[Bug c++/126881] New: [contracts] ICE/wrong code when calling function with precondition/postcondition that uses a parameter pack

"waffl3x at gcc dot gnu.org via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.