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.

Reply via email to