On 2/28/21 12:58 PM, Patrick Palka wrote:
This patch mostly performs some straightforward refactoring:

   - Renamed satisfy_constraint to satisfy_normalized_constraints
   - Renamed the three-parameter version of satisfy_constraint_expression
     to satisfy_nondeclaration_constraints
   - Removed normalize_(non)?template_requirements
   - Removed satisfy_associated_constraints (and made its callers
     check for dependent template args sooner, before normalization)
   - Removed the tsubst_flags_t parameter of evaluate_concept_check
   - Combined the two versions of constraint_satisfaction_value
   - Combined the two versions of constraint_satisfied_p

Additionally, this patch removes the handling of bare
constraint-expressions from satisfy_nondeclaration_constraints, and
hence constraints_satisfied_p and constraint_satisfaction_value now only
take things that carry their own template information needed for
normalization.  In practice, this only means it's no longer possible to
evaluate bare REQUIRES_EXPRs via the satisfaction routines, and so this
patch adjusts the affected callers to instead use tsubst_requires_expr.

It's probably better to have a different entry point than tsubst_requires_expr for callers that have nothing to do with templates. Whether that's a one-line wrapper for the call to tsubst_requires_expr ("evaluate_requires_expr"?) or calling tsubst_requires_expr from satisfy_nondeclaration_constraints, I don't have an opinion either way.

For convenience, the function diagnose_constraints continues to accept
REQUIRES_EXPRs, but it now handles them by calling diagnose_require_expr
directly.

This might argue for the latter choice above.

(That we used to evaluate REQUIRES_EXPR via satisfaction might even be a
correctness issue: since we cache satisfaction in special ways that don't
apply to regular evaluation, going through satisfaction could in theory
cause us to reuse a cached value for a REQUIRES_EXPR when we shouldn't
have.)

gcc/cp/ChangeLog:

        * constexpr.c (cxx_eval_call_expression): Adjust call to
        evaluate_concept_check.
        (cxx_eval_constant_expression) <case REQUIRES_EXPR>: Use
        tsubst_requires_expr instead of satisfy_constraint_expression.
        <case TEMPLATE_ID_EXPR>: Adjust call to evaluate_concept_check.
        * constraint.cc (struct sat_info): Adjust comment about which
        satisfaction entrypoints use noisy-unsat.
        (normalize_template_requirements): Remove (and adjust callers
        appropriately).
        (normalize_nontemplate_requirements): Likewise.
        (tsubst_nested_requirement): Use constraint_satisfaction_value
        instead of satisfy_constraint_expression, which'll do the
        noisy replaying of ill-formed quiet satisfaction for us.
        (decl_satisfied_cache): Adjust comment.
        (satisfy_constraint): Rename to ...
        (satisfy_normalized_constraints): ... this.
        (satisfy_associated_constraints): Remove (and make its
        callers check for dependent arguments).
        (satisfy_constraint_expression): Rename to ...
        (satisfy_nondeclaration_constraints): ... this.  Assert that
        'args' is empty when 't' is a concept-id.  Removing handling
        bare constraint-expressions.  Adjust comment accordingly.
        (satisfy_declaration_constraints): Assert in the two-parameter
        version that 't' is not a TEMPLATE_DECL.  Adjust following
        removal of normalize_(non)?template_requirements and
        satisfy_asociated_constraints.
        (constraint_satisfaction_value): Combine the two- and
        three-parameter versions in the natural way.
        (constraints_satisfied_p): Combine the one- and two-parameter
        versions in the natural way.  Improve documentation.
        (evaluate_concept_check): Remove 'complain' parameter.  Use
        constraint_satisfaction_value instead of
        satisfy_constraint_expression.
        (diagnose_nested_requirement): Adjust following renaming of
        satisfy_constraint_expression.
        (diagnose_constraints): Handle REQUIRES_EXPR by going through
        diagnose_requires_expr directly instead of treating it as a
        constraint-expression.  Improve documentation.
        * cp-gimplify.c (cp_genericize_r) <case CALL_EXPR>: Adjust call
        to evaluate_concept_check.
        <case REQUIRES_EXPR>: Use tsubst_requires_expr instead of
        constraints_satisfied_p.
        <case TEMPLATE_ID_EXPR>: Adjust call to evaluate_concept_check.
        * cp-tree.h (evaluate_concept_check): Remove tsubst_flag_t
        parameter.
        (satisfy_constraint_expression): Remove declaration.
        (constraints_satisfied_p): Remove one-parameter declaration.
        Add a default argument to the two-parameter declaration.
        * cvt.c (convert_to_void): Adjust call to
        evaluate_concept_check.
---
  gcc/cp/constexpr.c   |   6 +-
  gcc/cp/constraint.cc | 210 ++++++++++++++++---------------------------
  gcc/cp/cp-gimplify.c |   7 +-
  gcc/cp/cp-tree.h     |   6 +-
  gcc/cp/cvt.c         |   2 +-
  5 files changed, 85 insertions(+), 146 deletions(-)

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index cd0a68e9fd6..f940e3e5985 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -2257,7 +2257,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree 
t,
  {
    /* Handle concept checks separately.  */
    if (concept_check_p (t))
-    return evaluate_concept_check (t, tf_warning_or_error);
+    return evaluate_concept_check (t);
location_t loc = cp_expr_loc_or_input_loc (t);
    tree fun = get_function_named_in_call (t);
@@ -6905,7 +6905,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
           '!requires (T t) { ... }' which is not transformed into
           a constraint.  */
        if (!processing_template_decl)
-        return satisfy_constraint_expression (t);
+       return tsubst_requires_expr (t, NULL_TREE, tf_none, NULL_TREE);
        else
          *non_constant_p = true;
        return t;
@@ -6941,7 +6941,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
if (!processing_template_decl
            && !uid_sensitive_constexpr_evaluation_p ())
-         r = evaluate_concept_check (t, tf_warning_or_error);
+         r = evaluate_concept_check (t);
        else
          *non_constant_p = true;
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 2b61ad8d9ea..cf319b34da0 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -107,10 +107,9 @@ struct subst_info
     a constraint is not satisfied.
The entrypoints to satisfaction for which we set noisy+unsat are
-   diagnose_constraints and diagnose_nested_requirement.  The entrypoints for
-   which we set noisy-unsat are the replays inside 
constraint_satisfaction_value,
-   evaluate_concept_check and tsubst_nested_requirement.  In other entrypoints,
-   e.g. constraints_satisfied_p, we enter satisfaction quietly (both flags
+   diagnose_constraints and diagnose_nested_requirement.  The entrypoint for
+   which we set noisy-unsat is the replay inside constraint_satisfaction_value.
+   From constraints_satisfied_p, we enter satisfaction quietly (both flags
     cleared).  */
struct sat_info : subst_info
@@ -133,7 +132,7 @@ struct sat_info : subst_info
    bool diagnose_unsatisfaction;
  };
-static tree satisfy_constraint_expression (tree, tree, sat_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
     is false for dependent types and errors.  */
@@ -958,22 +957,6 @@ normalize_concept_definition (tree tmpl, bool diag = false)
    return norm;
  }
-/* Returns the normal form of TMPL's requirements. */
-
-static tree
-normalize_template_requirements (tree tmpl, bool diag = false)
-{
-  return get_normalized_constraints_from_decl (tmpl, diag);
-}
-
-/* Returns the normal form of TMPL's requirements.  */
-
-static tree
-normalize_nontemplate_requirements (tree decl, bool diag = false)
-{
-  return get_normalized_constraints_from_decl (decl, diag);
-}
-
  /* Normalize an EXPR as a constraint.  */
static tree
@@ -2068,15 +2051,8 @@ tsubst_compound_requirement (tree t, tree args, 
subst_info info)
  static tree
  tsubst_nested_requirement (tree t, tree args, subst_info info)
  {
-  /* Perform satisfaction quietly first.  */
    sat_info quiet (tf_none, info.in_decl);
-  tree result = satisfy_constraint_expression (t, args, quiet);
-  if (result == error_mark_node)
-    {
-      /* Replay the error.  */
-      sat_info noisy (tf_warning_or_error, info.in_decl);
-      satisfy_constraint_expression (t, args, noisy);
-    }
+  tree result = constraint_satisfaction_value (t, args, quiet);
    if (result != boolean_true_node)
      return error_mark_node;
    return boolean_true_node;
@@ -2459,7 +2435,7 @@ struct sat_hasher : ggc_ptr_hash<sat_entry>
  /* Cache the result of satisfy_atom.  */
  static GTY((deletable)) hash_table<sat_hasher> *sat_cache;
-/* Cache the result of constraint_satisfaction_value. */
+/* Cache the result of satisfy_declaration_constraints.  */
  static GTY((deletable)) hash_map<tree, tree> *decl_satisfied_cache;
/* A tool used by satisfy_atom to help manage satisfaction caching and to
@@ -2941,7 +2917,7 @@ satisfy_constraint_r (tree t, tree args, sat_info info)
  /* Check that the normalized constraint T is satisfied for ARGS.  */
static tree
-satisfy_constraint (tree t, tree args, sat_info info)
+satisfy_normalized_constraints (tree t, tree args, sat_info info)
  {
    auto_timevar time (TV_CONSTRAINT_SAT);
@@ -2957,24 +2933,6 @@ satisfy_constraint (tree t, tree args, sat_info info)
    return satisfy_constraint_r (t, args, info);
  }
-/* Check the normalized constraints T against ARGS, returning a satisfaction
-   value (either true, false, or error).  */
-
-static tree
-satisfy_associated_constraints (tree t, tree args, sat_info info)
-{
-  /* If there are no constraints then this is trivially satisfied.  */
-  if (!t)
-    return boolean_true_node;
-
-  /* If any arguments depend on template parameters, we can't
-     check constraints. Pretend they're satisfied for now.  */
-  if (args && uses_template_parms (args))
-    return boolean_true_node;
-
-  return satisfy_constraint (t, args, info);
-}
-
  /* Return the normal form of the constraints on the placeholder 'auto'
     type T.  */
@@ -3005,19 +2963,20 @@ normalize_placeholder_type_constraints (tree t, bool diag)
    return normalize_constraint_expression (constr, info);
  }
-/* Evaluate EXPR as a constraint expression using ARGS, returning a
-   satisfaction value. */
+/* Evaluate the constraints of T using ARGS, returning a satisfaction value.
+   Here, T can be a concept-id, nested-requirement or placeholder 'auto'.  */
static tree
-satisfy_constraint_expression (tree t, tree args, sat_info info)
+satisfy_nondeclaration_constraints (tree t, tree args, sat_info info)
  {
    if (t == error_mark_node)
      return error_mark_node;
/* Get the normalized constraints. */
    tree norm;
-  if (args == NULL_TREE && concept_check_p (t))
+  if (concept_check_p (t))
      {
+      gcc_assert (!args);
        tree id = unpack_concept_check (t);
        args = TREE_OPERAND (id, 1);
        tree tmpl = get_concept_check_template (id);
@@ -3032,11 +2991,6 @@ satisfy_constraint_expression (tree t, tree args, 
sat_info info)
        ninfo.initial_parms = TREE_TYPE (t);
        norm = normalize_constraint_expression (TREE_OPERAND (t, 0), ninfo);
      }
-  else if (EXPR_P (t))
-    {
-      norm_info ninfo (info.noisy () ? tf_norm : tf_none);
-      norm = normalize_constraint_expression (t, ninfo);
-    }
    else if (is_auto (t))
      {
        norm = normalize_placeholder_type_constraints (t, info.noisy ());
@@ -3047,23 +3001,16 @@ satisfy_constraint_expression (tree t, tree args, 
sat_info info)
      gcc_unreachable ();
/* Perform satisfaction. */
-  return satisfy_constraint (norm, args, info);
+  return satisfy_normalized_constraints (norm, args, info);
  }
-/* Used only to evaluate requires-expressions during constant expression
-   evaluation.  */
-
-tree
-satisfy_constraint_expression (tree expr)
-{
-  sat_info info (tf_none, NULL_TREE);
-  return satisfy_constraint_expression (expr, NULL_TREE, info);
-}
+/* Evaluate the associated constraints of the template specialization T
+   according to INFO, returning a satisfaction value.  */
static tree
  satisfy_declaration_constraints (tree t, sat_info info)
  {
-  gcc_assert (DECL_P (t));
+  gcc_assert (DECL_P (t) && TREE_CODE (t) != TEMPLATE_DECL);
    const tree saved_t = t;
/* For inherited constructors, consider the original declaration;
@@ -3083,26 +3030,24 @@ satisfy_declaration_constraints (tree t, sat_info info)
      if (tree *result = hash_map_safe_get (decl_satisfied_cache, saved_t))
        return *result;
- /* Get the normalized constraints. */
-  tree norm = NULL_TREE;
    tree args = NULL_TREE;
    if (tree ti = DECL_TEMPLATE_INFO (t))
      {
-      tree tmpl = TI_TEMPLATE (ti);
-      norm = normalize_template_requirements (tmpl, info.noisy ());
-
        /* The initial parameter mapping is the complete set of
         template arguments substituted into the declaration.  */
        args = TI_ARGS (ti);
        if (inh_ctor_targs)
        args = add_outermost_template_args (args, inh_ctor_targs);
-    }
-  else
-    {
-      /* These should be empty until we allow constraints on non-templates.  */
-      norm = normalize_nontemplate_requirements (t, info.noisy ());
+
+      /* If any arguments depend on template parameters, we can't
+        check constraints. Pretend they're satisfied for now.  */
+      if (uses_template_parms (args))
+       return boolean_true_node;
      }
+ /* Get the normalized constraints. */
+  tree norm = get_normalized_constraints_from_decl (t, info.noisy ());
+
    unsigned ftc_count = vec_safe_length (failed_type_completions);
tree result = boolean_true_node;
@@ -3111,7 +3056,7 @@ satisfy_declaration_constraints (tree t, sat_info info)
        if (!push_tinst_level (t))
        return result;
        push_access_scope (t);
-      result = satisfy_associated_constraints (norm, args, info);
+      result = satisfy_normalized_constraints (norm, args, info);
        pop_access_scope (t);
        pop_tinst_level ();
      }
@@ -3134,6 +3079,10 @@ satisfy_declaration_constraints (tree t, sat_info info)
    return result;
  }
+/* Evaluate the associated constraints of the template T using ARGS as the
+   innermost set of template arguments and according to INFO, returning a
+   satisfaction value.  */
+
  static tree
  satisfy_declaration_constraints (tree t, tree args, sat_info info)
  {
@@ -3144,14 +3093,19 @@ satisfy_declaration_constraints (tree t, tree args, 
sat_info info)
args = add_outermost_template_args (t, args); + /* If any arguments depend on template parameters, we can't
+     check constraints. Pretend they're satisfied for now.  */
+  if (uses_template_parms (args))
+    return boolean_true_node;
+
    tree result = boolean_true_node;
-  if (tree norm = normalize_template_requirements (t, info.noisy ()))
+  if (tree norm = get_normalized_constraints_from_decl (t, info.noisy ()))
      {
        if (!push_tinst_level (t, args))
        return result;
        tree pattern = DECL_TEMPLATE_RESULT (t);
        push_access_scope (pattern);
-      result = satisfy_associated_constraints (norm, args, info);
+      result = satisfy_normalized_constraints (norm, args, info);
        pop_access_scope (pattern);
        pop_tinst_level ();
      }
@@ -3159,62 +3113,50 @@ satisfy_declaration_constraints (tree t, tree args, 
sat_info info)
    return result;
  }
+/* A wrapper around satisfy_declaration_constraints and
+   satisfy_nondeclaration_constraints which additionally replays
+   quiet ill-formed satisfaction noisily, so that ill-formed
+   satisfaction always gets diagnosed.  */
+
  static tree
-constraint_satisfaction_value (tree t, sat_info info)
+constraint_satisfaction_value (tree t, tree args, sat_info info)
  {
    tree r;
    if (DECL_P (t))
-    r = satisfy_declaration_constraints (t, info);
+    {
+      if (args)
+       r = satisfy_declaration_constraints (t, args, info);
+      else
+       r = satisfy_declaration_constraints (t, info);
+    }
    else
-    r = satisfy_constraint_expression (t, NULL_TREE, info);
+    r = satisfy_nondeclaration_constraints (t, args, info);
    if (r == error_mark_node && info.quiet ()
        && !(DECL_P (t) && TREE_NO_WARNING (t)))
      {
-      /* Replay the error with re-normalized requirements.  */
+      /* Replay the error noisily.  */
        sat_info noisy (tf_warning_or_error, info.in_decl);
-      constraint_satisfaction_value (t, noisy);
-      if (DECL_P (t))
+      constraint_satisfaction_value (t, args, noisy);
+      if (DECL_P (t) && !args)
        /* Avoid giving these errors again.  */
        TREE_NO_WARNING (t) = true;
      }
    return r;
  }
-static tree
-constraint_satisfaction_value (tree t, tree args, sat_info info)
-{
-  tree r;
-  if (DECL_P (t))
-    r = satisfy_declaration_constraints (t, args, info);
-  else
-    r = satisfy_constraint_expression (t, args, info);
-  if (r == error_mark_node && info.quiet ())
-    {
-      /* Replay the error with re-normalized requirements.  */
-      sat_info noisy (tf_warning_or_error, info.in_decl);
-      constraint_satisfaction_value (t, args, noisy);
-    }
-  return r;
-}
-
-/* True iff the result of satisfying T is BOOLEAN_TRUE_NODE and false
-   otherwise, even in the case of errors.  */
+/* True iff the result of satisfying T using ARGS is BOOLEAN_TRUE_NODE
+   and false otherwise, even in the case of errors.
-bool
-constraints_satisfied_p (tree t)
-{
-  if (!flag_concepts)
-    return true;
-
-  sat_info quiet (tf_none, NULL_TREE);
-  return constraint_satisfaction_value (t, quiet) == boolean_true_node;
-}
-
-/* True iff the result of satisfying T with ARGS is BOOLEAN_TRUE_NODE
-    and false otherwise, even in the case of errors.  */
+   Here, T can be:
+     - a template declaration (in which case ARGS is an innermost template
+       argument set for T)
+     - a template specialization (in which case ARGS must be empty)
+     - a concept-id (in which case ARGS must be empty)
+     - a nested-requirement (in which case ARGS is a complete argument set)
+     - a placeholder 'auto' (in which case ARGS is a complete argument set).  
*/
bool
-constraints_satisfied_p (tree t, tree args)
+constraints_satisfied_p (tree t, tree args/*= NULL_TREE */)
  {
    if (!flag_concepts)
      return true;
@@ -3227,7 +3169,7 @@ constraints_satisfied_p (tree t, tree args)
     evaluation of template-ids as id-expressions.  */
tree
-evaluate_concept_check (tree check, tsubst_flags_t complain)
+evaluate_concept_check (tree check)
  {
    if (check == error_mark_node)
      return error_mark_node;
@@ -3236,14 +3178,7 @@ evaluate_concept_check (tree check, tsubst_flags_t 
complain)
/* Check for satisfaction without diagnostics. */
    sat_info quiet (tf_none, NULL_TREE);
-  tree result = satisfy_constraint_expression (check, NULL_TREE, quiet);
-  if (result == error_mark_node && (complain & tf_error))
-    {
-      /* Replay the error with re-normalized requirements.  */
-      sat_info noisy (tf_warning_or_error, NULL_TREE);
-      satisfy_constraint_expression (check, NULL_TREE, noisy);
-    }
-  return result;
+  return constraint_satisfaction_value (check, /*args=*/NULL_TREE, quiet);
  }
/*---------------------------------------------------------------------------
@@ -3709,7 +3644,7 @@ diagnose_nested_requirement (tree req, tree args)
  {
    /* Quietly check for satisfaction first.  */
    sat_info quiet (tf_none, NULL_TREE);
-  tree result = satisfy_constraint_expression (req, args, quiet);
+  tree result = satisfy_nondeclaration_constraints (req, args, quiet);
    if (result == boolean_true_node)
      return;
@@ -3721,7 +3656,7 @@ diagnose_nested_requirement (tree req, tree args)
        inform (loc, "nested requirement %qE is not satisfied, because", expr);
sat_info noisy (tf_warning_or_error, NULL_TREE, /*diag_unsat=*/true);
-      satisfy_constraint_expression (req, args, noisy);
+      satisfy_nondeclaration_constraints (req, args, noisy);
      }
    else
      inform (loc, "nested requirement %qE is not satisfied", expr);
@@ -3854,7 +3789,9 @@ diagnosing_failed_constraint::replay_errors_p ()
  }
/* Emit diagnostics detailing the failure ARGS to satisfy the constraints
-   of T. Here, T can be either a constraint or a declaration.  */
+   of T.  Here, T and ARGS are as in constraints_satisfied_p, except that T
+   can also be a REQUIRES_EXPR (in which case ARGS is must be empty).  The
+   latter is used by finish_static_assert to diagnose a false REQUIRES_EXPR.  
*/
void
  diagnose_constraints (location_t loc, tree t, tree args)
@@ -3866,8 +3803,13 @@ diagnose_constraints (location_t loc, tree t, tree args)
/* Replay satisfaction, but diagnose unsatisfaction. */
    sat_info noisy (tf_warning_or_error, NULL_TREE, /*diag_unsat=*/true);
-  if (!args)
-    constraint_satisfaction_value (t, noisy);
+  if (TREE_CODE (t) == REQUIRES_EXPR)
+    {
+      gcc_assert (!args);
+      ++current_constraint_diagnosis_depth;
+      diagnose_requires_expr (t, /*map=*/NULL_TREE, /*in_decl=*/NULL_TREE);
+      --current_constraint_diagnosis_depth;
+    }
    else
      constraint_satisfaction_value (t, args, noisy);
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index abb8a6ef078..64b1dc1b433 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -1381,7 +1381,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void 
*data)
         normal functions.  */
        if (concept_check_p (stmt))
        {
-         *stmt_p = evaluate_concept_check (stmt, tf_warning_or_error);
+         *stmt_p = evaluate_concept_check (stmt);
          * walk_subtrees = 0;
          break;
        }
@@ -1453,15 +1453,14 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void 
*data)
case REQUIRES_EXPR:
        /* Emit the value of the requires-expression.  */
-      *stmt_p = constant_boolean_node (constraints_satisfied_p (stmt),
-                                      boolean_type_node);
+      *stmt_p = tsubst_requires_expr (stmt, NULL_TREE, tf_none, NULL_TREE);
        *walk_subtrees = 0;
        break;
case TEMPLATE_ID_EXPR:
        gcc_assert (concept_check_p (stmt));
        /* Emit the value of the concept check.  */
-      *stmt_p = evaluate_concept_check (stmt, tf_warning_or_error);
+      *stmt_p = evaluate_concept_check (stmt);
        walk_subtrees = 0;
        break;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 544e99538a4..995e13f4a6e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8123,10 +8123,8 @@ struct processing_constraint_expression_sentinel
  extern bool processing_constraint_expression_p        ();
extern tree unpack_concept_check (tree);
-extern tree evaluate_concept_check              (tree, tsubst_flags_t);
-extern tree satisfy_constraint_expression      (tree);
-extern bool constraints_satisfied_p            (tree);
-extern bool constraints_satisfied_p            (tree, tree);
+extern tree evaluate_concept_check              (tree);
+extern bool constraints_satisfied_p            (tree, tree = NULL_TREE);
  extern bool* lookup_subsumption_result          (tree, tree);
  extern bool save_subsumption_result             (tree, tree, bool);
  extern tree find_template_parameters          (tree, tree);
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index e809f0e4068..3f5467c8283 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -1170,7 +1170,7 @@ convert_to_void (tree expr, impl_conv_void implicit, 
tsubst_flags_t complain)
    /* Explicitly evaluate void-converted concept checks since their
       satisfaction may produce ill-formed programs.  */
     if (concept_check_p (expr))
-     expr = evaluate_concept_check (expr, tf_warning_or_error);
+     expr = evaluate_concept_check (expr);
if (VOID_TYPE_P (TREE_TYPE (expr)))
      return expr;


Reply via email to