--- gcc/cp/constraint.cc.jj	2024-07-24 15:47:15.207477692 +0200
+++ gcc/cp/constraint.cc	2024-07-24 18:58:32.646330544 +0200
@@ -83,13 +83,13 @@ struct subst_info
   { }
 
   /* True if we should not diagnose errors.  */
-  bool quiet() const
+  bool quiet () const
   {
     return !(complain & tf_warning_or_error);
   }
 
   /* True if we should diagnose errors.  */
-  bool noisy() const
+  bool noisy () const
   {
     return !quiet ();
   }
@@ -148,7 +148,7 @@ struct sat_info : subst_info
 
 static tree constraint_satisfaction_value (tree, tree, sat_info);
 
-/* True if T is known to be some type other than bool. Note that this
+/* True if T is known to be some type other than bool.  Note that this
    is false for dependent types and errors.  */
 
 static inline bool
@@ -245,8 +245,8 @@ combine_constraint_expressions (tree lhs
   return finish_constraint_and_expr (UNKNOWN_LOCATION, lhs, rhs);
 }
 
-/* Extract the template-id from a concept check. For standard and variable
-   checks, this is simply T. For function concept checks, this is the
+/* Extract the template-id from a concept check.  For standard and variable
+   checks, this is simply T.  For function concept checks, this is the
    called function.  */
 
 tree
@@ -278,7 +278,7 @@ get_concept_check_template (tree t)
 ---------------------------------------------------------------------------*/
 
 /* This facility is used to resolve constraint checks from requirement
-   expressions. A constraint check is a call to a function template declared
+   expressions.  A constraint check is a call to a function template declared
    with the keyword 'concept'.
 
    The result of resolution is a pair (a TREE_LIST) whose value is the
@@ -288,9 +288,9 @@ get_concept_check_template (tree t)
 /* Given an overload set OVL, try to find a unique definition that can be
    instantiated by the template arguments ARGS.
 
-   This function is not called for arbitrary call expressions. In particular,
+   This function is not called for arbitrary call expressions.  In particular,
    the call expression must be written with explicit template arguments
-   and no function arguments. For example:
+   and no function arguments.  For example:
 
         f<T, U>()
 
@@ -309,13 +309,13 @@ resolve_function_concept_overload (tree
       if (TREE_CODE (tmpl) != TEMPLATE_DECL)
         continue;
 
-      /* Don't try to deduce checks for non-concepts. We often end up trying
+      /* Don't try to deduce checks for non-concepts.  We often end up trying
          to resolve constraints in functional casts as part of a
-         postfix-expression. We can save time and headaches by not
+	 postfix-expression.  We can save time and headaches by not
          instantiating those declarations.
 
          NOTE: This masks a potential error, caused by instantiating
-         non-deduced contexts using placeholder arguments. */
+	 non-deduced contexts using placeholder arguments.  */
       tree fn = DECL_TEMPLATE_RESULT (tmpl);
       if (DECL_ARGUMENTS (fn))
         continue;
@@ -346,7 +346,7 @@ resolve_function_concept_overload (tree
 }
 
 /* Determine if the call expression CALL is a constraint check, and
-   return the concept declaration and arguments being checked. If CALL
+   return the concept declaration and arguments being checked.  If CALL
    does not denote a constraint check, return NULL.  */
 
 tree
@@ -356,7 +356,7 @@ resolve_function_concept_check (tree cal
 
   /* A constraint check must be only a template-id expression.
      If it's a call to a base-link, its function(s) should be a
-     template-id expression. If this is not a template-id, then
+     template-id expression.  If this is not a template-id, then
      it cannot be a concept-check.  */
   tree target = CALL_EXPR_FN (call);
   if (BASELINK_P (target))
@@ -381,10 +381,10 @@ resolve_function_concept_check (tree cal
 }
 
 /* Returns a pair containing the checked concept and its associated
-   prototype parameter. The result is a TREE_LIST whose TREE_VALUE
+   prototype parameter.  The result is a TREE_LIST whose TREE_VALUE
    is the concept (non-template) and whose TREE_PURPOSE contains
    the converted template arguments, including the deduced prototype
-   parameter (in position 0). */
+   parameter (in position 0).  */
 
 tree
 resolve_concept_check (tree check)
@@ -415,7 +415,7 @@ resolve_concept_check (tree check)
 
 /* Given a call expression or template-id expression to a concept EXPR
    possibly including a wildcard, deduce the concept being checked and
-   the prototype parameter. Returns true if the constraint and prototype
+   the prototype parameter.  Returns true if the constraint and prototype
    can be deduced and false otherwise.  Note that the CHECK and PROTO
    arguments are set to NULL_TREE if this returns false.  */
 
@@ -453,7 +453,7 @@ finish_type_constraints (tree spec, tree
   if (check == error_mark_node)
     return std::make_pair (error_mark_node, NULL_TREE);
 
-  /* Extract the concept and prototype parameter from the check. */
+  /* Extract the concept and prototype parameter from the check.  */
   tree con;
   tree proto;
   if (!deduce_constrained_parameter (check, con, proto))
@@ -466,7 +466,7 @@ finish_type_constraints (tree spec, tree
                        Expansion of concept definitions
 ---------------------------------------------------------------------------*/
 
-/* Returns the expression of a function concept. */
+/* Returns the expression of a function concept.  */
 
 static tree
 get_returned_expression (tree fn)
@@ -483,7 +483,7 @@ get_returned_expression (tree fn)
   return TREE_OPERAND (body, 0);
 }
 
-/* Returns the initializer of a variable concept. */
+/* Returns the initializer of a variable concept.  */
 
 static tree
 get_variable_initializer (tree var)
@@ -630,7 +630,7 @@ struct norm_info : subst_info
       initial_parms = current_template_parms;
   }
 
-  void update_context(tree expr, tree args)
+  void update_context (tree expr, tree args)
   {
     if (generate_diagnostics)
       {
@@ -643,7 +643,7 @@ struct norm_info : subst_info
   /* Returns the template parameters that are in scope for the current
      normalization context.  */
 
-  tree ctx_parms()
+  tree ctx_parms ()
   {
     if (in_decl)
       return DECL_TEMPLATE_PARMS (in_decl);
@@ -651,9 +651,9 @@ struct norm_info : subst_info
       return initial_parms;
   }
 
-  /* Provides information about the source of a constraint. This is a
+  /* Provides information about the source of a constraint.  This is a
      TREE_LIST whose VALUE is either a concept check or a constrained
-     declaration. The PURPOSE, for concept checks is a parameter mapping
+     declaration.  The PURPOSE, for concept checks is a parameter mapping
      for that check.  */
 
   tree context = NULL_TREE;
@@ -672,7 +672,7 @@ struct norm_info : subst_info
 static tree normalize_expression (tree, tree, norm_info);
 
 /* Transform a logical-or or logical-and expression into either
-   a conjunction or disjunction. */
+   a conjunction or disjunction.  */
 
 static tree
 normalize_logical_operation (tree t, tree args, tree_code c, norm_info info)
@@ -681,9 +681,8 @@ normalize_logical_operation (tree t, tre
   tree t1 = normalize_expression (TREE_OPERAND (t, 1), args, info);
 
   /* Build a new info object for the constraint.  */
-  tree ci = info.generate_diagnostics
-    ? build_tree_list (t, info.context)
-    : NULL_TREE;
+  tree ci = (info.generate_diagnostics
+	     ? build_tree_list (t, info.context) : NULL_TREE);
 
   return build2 (c, ci, t0, t1);
 }
@@ -744,7 +743,7 @@ normalize_concept_check (tree check, tre
       tmpl = OVL_FIRST (tmpl);
     }
 
-  /* Substitute through the arguments of the concept check. */
+  /* Substitute through the arguments of the concept check.  */
   if (args)
     targs = tsubst_template_args (targs, args, info.complain, info.in_decl);
   if (targs == error_mark_node)
@@ -790,10 +789,10 @@ normalize_concept_check (tree check, tre
 
 static GTY((deletable)) hash_table<atom_hasher> *atom_cache;
 
-/* The normal form of an atom depends on the expression. The normal
+/* The normal form of an atom depends on the expression.  The normal
    form of a function call to a function concept is a check constraint
-   for that concept. The normal form of a reference to a variable
-   concept is a check constraint for that concept. Otherwise, the
+   for that concept.  The normal form of a reference to a variable
+   concept is a check constraint for that concept.  Otherwise, the
    constraint is a predicate constraint.  */
 
 static tree
@@ -853,7 +852,7 @@ normalize_atom (tree t, tree args, norm_
   return atom;
 }
 
-/* Returns the normal form of an expression. */
+/* Returns the normal form of an expression.  */
 
 static tree
 normalize_expression (tree t, tree args, norm_info info)
@@ -887,7 +886,7 @@ get_normalized_constraints (tree t, norm
 }
 
 /* Returns the normalized constraints from a constraint-info object
-   or NULL_TREE if the constraints are null. IN_DECL provides the
+   or NULL_TREE if the constraints are null.  IN_DECL provides the
    declaration to which the constraints belong.  */
 
 static tree
@@ -914,7 +913,7 @@ get_normalized_constraints_from_decl (tr
   tree decl;
 
   /* For inherited constructors, consider the original declaration;
-     it has the correct template information attached. */
+     it has the correct template information attached.  */
   d = strip_inheriting_ctors (d);
 
   if (regenerated_lambda_fn_p (d))
@@ -942,7 +941,7 @@ get_normalized_constraints_from_decl (tr
     }
 
   /* Get the most general template for the declaration, and compute
-     arguments from that. This ensures that the arguments used for
+     arguments from that.  This ensures that the arguments used for
      normalization are always template parameters and not arguments
      used for outer specializations.  For example:
 
@@ -954,13 +953,13 @@ get_normalized_constraints_from_decl (tr
         S<int>::f(0);
 
      When we normalize the requirements for S<int>::f, we want the
-     arguments to be {T, U}, not {int, U}. One reason for this is that
+     arguments to be {T, U}, not {int, U}.  One reason for this is that
      accepting the latter causes the template parameter level of U
      to be reduced in a way that makes it overly difficult substitute
      concrete arguments (i.e., eventually {int, int} during satisfaction.  */
   if (tmpl)
   {
-    if (DECL_LANG_SPECIFIC(tmpl) && !DECL_TEMPLATE_SPECIALIZATION (tmpl))
+    if (DECL_LANG_SPECIFIC (tmpl) && !DECL_TEMPLATE_SPECIALIZATION (tmpl))
       tmpl = most_general_template (tmpl);
   }
 
@@ -1037,7 +1036,7 @@ normalize_constraint_expression (tree ex
   return norm;
 }
 
-/* 17.4.1.2p2. Two constraints are identical if they are formed
+/* 17.4.1.2p2.  Two constraints are identical if they are formed
    from the same expression and the targets of the parameter mapping
    are equivalent.  */
 
@@ -1069,21 +1068,23 @@ constraints_equivalent_p (tree t1, tree
     return false;
 
   switch (TREE_CODE (t1))
-  {
-  case CONJ_CONSTR:
-  case DISJ_CONSTR:
-    if (!constraints_equivalent_p (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
-      return false;
-    if (!constraints_equivalent_p (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)))
-      return false;
-    break;
-  case ATOMIC_CONSTR:
-    if (!atomic_constraints_identical_p(t1, t2))
-      return false;
-    break;
-  default:
-    gcc_unreachable ();
-  }
+    {
+    case CONJ_CONSTR:
+    case DISJ_CONSTR:
+      if (!constraints_equivalent_p (TREE_OPERAND (t1, 0),
+				     TREE_OPERAND (t2, 0)))
+	return false;
+      if (!constraints_equivalent_p (TREE_OPERAND (t1, 1),
+				     TREE_OPERAND (t2, 1)))
+	return false;
+      break;
+    case ATOMIC_CONSTR:
+      if (!atomic_constraints_identical_p (t1, t2))
+	return false;
+      break;
+    default:
+      gcc_unreachable ();
+    }
   return true;
 }
 
@@ -1114,20 +1115,20 @@ namespace inchash
 static void
 add_constraint (tree t, hash& h)
 {
-  h.add_int(TREE_CODE (t));
+  h.add_int (TREE_CODE (t));
   switch (TREE_CODE (t))
-  {
-  case CONJ_CONSTR:
-  case DISJ_CONSTR:
-    add_constraint (TREE_OPERAND (t, 0), h);
-    add_constraint (TREE_OPERAND (t, 1), h);
-    break;
-  case ATOMIC_CONSTR:
-    h.merge_hash (hash_atomic_constraint (t));
-    break;
-  default:
-    gcc_unreachable ();
-  }
+    {
+    case CONJ_CONSTR:
+    case DISJ_CONSTR:
+      add_constraint (TREE_OPERAND (t, 0), h);
+      add_constraint (TREE_OPERAND (t, 1), h);
+      break;
+    case ATOMIC_CONSTR:
+      h.merge_hash (hash_atomic_constraint (t));
+      break;
+    default:
+      gcc_unreachable ();
+    }
 }
 
 }
@@ -1179,7 +1180,7 @@ associate_classtype_constraints (tree ty
       tree ci = current_template_constraints ();
 
       /* An implicitly instantiated member template declaration already
-	 has associated constraints. If it is defined outside of its
+	 has associated constraints.  If it is defined outside of its
 	 class, then we need match these constraints against those of
 	 original declaration.  */
       if (tree orig_ci = get_constraints (decl))
@@ -1265,8 +1266,8 @@ append_constraint (tree ci, tree rhs)
 
 static GTY ((cache)) decl_tree_cache_map *decl_constraints;
 
-/* Returns the template constraints of declaration T. If T is not
-   constrained, return NULL_TREE. Note that T must be non-null. */
+/* Returns the template constraints of declaration T.  If T is not
+   constrained, return NULL_TREE.  Note that T must be non-null.  */
 
 tree
 get_constraints (const_tree t)
@@ -1287,8 +1288,8 @@ get_constraints (const_tree t)
 }
 
 /* Associate the given constraint information CI with the declaration
-   T. If T is a template, then the constraints are associated with
-   its underlying declaration. Don't build associations if CI is
+   T.  If T is a template, then the constraints are associated with
+   its underlying declaration.  Don't build associations if CI is
    NULL_TREE.  */
 
 void
@@ -1353,7 +1354,7 @@ get_trailing_function_requirements (tree
 }
 
 /* Construct a sequence of template arguments by prepending
-   ARG to REST. Either ARG or REST may be null. */
+   ARG to REST.  Either ARG or REST may be null.  */
 static tree
 build_concept_check_arguments (tree arg, tree rest)
 {
@@ -1386,14 +1387,14 @@ build_function_check (tree tmpl, tree ar
   if (TREE_CODE (tmpl) == TEMPLATE_DECL)
     {
       /* If we just got a template, wrap it in an overload so it looks like any
-	 other template-id. */
+	 other template-id.  */
       tmpl = ovl_make (tmpl);
       TREE_TYPE (tmpl) = boolean_type_node;
     }
 
   /* Perform function concept resolution now so we always have a single
      function of the overload set (even if we started with only one; the
-     resolution function converts template arguments). Note that we still
+     resolution function converts template arguments).  Note that we still
      wrap this in an overload set so we don't upset other parts of the
      compiler that expect template-ids referring to function concepts
      to have an overload set.  */
@@ -1466,7 +1467,7 @@ build_concept_check (tree target, tree a
   return build_concept_check (target, NULL_TREE, args, complain);
 }
 
-/* Construct an expression that checks the concept given by DECL. If
+/* Construct an expression that checks the concept given by DECL.  If
    concept_definition_p (DECL) is false, this returns null.  */
 
 tree
@@ -1549,7 +1550,7 @@ build_constrained_parameter (tree cnc, t
    information necessary to build the requirements (see finish_concept_name
    for the layout of that TYPE_DECL).
 
-   Note that the constraints are neither reduced nor decomposed. That is
+   Note that the constraints are neither reduced nor decomposed.  That is
    done only after the requires clause has been parsed (or not).  */
 
 tree
@@ -1594,8 +1595,8 @@ finish_shorthand_constraint (tree decl,
 }
 
 /* Returns a conjunction of shorthand requirements for the template
-   parameter list PARMS. Note that the requirements are stored in
-   the TYPE of each tree node. */
+   parameter list PARMS.  Note that the requirements are stored in
+   the TYPE of each tree node.  */
 
 tree
 get_shorthand_constraints (tree parms)
@@ -1992,7 +1993,7 @@ declare_constraint_vars (tree parms, tre
   return vars;
 }
 
-/* Substitute through as if checking function parameter types. This
+/* Substitute through as if checking function parameter types.  This
    will diagnose common parameter type errors.  Returns error_mark_node
    if an error occurred.  */
 
@@ -2010,13 +2011,13 @@ check_constraint_variables (tree t, tree
   return tsubst_function_parms (types, args, info.complain, info.in_decl);
 }
 
-/* A subroutine of tsubst_parameterized_constraint. Substitute ARGS
+/* A subroutine of tsubst_parameterized_constraint.  Substitute ARGS
    into the parameter list T, producing a sequence of constraint
    variables, declared in the current scope.
 
    Note that the caller must establish a local specialization stack
    prior to calling this function since this substitution will
-   declare the substituted parameters. */
+   declare the substituted parameters.  */
 
 static tree
 tsubst_constraint_variables (tree t, tree args, subst_info info)
@@ -2037,10 +2038,10 @@ tsubst_constraint_variables (tree t, tre
   return declare_constraint_vars (t, vars);
 }
 
-/* Substitute ARGS into the requires-expression T. [8.4.7]p6. The
+/* Substitute ARGS into the requires-expression T. [8.4.7]p6.  The
    substitution of template arguments into a requires-expression
    may result in the formation of invalid types or expressions
-   in its requirements ... In such cases, the expression evaluates
+   in its requirements ...  In such cases, the expression evaluates
    to false; it does not cause the program to be ill-formed.
 
    When substituting through a REQUIRES_EXPR as part of template
@@ -2680,9 +2681,9 @@ get_mapped_args (tree t, tree args)
   /* Determine the depth of the resulting argument vector.  */
   int depth;
   if (ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P (t))
-    /* The expression of this atomic constraint comes from a concept definition,
-       whose template depth is always one, so the resulting argument vector
-       will also have depth one.  */
+    /* The expression of this atomic constraint comes from a concept
+       definition, whose template depth is always one, so the resulting
+       argument vector will also have depth one.  */
     depth = 1;
   else
     /* Otherwise, the expression of this atomic constraint comes from
@@ -2691,7 +2692,7 @@ get_mapped_args (tree t, tree args)
     depth = TMPL_ARGS_DEPTH (args);
 
   /* Place each argument at its corresponding position in the argument
-     list. Note that the list will be sparse (not all arguments supplied),
+     list.  Note that the list will be sparse (not all arguments supplied),
      but instantiation is guaranteed to only use the parameters in the
      mapping, so null arguments would never be used.  */
   auto_vec< vec<tree> > lists (depth);
@@ -2715,7 +2716,7 @@ get_mapped_args (tree t, tree args)
     {
       vec<tree> &list = lists[i];
       tree level = make_tree_vec (list.length ());
-      for (unsigned j = 0; j < list.length(); ++j)
+      for (unsigned j = 0; j < list.length (); ++j)
 	TREE_VEC_ELT (level, j) = list[j];
       SET_TMPL_ARGS_LEVEL (args, i + 1, level);
       list.release ();
@@ -2792,8 +2793,8 @@ satisfy_atom (tree t, tree args, sat_inf
   tree result = tsubst_expr (expr, args, quiet.complain, quiet.in_decl);
   if (result == error_mark_node)
     {
-      /* If substitution results in an invalid type or expression, the constraint
-	 is not satisfied. Replay the substitution.  */
+      /* If substitution results in an invalid type or expression, the
+	 constraint is not satisfied.  Replay the substitution.  */
       if (info.diagnose_unsatisfaction_p ())
 	tsubst_expr (expr, args, info.complain, info.in_decl);
       return cache.save (inst_cache.save (boolean_false_node));
@@ -2833,12 +2834,12 @@ satisfy_atom (tree t, tree args, sat_inf
 /* Determine if the normalized constraint T is satisfied.
    Returns boolean_true_node if the expression/constraint is
    satisfied, boolean_false_node if not, and error_mark_node
-   if the there was an error evaluating the constraint.
+   if there was an error evaluating the constraint.
 
    The parameter mapping of atomic constraints is simply the
    set of template arguments that will be substituted into
    the expression, regardless of template parameters appearing
-   withing. Whether a template argument is used in the atomic
+   within.  Whether a template argument is used in the atomic
    constraint only matters for subsumption.  */
 
 static tree
@@ -2869,7 +2870,7 @@ satisfy_normalized_constraints (tree t,
 
   auto ovr = make_temp_override (satisfying_constraint, true);
 
-  /* Turn off template processing. Constraint satisfaction only applies
+  /* Turn off template processing.  Constraint satisfaction only applies
      to non-dependent terms, so we want to ensure full checking here.  */
   processing_template_decl_sentinel proc (true);
 
@@ -2974,7 +2975,7 @@ satisfy_declaration_constraints (tree t,
   const tree saved_t = t;
 
   /* For inherited constructors, consider the original declaration;
-     it has the correct template information attached. */
+     it has the correct template information attached.  */
   t = strip_inheriting_ctors (t);
   tree inh_ctor_targs = NULL_TREE;
   if (t != saved_t)
@@ -3161,7 +3162,7 @@ constraints_satisfied_p (tree t, tree ar
   return constraint_satisfaction_value (t, args, quiet) == boolean_true_node;
 }
 
-/* Evaluate a concept check of the form C<ARGS>. This is only used for the
+/* Evaluate a concept check of the form C<ARGS>.  This is only used for the
    evaluation of template-ids as id-expressions.  */
 
 tree
@@ -3199,7 +3200,7 @@ evaluate_requires_expr (tree t)
 tree
 finish_requires_expr (location_t loc, tree parms, tree reqs)
 {
-  /* Build the node. */
+  /* Build the node.  */
   tree r = build_min (REQUIRES_EXPR, boolean_type_node, parms, reqs, NULL_TREE);
   TREE_SIDE_EFFECTS (r) = false;
   TREE_CONSTANT (r) = true;
@@ -3228,7 +3229,7 @@ finish_type_requirement (location_t loc,
 }
 
 /* Construct a requirement for the validity of EXPR, along with
-   its properties. if TYPE is non-null, then it specifies either
+   its properties.  If TYPE is non-null, then it specifies either
    an implicit conversion or argument deduction constraint,
    depending on whether any placeholders occur in the type name.
    NOEXCEPT_P is true iff the noexcept keyword was specified.  */
@@ -3265,7 +3266,7 @@ check_function_concept (tree fn)
     body = BIND_EXPR_BODY (body);
 
   /* Sometimes a function call results in the creation of clean up
-     points. Allow these to be preserved in the body of the
+     points.  Allow these to be preserved in the body of the
      constraint, as we might actually need them for some constexpr
      evaluations.  */
   if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
@@ -3303,7 +3304,7 @@ equivalent_constraints (tree a, tree b)
 }
 
 /* Returns true if the template declarations A and B have equivalent
-   constraints. This is the case when A's constraints subsume B's and
+   constraints.  This is the case when A's constraints subsume B's and
    when B's also constrain A's.  */
 bool
 equivalently_constrained (tree d1, tree d2)
@@ -3346,7 +3347,7 @@ ttp_subsumes (tree ci, tree tmpl)
    by the other's?
 
    Returns 1 if D1 is more constrained than D2, -1 if D2 is more constrained
-   than D1, and 0 otherwise. */
+   than D1, and 0 otherwise.  */
 
 int
 more_constrained (tree d1, tree d2)
@@ -3633,7 +3634,7 @@ static void
 diagnose_atomic_constraint (tree t, tree args, tree result, sat_info info)
 {
   /* If the constraint is already ill-formed, we've previously diagnosed
-     the reason. We should still say why the constraints aren't satisfied.  */
+     the reason.  We should still say why the constraints aren't satisfied.  */
   if (t == error_mark_node)
     {
       location_t loc;
--- gcc/cp/cp-tree.h.jj	2024-07-24 17:55:57.418097544 +0200
+++ gcc/cp/cp-tree.h	2024-07-24 18:59:54.772278455 +0200
@@ -440,7 +440,7 @@ extern GTY(()) tree cp_global_trees[CPTI
       COMPOUND_REQ_NOEXCEPT_P (in COMPOUND_REQ)
       WILDCARD_PACK_P (in WILDCARD_DECL)
       BLOCK_OUTER_CURLY_BRACE_P (in BLOCK)
-      FOLD_EXPR_MODOP_P (*_FOLD_EXPR)
+      FOLD_EXPR_MODIFY_P (*_FOLD_EXPR)
       IF_STMT_CONSTEXPR_P (IF_STMT)
       DECL_NAMESPACE_INLINE_P (in NAMESPACE_DECL)
       SWITCH_STMT_ALL_CASES_P (in SWITCH_STMT)
@@ -778,14 +778,14 @@ typedef struct ptrmem_cst * ptrmem_cst_t
     && DECL_NAME (NODE) != NULL_TREE			\
     && MAIN_NAME_P (DECL_NAME (NODE)))
 
-/* Nonzero iff NODE is a declaration for `int main', or we are hosted. */
+/* Nonzero iff NODE is a declaration for `int main', or we are hosted.  */
 #define DECL_MAIN_FREESTANDING_P(NODE)				\
   (DECL_MAIN_ANY_P(NODE)					\
    && (flag_hosted						\
        || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (NODE)))	\
 	  == integer_type_node))
 
-/* Nonzero iff NODE is a declaration for `main', and we are hosted. */
+/* Nonzero iff NODE is a declaration for `main', and we are hosted.  */
 #define DECL_MAIN_P(NODE) (DECL_MAIN_ANY_P(NODE) && flag_hosted)
 
 /* Lookup walker marking.  */
@@ -1121,7 +1121,7 @@ enum cp_id_kind
 };
 
 
-/* The various kinds of C++0x warnings we encounter. */
+/* The various kinds of C++0x warnings we encounter.  */
 
 enum cpp0x_warn_str
 {
@@ -1157,7 +1157,7 @@ enum cpp0x_warn_str
   CPP0X_REF_QUALIFIER
 };
 
-/* The various kinds of operation used by composite_pointer_type. */
+/* The various kinds of operation used by composite_pointer_type.  */
 
 enum composite_pointer_operation
 {
@@ -1169,14 +1169,15 @@ enum composite_pointer_operation
   CPO_CONDITIONAL_EXPR
 };
 
-/* Possible cases of expression list used by build_x_compound_expr_from_list. */
+/* Possible cases of expression list used by
+   build_x_compound_expr_from_list.  */
 enum expr_list_kind {
   ELK_INIT,		/* initializer */
   ELK_MEM_INIT,		/* member initializer */
   ELK_FUNC_CAST		/* functional cast */
 };
 
-/* Possible cases of implicit bad rhs conversions. */
+/* Possible cases of implicit bad rhs conversions.  */
 enum impl_conv_rhs {
   ICR_DEFAULT_ARGUMENT, /* default argument */
   ICR_CONVERTING,       /* converting */
@@ -1186,7 +1187,7 @@ enum impl_conv_rhs {
   ICR_ASSIGN            /* assignment */
 };
 
-/* Possible cases of implicit or explicit bad conversions to void. */
+/* Possible cases of implicit or explicit bad conversions to void.  */
 enum impl_conv_void {
   ICV_CAST,            /* (explicit) conversion to void */
   ICV_SECOND_OF_COND,  /* second operand of conditional expression */
@@ -1576,7 +1577,7 @@ struct GTY (()) tree_lambda_expr
 /* The representation of a deferred access check.  */
 
 struct GTY(()) deferred_access_check {
-  /* The base class in which the declaration is referenced. */
+  /* The base class in which the declaration is referenced.  */
   tree binfo;
   /* The declaration whose access must be checked.  */
   tree decl;
@@ -1704,7 +1705,7 @@ check_constraint_info (tree t)
 #define CONSTR_CONTEXT(NODE) \
   TREE_VALUE (CONSTR_INFO (NODE))
 
-/* The parameter mapping for an atomic constraint. */
+/* The parameter mapping for an atomic constraint.  */
 #define ATOMIC_CONSTR_MAP(NODE) \
   TREE_OPERAND (TREE_CHECK (NODE, ATOMIC_CONSTR), 0)
 
@@ -1719,7 +1720,7 @@ check_constraint_info (tree t)
 #define ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P(NODE) \
   TREE_LANG_FLAG_1 (ATOMIC_CONSTR_CHECK (NODE))
 
-/* The expression of an atomic constraint. */
+/* The expression of an atomic constraint.  */
 #define ATOMIC_CONSTR_EXPR(NODE) \
   CONSTR_EXPR (ATOMIC_CONSTR_CHECK (NODE))
 
@@ -3624,7 +3625,7 @@ struct GTY(()) lang_decl {
 #define DECL_IMPLICIT_TEMPLATE_PARM_P(NODE) \
   DECL_VIRTUAL_P (DECL_TEMPLATE_PARM_CHECK (NODE))
 
-/* 1 iff FUNCTION_TYPE or METHOD_TYPE has a ref-qualifier (either & or &&). */
+/* 1 iff FUNCTION_TYPE or METHOD_TYPE has a ref-qualifier (either & or &&).  */
 #define FUNCTION_REF_QUALIFIED(NODE) \
   TREE_LANG_FLAG_4 (FUNC_OR_METHOD_CHECK (NODE))
 
@@ -3676,7 +3677,7 @@ struct GTY(()) lang_decl {
    parameters in the list have declarators enclosed in ().  */
 #define PARENTHESIZED_LIST_P(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE))
 
-/* Non zero if this is a using decl for a dependent scope. */
+/* Non zero if this is a using decl for a dependent scope.  */
 #define DECL_DEPENDENT_P(NODE) DECL_LANG_FLAG_0 (USING_DECL_CHECK (NODE))
 
 /* The scope named in a using decl.  */
@@ -4100,11 +4101,11 @@ struct GTY(()) lang_decl {
    || TREE_CODE (NODE) == BINARY_LEFT_FOLD_EXPR		\
    || TREE_CODE (NODE) == BINARY_RIGHT_FOLD_EXPR)
 
-/* True when NODE is a fold over a compound assignment operator. */
+/* True when NODE is a fold over a compound assignment operator.  */
 #define FOLD_EXPR_MODIFY_P(NODE) \
   TREE_LANG_FLAG_0 (FOLD_EXPR_CHECK (NODE))
 
-/* An INTEGER_CST containing the tree code of the folded operator. */
+/* An INTEGER_CST containing the tree code of the folded operator.  */
 #define FOLD_EXPR_OP_RAW(NODE) \
   TREE_OPERAND (FOLD_EXPR_CHECK (NODE), 0)
 
@@ -4112,12 +4113,12 @@ struct GTY(()) lang_decl {
 #define FOLD_EXPR_OP(NODE) \
   ((enum tree_code) TREE_INT_CST_LOW (FOLD_EXPR_OP_RAW (NODE)))
 
-/* The expression containing an unexpanded parameter pack. */
+/* The expression containing an unexpanded parameter pack.  */
 #define FOLD_EXPR_PACK(NODE) \
   TREE_OPERAND (FOLD_EXPR_CHECK (NODE), 1)
 
 /* In a binary fold expression, the argument with no unexpanded
-   parameter packs. */
+   parameter packs.  */
 #define FOLD_EXPR_INIT(NODE) \
   TREE_OPERAND (BINARY_FOLD_EXPR_CHECK (NODE), 2)
 
@@ -5010,7 +5011,7 @@ get_vec_init_expr (tree t)
 
 /* True if TYPE is an unnamed structured type with a typedef for
    linkage purposes.  In that case TYPE_NAME and TYPE_STUB_DECL of the
-   MAIN-VARIANT are different. */
+   MAIN-VARIANT are different.  */
 #define TYPE_WAS_UNNAMED(NODE)				\
   (TYPE_NAME (TYPE_MAIN_VARIANT (NODE))			\
    != TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE)))
@@ -5788,7 +5789,7 @@ extern bool comparing_override_contracts
 extern int cp_unevaluated_operand;
 
 /* RAII class used to inhibit the evaluation of operands during parsing
-   and template instantiation. Evaluation warnings are also inhibited. */
+   and template instantiation.  Evaluation warnings are also inhibited.  */
 
 class cp_unevaluated
 {
@@ -6259,7 +6260,7 @@ enum ovl_op_code {
   OVL_OP_MAX
 };
 
-/* Make sure it fits in lang_decl_fn::ovl_op_code. */
+/* Make sure it fits in lang_decl_fn::ovl_op_code.  */
 STATIC_ASSERT (OVL_OP_MAX < (1 << 6));
 
 struct GTY(()) ovl_op_info_t {
@@ -6533,7 +6534,7 @@ struct cp_declarator {
       tree exception_specification;
       /* The late-specified return type, if any.  */
       tree late_return_type;
-      /* The trailing requires-clause, if any. */
+      /* The trailing requires-clause, if any.  */
       tree requires_clause;
       location_t parens_loc;
     } function;
@@ -8849,7 +8850,7 @@ null_node_p (const_tree expr)
   return expr == null_node;
 }
 
-/* True iff T is a variable template declaration. */
+/* True iff T is a variable template declaration.  */
 inline bool
 variable_template_p (tree t)
 {
@@ -8910,7 +8911,7 @@ concept_definition_p (tree t)
   if (TREE_CODE (t) == OVERLOAD)
     t = OVL_FIRST (t);
 
-  /* See through templates. */
+  /* See through templates.  */
   if (TREE_CODE (t) == TEMPLATE_DECL)
     t = DECL_TEMPLATE_RESULT (t);
 
--- gcc/cp/logic.cc.jj	2024-07-24 15:46:56.020723420 +0200
+++ gcc/cp/logic.cc	2024-07-24 18:57:27.770161657 +0200
@@ -69,7 +69,7 @@ struct clause
     m_current = m_terms.begin ();
   }
 
-  /* Create a copy of the current term. The current
+  /* Create a copy of the current term.  The current
      iterator is set to point to the same position in the
      copied list of terms.  */
 
@@ -96,7 +96,7 @@ struct clause
 
   /* Replaces the current term at position ITER with T.  If
      T is an atomic constraint that already appears in the
-     clause, remove but do not replace ITER. Returns a pair
+     clause, remove but do not replace ITER.  Returns a pair
      containing an iterator to the replace object or past
      the erased object and a boolean value which is true if
      an object was erased.  */
@@ -113,24 +113,23 @@ struct clause
     return std::make_pair (iter, false);
   }
 
-  /* Inserts T before ITER in the list of terms.  If T has 
-     already is an atomic constraint that already appears in
-     the clause, no action is taken, and the current iterator
-     is returned. Returns a pair of an iterator to the inserted
-     object or ITER if no insertion occurred and a boolean
+  /* Inserts T before ITER in the list of terms.  If T is an atomic
+     constraint that already appears in the clause, no action is taken,
+     and the current iterator is returned.  Returns a pair of an iterator
+     to the inserted object or ITER if no insertion occurred and a boolean
      value which is true if an object was inserted.  */
 
   std::pair<iterator, bool> insert (iterator iter, tree t)
   {
     if (TREE_CODE (t) == ATOMIC_CONSTR)
-    {
-      if (m_set.add (t))
-	return std::make_pair (iter, false);
-    }
+      {
+	if (m_set.add (t))
+	  return std::make_pair (iter, false);
+      }
     return std::make_pair (m_terms.insert (iter, t), true);
   }
 
-  /* Replaces the current term with T. In the case where the
+  /* Replaces the current term with T.  In the case where the
      current term is erased (because T is redundant), update
      the position of the current term to the next term.  */
 
@@ -143,7 +142,7 @@ struct clause
 
   void replace (tree t1, tree t2)
   {
-    /* Replace the current term with t1. Ensure that iter points
+    /* Replace the current term with t1.  Ensure that iter points
        to the term before which t2 will be inserted.  Update the
        current term as needed.  */
     std::pair<iterator, bool> rep = replace (m_current, t1);
@@ -152,7 +151,7 @@ struct clause
     else
       ++rep.first;
 
-    /* Insert the t2. Make this the current term if we erased
+    /* Insert the t2.  Make this the current term if we erased
        the prior term.  */
     std::pair<iterator, bool> ins = insert (rep.first, t2);
     if (rep.second && ins.second)
@@ -210,8 +209,8 @@ struct clause
 
 
 /* A proof state owns a list of goals and tracks the
-   current sub-goal. The class also provides facilities
-   for managing subgoals and constructing term lists. */
+   current sub-goal.  The class also provides facilities
+   for managing subgoals and constructing term lists.  */
 
 struct formula
 {
@@ -240,7 +239,7 @@ struct formula
     ++m_current;
   }
 
-  /* Insert a copy of clause into the formula. This corresponds
+  /* Insert a copy of clause into the formula.  This corresponds
      to a distribution of one logical operation over the other.  */
 
   clause& branch ()
@@ -299,14 +298,14 @@ struct formula
 void
 debug (clause& c)
 {
-  for (clause::iterator i = c.begin(); i != c.end(); ++i)
+  for (clause::iterator i = c.begin (); i != c.end (); ++i)
     verbatim ("  # %E", *i);
 }
 
 void
 debug (formula& f)
 {
-  for (formula::iterator i = f.begin(); i != f.end(); ++i)
+  for (formula::iterator i = f.begin (); i != f.end (); ++i)
     {
       /* Format punctuators via %s to avoid -Wformat-diag.  */
       verbatim ("%s", "(((");
@@ -315,7 +314,7 @@ debug (formula& f)
     }
 }
 
-/* The logical rules used to analyze a logical formula. The
+/* The logical rules used to analyze a logical formula.  The
    "left" and "right" refer to the position of formula in a
    sequent (as in sequent calculus).  */
 
@@ -345,9 +344,9 @@ atomic_p (tree t)
 }
 
 /* Recursively count the number of clauses produced when converting T
-   to DNF. Returns a pair containing the number of clauses and a bool
+   to DNF.  Returns a pair containing the number of clauses and a bool
    value signifying that the tree would be rewritten as a result of
-   distributing. In general, a conjunction for which this flag is set
+   distributing.  In general, a conjunction for which this flag is set
    is considered a disjunction for the purpose of counting.  */
 
 static std::pair<int, bool>
@@ -368,10 +367,10 @@ dnf_size_r (tree t)
 
   if (disjunction_p (t))
     {
-      /* Matches constraints of the form P \/ Q. Disjunctions contribute
+      /* Matches constraints of the form P \/ Q.  Disjunctions contribute
 	 linearly to the number of constraints.  When both P and Q are
-	 disjunctions, clauses are added. When only one of P and Q
-	 is a disjunction, an additional clause is produced. When neither
+	 disjunctions, clauses are added.  When only one of P and Q
+	 is a disjunction, an additional clause is produced.  When neither
 	 P nor Q are disjunctions, two clauses are produced.  */
       if (disjunction_p (lhs))
 	{
@@ -410,10 +409,10 @@ dnf_size_r (tree t)
   else /* conjunction_p (t)  */
     {
       /* Matches constraints of the form P /\ Q, possibly resulting
-         in the distribution of one side over the other. When both
+	 in the distribution of one side over the other.  When both
          P and Q are disjunctions, the number of clauses are multiplied.
 	 When only one of P and Q is a disjunction, the number of
-         clauses are added. Otherwise, neither side is a disjunction and
+	 clauses are added.  Otherwise, neither side is a disjunction and
          no clauses are created.  */
       if (disjunction_p (lhs))
 	{
@@ -453,9 +452,9 @@ dnf_size_r (tree t)
 }
 
 /* Recursively count the number of clauses produced when converting T
-   to CNF. Returns a pair containing the number of clauses and a bool
+   to CNF.  Returns a pair containing the number of clauses and a bool
    value signifying that the tree would be rewritten as a result of
-   distributing. In general, a disjunction for which this flag is set
+   distributing.  In general, a disjunction for which this flag is set
    is considered a conjunction for the purpose of counting.  */
 
 static std::pair<int, bool>
@@ -477,10 +476,10 @@ cnf_size_r (tree t)
   if (disjunction_p (t))
     {
       /* Matches constraints of the form P \/ Q, possibly resulting
-         in the distribution of one side over the other. When both
+	 in the distribution of one side over the other.  When both
          P and Q are conjunctions, the number of clauses are multiplied.
 	 When only one of P and Q is a conjunction, the number of
-         clauses are added. Otherwise, neither side is a conjunction and
+	 clauses are added.  Otherwise, neither side is a conjunction and
          no clauses are created.  */
       if (disjunction_p (lhs))
 	{
@@ -517,10 +516,10 @@ cnf_size_r (tree t)
     }
   else /* conjunction_p (t)  */
     {
-      /* Matches constraints of the form P /\ Q. Conjunctions contribute
+      /* Matches constraints of the form P /\ Q.  Conjunctions contribute
 	 linearly to the number of constraints.  When both P and Q are
-	 conjunctions, clauses are added. When only one of P and Q
-	 is a conjunction, an additional clause is produced. When neither
+	 conjunctions, clauses are added.  When only one of P and Q
+	 is a conjunction, an additional clause is produced.  When neither
 	 P nor Q are conjunctions, two clauses are produced.  */
       if (disjunction_p (lhs))
 	{
@@ -559,7 +558,7 @@ cnf_size_r (tree t)
 }
 
 /* Count the number conjunctive clauses that would be created
-   when rewriting T to DNF. */
+   when rewriting T to DNF.  */
 
 static int
 dnf_size (tree t)
@@ -570,7 +569,7 @@ dnf_size (tree t)
 
 
 /* Count the number disjunctive clauses that would be created
-   when rewriting T to CNF. */
+   when rewriting T to CNF.  */
 
 static int
 cnf_size (tree t)
@@ -591,7 +590,7 @@ replace_term (clause& c, tree t)
 }
 
 /* Create a new clause in the formula by copying the current
-   clause. In the current clause, the term at CI is replaced
+   clause.  In the current clause, the term at CI is replaced
    by the first operand, and in the new clause, it is replaced
    by the second.  */
 
@@ -627,7 +626,7 @@ decompose_disjunction (formula& f, claus
     branch_clause (f, c, t);
 }
 
-/* An atomic constraint is already decomposed.  */
+/* An atomic or fold expanded constraint is already decomposed.  */
 inline void
 decompose_atom (clause& c)
 {
@@ -635,19 +634,19 @@ decompose_atom (clause& c)
 }
 
 /* Decompose a term of clause C (in formula F) according to the
-   logical rules R. */
+   logical rules R.  */
 
 void
 decompose_term (formula& f, clause& c, tree t, rules r)
 {
   switch (TREE_CODE (t))
     {
-      case CONJ_CONSTR:
-        return decompose_conjuntion (f, c, t, r);
-      case DISJ_CONSTR:
-	return decompose_disjunction (f, c, t, r);
-      default:
-	return decompose_atom (c);
+    case CONJ_CONSTR:
+      return decompose_conjuntion (f, c, t, r);
+    case DISJ_CONSTR:
+      return decompose_disjunction (f, c, t, r);
+    default:
+      return decompose_atom (c);
     }
 }
 
@@ -714,7 +713,7 @@ derive_proof (clause& c, tree t, rules r
   }
 }
 
-/* Key/value pair for caching subsumption results. This associates a pair of
+/* Key/value pair for caching subsumption results.  This associates a pair of
    constraints with a boolean value indicating the result.  */
 
 struct GTY((for_user)) subsumption_entry
@@ -746,11 +745,11 @@ struct subsumption_hasher : ggc_ptr_hash
   }
 };
 
-/* Caches the results of subsumes_non_null(t1, t1).  */
+/* Caches the results of subsumes_constraints_nonnull (t1, t1).  */
 
 static GTY ((deletable)) hash_table<subsumption_hasher> *subsumption_cache;
 
-/* Search for a previously cached subsumption result. */
+/* Search for a previously cached subsumption result.  */
 
 static bool*
 lookup_subsumption (tree t1, tree t2)
@@ -765,13 +764,13 @@ lookup_subsumption (tree t1, tree t2)
     return 0;
 }
 
-/* Save a subsumption result. */
+/* Save a subsumption result.  */
 
 static bool
 save_subsumption (tree t1, tree t2, bool result)
 {
   if (!subsumption_cache)
-    subsumption_cache = hash_table<subsumption_hasher>::create_ggc(31);
+    subsumption_cache = hash_table<subsumption_hasher>::create_ggc (31);
   subsumption_entry elt = {t1, t2, result};
   subsumption_entry** slot = subsumption_cache->find_slot (&elt, INSERT);
   subsumption_entry* entry = ggc_alloc<subsumption_entry> ();
@@ -790,7 +789,7 @@ subsumes_constraints_nonnull (tree lhs,
 {
   auto_timevar time (TV_CONSTRAINT_SUB);
 
-  if (bool *b = lookup_subsumption(lhs, rhs))
+  if (bool *b = lookup_subsumption (lhs, rhs))
     return *b;
 
   tree x, y;
