https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127766
Bug ID: 127766
Summary: __builtin_structured_binding_size` rejects a class
template specialization that has not been instantiated
yet
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: bic60176 at gmail dot com
Target Milestone: ---
```c++
template<class T> struct Pair { T a; T b; };
int main() { return __builtin_structured_binding_size(Pair<int>) == 2 ? 0 : 1;
}
```
`g++ -O2` rejects this with "structured binding refers to incomplete class type
'Pair<int>'". Adding
`static_assert(sizeof(Pair<int>) != 0, "");` before `main` makes it compile,
and the trait then yields 2. In a SFINAE
context the same situation silently gives "no structured binding size":
```c++
typedef decltype(sizeof(0)) size_t_;
template<class T, size_t_ = __builtin_structured_binding_size(T)> char
probe(int);
template<class T> long probe(...);
template<class T> constexpr bool has_sbs = sizeof(probe<T>(0)) == 1;
template<class T> struct Pair { T a; T b; };
static_assert(!has_sbs<Pair<int>>); // accepted
int main() { Pair<int> p{}; auto [x, y] = p; return x + y; }
```
The manual says the trait returns the structured binding size of the type, and
diagnoses (or fails in SFINAE) only
when the type has none. `cp_decomp_size` (gcc/cp/decl.cc) calls `complete_type`
only when `processing_template_decl`,
so an implicit instantiation is never triggered outside a template; the other
type traits complete their operands in
`finish_trait_expr`. Calling `complete_type` unconditionally there would fix
it.