public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/2] c++: remove NON_DEPENDENT_EXPR, part 1
@ 2023-09-25 20:43 Patrick Palka
  2023-09-25 20:43 ` [PATCH 2/2] c++: remove NON_DEPENDENT_EXPR, part 2 Patrick Palka
  2023-09-26 23:18 ` [PATCH 1/2] c++: remove NON_DEPENDENT_EXPR, part 1 Jason Merrill
  0 siblings, 2 replies; 13+ messages in thread
From: Patrick Palka @ 2023-09-25 20:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, Patrick Palka

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK
for trunk?

-- >8 --

This tree code dates all the way back to r69130[1] which implemented
typing of non-dependent expressions.  Its motivation was never clear (to
me at least) since the documentation for it in e.g. cp-tree.def doesn't
seem accurate anymore.  build_non_dependent_expr has since gained
a bunch of edge cases about whether (or how) to wrap certain templated
trees, making it hard to reason about in general.

So this patch removes this tree code, and temporarily turns
build_non_dependent_expr into the identity function.  The subsequent
patch will remove build_non_dependent_expr and adjust its callers
appropriately.

We now need to gracefully handle templated (sub)trees in a couple of
places, places which previously didn't see templated trees since they
didn't look through NON_DEPENDENT_EXPR.

[1]: https://gcc.gnu.org/pipermail/gcc-patches/2003-July/109355.html

gcc/c-family/ChangeLog:

	* c-warn.cc (check_address_or_pointer_of_packed_member): Handle
	templated CALL_EXPR naming a local extern function.

gcc/cp/ChangeLog:

	* class.cc (instantiate_type): Remove NON_DEPENDENT_EXPR
	handling.
	* constexpr.cc (cxx_eval_constant_expression): Likewise.
	(potential_constant_expression_1): Likewise.
	* coroutines.cc (coro_validate_builtin_call): Don't
	expect ALIGNOF_EXPR to be wrapped in NON_DEPENDENT_EXPR.
	* cp-objcp-common.cc (cp_common_init_ts): Remove
	NON_DEPENDENT_EXPR handling.
	* cp-tree.def (NON_DEPENDENT_EXPR): Remove.
	* cp-tree.h (build_non_dependent_expr): Temporarily redefine as
	the identity function.
	* cvt.cc (maybe_warn_nodiscard): Handle templated CALL_EXPR
	naming a local extern function.
	* cxx-pretty-print.cc (cxx_pretty_printer::expression): Remove
	NON_DEPENDENT_EXPR handling.
	* error.cc (dump_decl): Likewise.
	(dump_expr): Likewise.
	* expr.cc (mark_use): Likewise.
	(mark_exp_read): Likewise.
	* pt.cc (build_non_dependent_expr): Remove.
	* tree.cc (lvalue_kind): Remove NON_DEPENDENT_EXPR handling.
	(cp_stabilize_reference): Likewise.
	* typeck.cc (warn_for_null_address): Likewise.
	(cp_build_binary_op): Handle type-dependent SIZEOF_EXPR operands.
	(cp_build_unary_op) <case TRUTH_NOT_EXPR>: Don't fold inside a
	template.

gcc/testsuite/ChangeLog:

	* g++.dg/concepts/var-concept3.C: Adjust expected diagnostic
	for attempting to call a variable concept.
---
 gcc/c-family/c-warn.cc                       |  2 +-
 gcc/cp/class.cc                              |  9 --
 gcc/cp/constexpr.cc                          |  9 --
 gcc/cp/coroutines.cc                         |  3 +-
 gcc/cp/cp-objcp-common.cc                    |  1 -
 gcc/cp/cp-tree.def                           | 11 ---
 gcc/cp/cp-tree.h                             |  2 +-
 gcc/cp/cvt.cc                                |  4 +-
 gcc/cp/cxx-pretty-print.cc                   |  1 -
 gcc/cp/error.cc                              |  8 --
 gcc/cp/expr.cc                               |  2 -
 gcc/cp/pt.cc                                 | 92 --------------------
 gcc/cp/tree.cc                               |  5 --
 gcc/cp/typeck.cc                             | 13 +--
 gcc/testsuite/g++.dg/concepts/var-concept3.C |  2 +-
 15 files changed, 15 insertions(+), 149 deletions(-)

diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index e67dd87a773..c07770394bf 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -3029,7 +3029,7 @@ check_address_or_pointer_of_packed_member (tree type, tree rhs)
       if (TREE_CODE (rhs) == CALL_EXPR)
 	{
 	  rhs = CALL_EXPR_FN (rhs);	/* Pointer expression.  */
-	  if (rhs == NULL_TREE)
+	  if (rhs == NULL_TREE || TREE_CODE (rhs) == IDENTIFIER_NODE)
 	    return NULL_TREE;
 	  rhs = TREE_TYPE (rhs);	/* Pointer type.  */
 	  /* We could be called while processing a template and RHS could be
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index b71333af1f8..10de0437242 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -8843,15 +8843,6 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t complain)
       rhs = BASELINK_FUNCTIONS (rhs);
     }
 
-  /* If we are in a template, and have a NON_DEPENDENT_EXPR, we cannot
-     deduce any type information.  */
-  if (TREE_CODE (rhs) == NON_DEPENDENT_EXPR)
-    {
-      if (complain & tf_error)
-	error ("not enough type information");
-      return error_mark_node;
-    }
-
   /* There are only a few kinds of expressions that may have a type
      dependent on overload resolution.  */
   gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 2a6601c0cbc..8c9abeeec1b 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -8054,7 +8054,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case MODOP_EXPR:
       /* GCC internal stuff.  */
     case VA_ARG_EXPR:
-    case NON_DEPENDENT_EXPR:
     case BASELINK:
     case OFFSET_REF:
       if (!ctx->quiet)
@@ -9922,14 +9921,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
     case BIND_EXPR:
       return RECUR (BIND_EXPR_BODY (t), want_rval);
 
-    case NON_DEPENDENT_EXPR:
-      /* Treat NON_DEPENDENT_EXPR as non-constant: it's not handled by
-	 constexpr evaluation or tsubst, so fold_non_dependent_expr can't
-	 do anything useful with it.  And we shouldn't see it in a context
-	 where a constant expression is strictly required, hence the assert.  */
-      gcc_checking_assert (!(flags & tf_error));
-      return false;
-
     case CLEANUP_POINT_EXPR:
     case MUST_NOT_THROW_EXPR:
     case TRY_CATCH_EXPR:
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 3493d3c6ed3..df3cc820797 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1421,8 +1421,7 @@ coro_validate_builtin_call (tree call, tsubst_flags_t)
 	location_t loc = EXPR_LOCATION (arg);
 
 	/* We expect alignof expressions in templates.  */
-	if (TREE_CODE (arg) == NON_DEPENDENT_EXPR
-	    && TREE_CODE (TREE_OPERAND (arg, 0)) == ALIGNOF_EXPR)
+	if (TREE_CODE (arg) == ALIGNOF_EXPR)
 	  ;
 	else if (!TREE_CONSTANT (arg))
 	  {
diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc
index 93b027b80ce..2093ae02466 100644
--- a/gcc/cp/cp-objcp-common.cc
+++ b/gcc/cp/cp-objcp-common.cc
@@ -525,7 +525,6 @@ cp_common_init_ts (void)
   MARK_TS_EXP (MUST_NOT_THROW_EXPR);
   MARK_TS_EXP (NEW_EXPR);
   MARK_TS_EXP (NOEXCEPT_EXPR);
-  MARK_TS_EXP (NON_DEPENDENT_EXPR);
   MARK_TS_EXP (OFFSETOF_EXPR);
   MARK_TS_EXP (OFFSET_REF);
   MARK_TS_EXP (PSEUDO_DTOR_EXPR);
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 0e66ca70e00..d78005e50b9 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -262,17 +262,6 @@ DEFTREECODE (TYPEID_EXPR, "typeid_expr", tcc_expression, 1)
 DEFTREECODE (NOEXCEPT_EXPR, "noexcept_expr", tcc_unary, 1)
 DEFTREECODE (SPACESHIP_EXPR, "spaceship_expr", tcc_expression, 2)
 
-/* A placeholder for an expression that is not type-dependent, but
-   does occur in a template.  When an expression that is not
-   type-dependent appears in a larger expression, we must compute the
-   type of that larger expression.  That computation would normally
-   modify the original expression, which would change the mangling of
-   that expression if it appeared in a template argument list.  In
-   that situation, we create a NON_DEPENDENT_EXPR to take the place of
-   the original expression.  The expression is the only operand -- it
-   is only needed for diagnostics.  */
-DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", tcc_expression, 1)
-
 /* CTOR_INITIALIZER is a placeholder in template code for a call to
    setup_vtbl_pointer (and appears in all functions, not just ctors).  */
 DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", tcc_expression, 1)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6e34952da99..66b9a9c4b9a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7488,7 +7488,7 @@ extern bool any_value_dependent_elements_p      (const_tree);
 extern bool dependent_omp_for_p			(tree, tree, tree, tree);
 extern tree resolve_typename_type		(tree, bool);
 extern tree template_for_substitution		(tree);
-extern tree build_non_dependent_expr		(tree);
+inline tree build_non_dependent_expr		(tree t) { return t; } // XXX remove
 extern void make_args_non_dependent		(vec<tree, va_gc> *);
 extern bool reregister_specialization		(tree, tree, tree);
 extern tree instantiate_non_dependent_expr	(tree, tsubst_flags_t = tf_error);
diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc
index 96abfae7725..fdd34c8562e 100644
--- a/gcc/cp/cvt.cc
+++ b/gcc/cp/cvt.cc
@@ -1048,7 +1048,7 @@ maybe_warn_nodiscard (tree expr, impl_conv_void implicit)
     call = TARGET_EXPR_INITIAL (expr);
   location_t loc = cp_expr_loc_or_input_loc (call);
   tree callee = cp_get_callee (call);
-  if (!callee)
+  if (!callee || identifier_p (callee))
     return;
 
   tree type = TREE_TYPE (callee);
@@ -1056,6 +1056,8 @@ maybe_warn_nodiscard (tree expr, impl_conv_void implicit)
     type = TYPE_PTRMEMFUNC_FN_TYPE (type);
   if (INDIRECT_TYPE_P (type))
     type = TREE_TYPE (type);
+  if (!FUNC_OR_METHOD_TYPE_P (type))
+    return;
 
   tree rettype = TREE_TYPE (type);
   tree fn = cp_get_fndecl_from_callee (callee);
diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc
index eb16e63425f..6a82358f370 100644
--- a/gcc/cp/cxx-pretty-print.cc
+++ b/gcc/cp/cxx-pretty-print.cc
@@ -1207,7 +1207,6 @@ cxx_pretty_printer::expression (tree t)
       assignment_expression (t);
       break;
 
-    case NON_DEPENDENT_EXPR:
     case MUST_NOT_THROW_EXPR:
       expression (TREE_OPERAND (t, 0));
       break;
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 8a5219a68a1..49476a57ead 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -1510,10 +1510,6 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags)
       dump_decl (pp, BASELINK_FUNCTIONS (t), flags);
       break;
 
-    case NON_DEPENDENT_EXPR:
-      dump_expr (pp, t, flags);
-      break;
-
     case TEMPLATE_TYPE_PARM:
       if (flags & TFF_DECL_SPECIFIERS)
 	pp->declaration (t);
@@ -2942,10 +2938,6 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
       pp_cxx_right_paren (pp);
       break;
 
-    case NON_DEPENDENT_EXPR:
-      dump_expr (pp, TREE_OPERAND (t, 0), flags);
-      break;
-
     case ARGUMENT_PACK_SELECT:
       dump_template_argument (pp, ARGUMENT_PACK_SELECT_FROM_PACK (t), flags);
       break;
diff --git a/gcc/cp/expr.cc b/gcc/cp/expr.cc
index cdd29c15fc3..8371a245d95 100644
--- a/gcc/cp/expr.cc
+++ b/gcc/cp/expr.cc
@@ -147,7 +147,6 @@ mark_use (tree expr, bool rvalue_p, bool read_p,
 	}
       break;
     case COMPONENT_REF:
-    case NON_DEPENDENT_EXPR:
       recurse_op[0] = true;
       break;
     case COMPOUND_EXPR:
@@ -371,7 +370,6 @@ mark_exp_read (tree exp)
     case ADDR_EXPR:
     case INDIRECT_REF:
     case FLOAT_EXPR:
-    case NON_DEPENDENT_EXPR:
     case VIEW_CONVERT_EXPR:
       mark_exp_read (TREE_OPERAND (exp, 0));
       break;
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 73ac1cb597c..e565c0538b7 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -29294,98 +29294,6 @@ resolve_typename_type (tree type, bool only_current_p)
   return result;
 }
 
-/* EXPR is an expression which is not type-dependent.  Return a proxy
-   for EXPR that can be used to compute the types of larger
-   expressions containing EXPR.  */
-
-tree
-build_non_dependent_expr (tree expr)
-{
-  tree orig_expr = expr;
-  tree inner_expr;
-
-  /* When checking, try to get a constant value for all non-dependent
-     expressions in order to expose bugs in *_dependent_expression_p
-     and constexpr.  This can affect code generation, see PR70704, so
-     only do this for -fchecking=2.  */
-  if (flag_checking > 1
-      && cxx_dialect >= cxx11
-      /* Don't do this during nsdmi parsing as it can lead to
-	 unexpected recursive instantiations.  */
-      && !parsing_nsdmi ()
-      /* Don't do this during concept processing either and for
-         the same reason.  */
-      && !processing_constraint_expression_p ())
-    fold_non_dependent_expr (expr, tf_none);
-
-  STRIP_ANY_LOCATION_WRAPPER (expr);
-
-  /* Preserve OVERLOADs; the functions must be available to resolve
-     types.  */
-  inner_expr = expr;
-  if (TREE_CODE (inner_expr) == STMT_EXPR)
-    inner_expr = stmt_expr_value_expr (inner_expr);
-  if (TREE_CODE (inner_expr) == ADDR_EXPR)
-    inner_expr = TREE_OPERAND (inner_expr, 0);
-  if (TREE_CODE (inner_expr) == COMPONENT_REF)
-    inner_expr = TREE_OPERAND (inner_expr, 1);
-  if (is_overloaded_fn (inner_expr)
-      || TREE_CODE (inner_expr) == OFFSET_REF)
-    return orig_expr;
-  /* There is no need to return a proxy for a variable, parameter
-     or enumerator.  */
-  if (VAR_P (expr) || TREE_CODE (expr) == PARM_DECL
-      || TREE_CODE (expr) == CONST_DECL)
-    return orig_expr;
-  /* Preserve string constants; conversions from string constants to
-     "char *" are allowed, even though normally a "const char *"
-     cannot be used to initialize a "char *".  */
-  if (TREE_CODE (expr) == STRING_CST)
-    return orig_expr;
-  /* Preserve void and arithmetic constants, as an optimization -- there is no
-     reason to create a new node.  */
-  if (TREE_CODE (expr) == VOID_CST
-      || TREE_CODE (expr) == INTEGER_CST
-      || TREE_CODE (expr) == REAL_CST)
-    return orig_expr;
-  /* Preserve THROW_EXPRs -- all throw-expressions have type "void".
-     There is at least one place where we want to know that a
-     particular expression is a throw-expression: when checking a ?:
-     expression, there are special rules if the second or third
-     argument is a throw-expression.  */
-  if (TREE_CODE (expr) == THROW_EXPR)
-    return orig_expr;
-
-  /* Don't wrap an initializer list, we need to be able to look inside.  */
-  if (BRACE_ENCLOSED_INITIALIZER_P (expr))
-    return orig_expr;
-
-  /* Don't wrap a dummy object, we need to be able to test for it.  */
-  if (is_dummy_object (expr))
-    return orig_expr;
-
-  if (TREE_CODE (expr) == COND_EXPR)
-    return build3 (COND_EXPR,
-		   TREE_TYPE (expr),
-		   build_non_dependent_expr (TREE_OPERAND (expr, 0)),
-		   (TREE_OPERAND (expr, 1)
-		    ? build_non_dependent_expr (TREE_OPERAND (expr, 1))
-		    : build_non_dependent_expr (TREE_OPERAND (expr, 0))),
-		   build_non_dependent_expr (TREE_OPERAND (expr, 2)));
-  if (TREE_CODE (expr) == COMPOUND_EXPR)
-    return build2 (COMPOUND_EXPR,
-		   TREE_TYPE (expr),
-		   TREE_OPERAND (expr, 0),
-		   build_non_dependent_expr (TREE_OPERAND (expr, 1)));
-
-  /* If the type is unknown, it can't really be non-dependent */
-  gcc_assert (TREE_TYPE (expr) != unknown_type_node);
-
-  /* Otherwise, build a NON_DEPENDENT_EXPR.  */
-  return build1_loc (EXPR_LOCATION (orig_expr), NON_DEPENDENT_EXPR,
-		     TREE_TYPE (expr), expr);
-}
-
 /* ARGS is a vector of expressions as arguments to a function call.
    Replace the arguments with equivalent non-dependent expressions.
    This modifies ARGS in place.  */
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index eaf882f8854..a3d61d3e7c9 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -308,7 +308,6 @@ lvalue_kind (const_tree ref)
 	 its argument unmodified and we assign it to a const_tree.  */
       return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)));
 
-    case NON_DEPENDENT_EXPR:
     case PAREN_EXPR:
       return lvalue_kind (TREE_OPERAND (ref, 0));
 
@@ -412,10 +411,6 @@ cp_stabilize_reference (tree ref)
   STRIP_ANY_LOCATION_WRAPPER (ref);
   switch (TREE_CODE (ref))
     {
-    case NON_DEPENDENT_EXPR:
-      /* We aren't actually evaluating this.  */
-      return ref;
-
     /* We need to treat specially anything stabilize_reference doesn't
        handle specifically.  */
     case VAR_DECL:
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 8132bd7fccc..2cfa3c8a935 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -4844,9 +4844,6 @@ warn_for_null_address (location_t location, tree op, tsubst_flags_t complain)
       || warning_suppressed_p (op, OPT_Waddress))
     return;
 
-  if (TREE_CODE (op) == NON_DEPENDENT_EXPR)
-    op = TREE_OPERAND (op, 0);
-
   tree cop = fold_for_warn (op);
 
   if (TREE_CODE (cop) == NON_LVALUE_EXPR)
@@ -5405,7 +5402,9 @@ cp_build_binary_op (const op_location_t &location,
 	    type0 = TREE_TYPE (type0);
 	  if (!TYPE_P (type1))
 	    type1 = TREE_TYPE (type1);
-	  if (INDIRECT_TYPE_P (type0) && same_type_p (TREE_TYPE (type0), type1))
+	  if (type0
+	      && INDIRECT_TYPE_P (type0)
+	      && same_type_p (TREE_TYPE (type0), type1))
 	    {
 	      if (!(TREE_CODE (first_arg) == PARM_DECL
 		    && DECL_ARRAY_PARAMETER_P (first_arg)
@@ -5422,7 +5421,9 @@ cp_build_binary_op (const op_location_t &location,
 			      "first %<sizeof%> operand was declared here");
 		}
 	    }
-	  else if (TREE_CODE (type0) == ARRAY_TYPE
+	  else if (!dependent_type_p (type0)
+		   && !dependent_type_p (type1)
+		   && TREE_CODE (type0) == ARRAY_TYPE
 		   && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0)))
 		   /* Set by finish_parenthesized_expr.  */
 		   && !warning_suppressed_p (op1, OPT_Wsizeof_array_div)
@@ -7399,6 +7400,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
 					 complain);
       if (arg != error_mark_node)
 	{
+	  if (processing_template_decl)
+	    return build1_loc (location, TRUTH_NOT_EXPR, boolean_type_node, arg);
 	  val = invert_truthvalue_loc (location, arg);
 	  if (obvalue_p (val))
 	    val = non_lvalue_loc (location, val);
diff --git a/gcc/testsuite/g++.dg/concepts/var-concept3.C b/gcc/testsuite/g++.dg/concepts/var-concept3.C
index 6fd96a5042e..b4483ebca89 100644
--- a/gcc/testsuite/g++.dg/concepts/var-concept3.C
+++ b/gcc/testsuite/g++.dg/concepts/var-concept3.C
@@ -12,7 +12,7 @@ template<typename T>
 
 
 template<typename U>
-  requires C1<U>() // { dg-error "cannot be used as a function" }
+  requires C1<U>() // { dg-error "cannot call a concept" }
   void f1(U) { }
 
 template<typename U>
-- 
2.42.0.270.gbcb6cae296


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2023-10-20 15:57 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-25 20:43 [PATCH 1/2] c++: remove NON_DEPENDENT_EXPR, part 1 Patrick Palka
2023-09-25 20:43 ` [PATCH 2/2] c++: remove NON_DEPENDENT_EXPR, part 2 Patrick Palka
2023-10-02 19:37   ` [PATCH] c++: merge tsubst_copy into tsubst_copy_and_build Patrick Palka
2023-10-03 12:41     ` Patrick Palka
2023-10-03 21:57       ` Jason Merrill
2023-10-04 16:08         ` Patrick Palka
2023-10-04 19:23           ` [PATCH 2/1] c++: rename tsubst_copy_and_build and tsubst_expr Patrick Palka
2023-10-19 21:43             ` Jason Merrill
2023-10-19 21:43           ` [PATCH] c++: merge tsubst_copy into tsubst_copy_and_build Jason Merrill
2023-10-19 21:46   ` [PATCH 2/2] c++: remove NON_DEPENDENT_EXPR, part 2 Jason Merrill
2023-10-20 15:57   ` Andrew Pinski
2023-09-26 23:18 ` [PATCH 1/2] c++: remove NON_DEPENDENT_EXPR, part 1 Jason Merrill
2023-09-27 11:54   ` Patrick Palka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).