Fix constexpr structured bindings used in conditions
GCC now correctly handles constexpr structured bindings used in conditional statements, resolving a lifetime issue.
This commit addresses an issue where constexpr structured bindings used as conditions in C++ code were incorrectly rejected by GCC. The compiler mistakenly flagged access to internal variables as out-of-lifetime during constant evaluation. The fix involves changing the internal representation from TARGET_EXPR to get_temp_regvar with pushdecl, which properly differentiates temporary variables from structured binding base variables.
In Details
This change affects C++ constant evaluation and structured binding decomposition in GCC's C++ frontend (cp). Specifically, it resolves a lifetime issue (PR127109) where a TARGET_EXPR created during cp_finish_decomp for structured bindings was being destructed prematurely by a CLEANUP_POINT_EXPR surrounding the initialization. This caused subsequent uses of the binding in if conditions to be considered out-of-lifetime during constant folding. The fix replaces get_internal_target_expr with get_temp_regvar and pushdecl, and uses DECL_DECOMP_BASE to manage the temporary, alignin…
- constexpr
- A C++ keyword that denotes that a variable or function may be evaluated at compile time.
- structured bindings
- A C++17 feature that allows decomposing an object (like a struct or tuple) into individual variables.
- TARGET_EXPR
- A GCC internal tree node representing a target expression, often used for assignments or deconstructions.
- CLEANUP_POINT_EXPR
- A GCC internal tree node that marks a point where cleanup actions (like destructors) need to be performed.
- constant evaluation
- The process by which the compiler evaluates expressions with constant values at compile time, rather than at runtime.
- CWG2867
- A resolution from the C++ Core Working Group addressing the lifetime of variables initialized via structured bindings when used in certain contexts.
- get_temp_regvar
- A GCC internal function to create a temporary variable that can be associated with a register.
- pushdecl
- A GCC internal mechanism to temporarily introduce a declaration into the current scope.