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
  • [Bug c++/125645] New: contr... ivan.lazaric.gcc at gmail dot com via Gcc-bugs

Reply via email to