https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125645
Bug ID: 125645
Summary: contracts: using packs in preconditions results in
garbage
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: ivan.lazaric.gcc at gmail dot com
Target Milestone: ---
Three examples will follow, but first a utility that
clarifies the situation later:
```cpp
#ifdef LOG
#include <iostream>
bool log(auto... args) {
std::cout << "LOG";
((std::cout << " " << args), ...);
std::cout << std::endl;
return true;
}
#define PRE log(args...)
#else
#define PRE ((args == 2) && ...)
#endif
```
The precondition `((args == 2) && ...)` is expected to hold,
while the other `log()` branch is to show what values actually get used.
Example 1:
```cpp
void fn(auto... args)
pre(PRE)
{}
int main() {
fn(2);
}
```
Example 2:
```cpp
struct S {
S(auto... args)
pre(PRE)
{}
};
int main() {
S s(2);
}
```
Example 3:
```cpp
#include <vector>
struct S {
std::vector<int> member;
S(auto... args)
pre(PRE)
{}
};
int main() {
S s(2);
}
```
Compilation flags: "-std=c++26 -fcontracts"
All three examples compile successfuly, but erroneously raise
a contract violation in the `pre(PRE)` precondition.
If I compile the examples with `-DLOG` added, I get (ran 10 times each):
```
# example 1
LOG 1819242352
LOG 1819242352
LOG 1819242352
LOG 1819242352
LOG 1819242352
LOG 1819242352
LOG 1819242352
LOG 1819242352
LOG 1819242352
LOG 1819242352
# example 2
LOG 0
LOG 0
LOG 0
LOG 0
LOG 0
LOG 0
LOG 0
LOG 0
LOG 0
LOG 0
# example 3
LOG 30724
LOG 32211
LOG 29704
LOG 30743
LOG 30222
LOG 30021
LOG 30564
LOG 32462
LOG 32081
LOG 30958
```
First example on godbolt, without the LOG shenanigans:
https://godbolt.org/z/qnP4hxEEb