On Tue, 26 Sep 2023, Jason Merrill wrote:

> On 9/25/23 16:43, Patrick Palka wrote:
> > 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
> >              a functor.  In that case it's a class, not a pointer.  */
> >           if (!POINTER_TYPE_P (rhs))
> 
> How about adding !rhs to this condition instead of checking specifically for
> IDENTIFIER_NODE above?

Done.

> 
> >             return NULL_TREE;
> 
> > @@ -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;
> 
> And similarly handling null type here?

Done.

> 
> > @@ -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 type0 were null here, wouldn't we have crashed when checking TYPE_P (type0)
> a few lines above?

In this case type0 was originally a type-dependent expression and became
null after 'type0 = TREE_TYPE (type0)'.

Here's an updated patch with the above changes made, bootstrapped and
regtested on x86_64-pc-linux-gnu.

-- >8 --

Subject: [PATCH] c++: remove NON_DEPENDENT_EXPR, part 1

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 e.g. in 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 more thoroughly handle templated (sub)trees in a couple
of places which previously didn't need to 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
        type-dependent callee of CALL_EXPR.

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 type-dependent and
        variable callee of CALL_EXPR.
        * 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..a0650ec3637 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -3034,7 +3034,7 @@ check_address_or_pointer_of_packed_member (tree type, 
tree rhs)
          rhs = TREE_TYPE (rhs);        /* Pointer type.  */
          /* We could be called while processing a template and RHS could be
             a functor.  In that case it's a class, not a pointer.  */
-         if (!POINTER_TYPE_P (rhs))
+         if (!rhs || !POINTER_TYPE_P (rhs))
            return NULL_TREE;
          rhs = TREE_TYPE (rhs);        /* Function type.  */
          rhstype = TREE_TYPE (rhs);
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..4dfb39fb60b 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 || !TREE_TYPE (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

Reply via email to