Fix C++ ICE with requires clauses and sequence point warning.
C++ compiler avoids internal compiler error when `requires` clauses are processed with `-Wsequence-point`.
An Internal Compiler Error (ICE) in GCC’s C++ frontend has been fixed, which occurred when processing requires clauses in conjunction with the -Wsequence-point warning. The issue stemmed from the compiler attempting to analyze expressions within the requires clause as if they were evaluated in a standard context, leading to incorrect handling of a MODOP_EXPR. By marking REQUIRES_EXPR as ‘tcc_exceptional’, the compiler now correctly identifies these expressions as non-standard and avoids walking them in contexts where they are not expected, preventing the ICE.
In Details
A bug in GCC's C++ parser, specifically in handling requires clauses within template concepts when diagnostics like -Wsequence-point are enabled, has been resolved. The compiler was incorrectly encountering MODOP_EXPRs in contexts where processing_template_decl was false, triggering an assertion in lvalue_kind. This was caused by verify_sequence_points traversing unevaluated operands of REQUIRES_EXPRs as if they were evaluated expressions. The fix involves changing the REQUIRES_EXPR tree node type to tcc_exceptional in cp-tree.def, preventing generic tree walkers from desc…
- Internal Compiler Error (ICE)
- A severe error within the compiler itself that prevents it from completing the compilation process. It indicates a bug in the compiler's logic, often triggered by specific code constructs or compiler options.
- requires clause
- A C++20 feature used in concepts to specify requirements on template arguments. It defines a set of constraints that must be satisfied by a type for it to be a valid instantiation of the concept.
- sequence point
- A point in the execution of a program where all side effects of previous evaluations are evaluated. The
-Wsequence-pointwarning flags potential issues with expressions where side effects might occur in an undefined order. - MODOP_EXPR
- A GCC internal representation (tree node) for a compound assignment operator (like +=, -=, etc.) that has been simplified or transformed during compilation.