On Mon, Jan 27, 2025 at 10:20:05AM -0500, Patrick Palka wrote:
> [snip]
>
> > @@ -18486,6 +18562,12 @@ dependent_operand_p (tree t)
> >  {
> >    while (TREE_CODE (t) == IMPLICIT_CONV_EXPR)
> >      t = TREE_OPERAND (t, 0);
> > +
> > +  /* If we contain a TU_LOCAL_ENTITY assume we're non-dependent; we'll 
> > error
> > +     later when instantiating.  */
> > +  if (expr_contains_tu_local_entity (t))
> > +    return false;
> 
> I think it'd be more robust and cheaper (avoiding a separate tree walk)
> to teach the general constexpr/dependence predicates about
> TU_LOCAL_ENTITY instead of handling it only here.
> 
> > +
> >    ++processing_template_decl;
> >    bool r = (potential_constant_expression (t)
> >         ? value_dependent_expression_p (t)
> > @@ -20255,6 +20337,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
> > complain, tree in_decl)
> >     else
> >       object = NULL_TREE;
> >  
> > +   if (function_contains_tu_local_entity (templ))
> > +     RETURN (error_mark_node);
> > +
> >     tree tid = lookup_template_function (templ, targs);
> >     protected_set_expr_location (tid, EXPR_LOCATION (t));
> >  
> > @@ -20947,6 +21032,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
> > complain, tree in_decl)
> >           qualified_p = true;
> >       }
> >  
> > +   if (function_contains_tu_local_entity (function))
> > +     RETURN (error_mark_node);
> 
> Similarly, maybe it'd suffice to check this more generally in the
> OVERLOAD case of tsubst_expr?
> 

So I'd completely missed the idea of handling it in the OVERLOAD case;
doing this also fixes the issues I'd been having trying to handle it in
potential_constant_expression.  I think this should be a lot cleaner
now.

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

-- >8 --

Subject: [PATCH] c++: Handle TU_LOCAL_ENTITY in tsubst_expr and
 potential_constant_expression

This cleans up the TU_LOCAL_ENTITY handling to avoid unnecessary
tree walks and make the logic more robust.

gcc/cp/ChangeLog:

        * constexpr.cc (potential_constant_expression_1): Handle
        TU_LOCAL_ENTITY.
        * pt.cc (expr_contains_tu_local_entity): Remove.
        (function_contains_tu_local_entity): Remove.
        (dependent_operand_p): Remove special handling for
        TU_LOCAL_ENTITY.
        (tsubst_expr): Handle TU_LOCAL_ENTITY when tsubsting OVERLOADs;
        remove now-unnecessary extra handling.
        (type_dependent_expression_p): Handle TU_LOCAL_ENTITY.

Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
---
 gcc/cp/constexpr.cc |  5 +++
 gcc/cp/pt.cc        | 80 ++++++++-------------------------------------
 2 files changed, 19 insertions(+), 66 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index f142dd32bc8..b36705fd4ce 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -10825,6 +10825,11 @@ potential_constant_expression_1 (tree t, bool 
want_rval, bool strict, bool now,
     case CO_RETURN_EXPR:
       return false;
 
+    /* Assume a TU-local entity is not constant, we'll error later when
+       instantiating.  */
+    case TU_LOCAL_ENTITY:
+      return false;
+
     case NONTYPE_ARGUMENT_PACK:
       {
        tree args = ARGUMENT_PACK_ARGS (t);
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index f857b3f1180..966050a6608 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -9935,61 +9935,6 @@ complain_about_tu_local_entity (tree e)
   inform (TU_LOCAL_ENTITY_LOCATION (e), "declared here");
 }
 
-/* Checks if T contains a TU-local entity.  */
-
-static bool
-expr_contains_tu_local_entity (tree t)
-{
-  if (!modules_p ())
-    return false;
-
-  auto walker = [](tree *tp, int *walk_subtrees, void *) -> tree
-    {
-      if (TREE_CODE (*tp) == TU_LOCAL_ENTITY)
-       return *tp;
-      if (!EXPR_P (*tp))
-       *walk_subtrees = false;
-      return NULL_TREE;
-    };
-  return cp_walk_tree (&t, walker, nullptr, nullptr);
-}
-
-/* Errors and returns TRUE if X is a function that contains a TU-local
-   entity in its overload set.  */
-
-static bool
-function_contains_tu_local_entity (tree x)
-{
-  if (!modules_p ())
-    return false;
-
-  if (!x || x == error_mark_node)
-    return false;
-
-  if (TREE_CODE (x) == OFFSET_REF
-      || TREE_CODE (x) == COMPONENT_REF)
-    x = TREE_OPERAND (x, 1);
-  x = MAYBE_BASELINK_FUNCTIONS (x);
-  if (TREE_CODE (x) == TEMPLATE_ID_EXPR)
-    x = TREE_OPERAND (x, 0);
-
-  if (OVL_P (x))
-    for (tree ovl : lkp_range (x))
-      if (TREE_CODE (ovl) == TU_LOCAL_ENTITY)
-       {
-         x = ovl;
-         break;
-       }
-
-  if (TREE_CODE (x) == TU_LOCAL_ENTITY)
-    {
-      complain_about_tu_local_entity (x);
-      return true;
-    }
-
-  return false;
-}
-
 /* Return a TEMPLATE_ID_EXPR corresponding to the indicated FNS and
    ARGLIST.  Valid choices for FNS are given in the cp-tree.def
    documentation for TEMPLATE_ID_EXPR.  */
@@ -18797,11 +18742,6 @@ dependent_operand_p (tree t)
   while (TREE_CODE (t) == IMPLICIT_CONV_EXPR)
     t = TREE_OPERAND (t, 0);
 
-  /* If we contain a TU_LOCAL_ENTITY assume we're non-dependent; we'll error
-     later when instantiating.  */
-  if (expr_contains_tu_local_entity (t))
-    return false;
-
   ++processing_template_decl;
   bool r = (potential_constant_expression (t)
            ? value_dependent_expression_p (t)
@@ -20629,9 +20569,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
        else
          object = NULL_TREE;
 
-       if (function_contains_tu_local_entity (templ))
-         RETURN (error_mark_node);
-
        tree tid = lookup_template_function (templ, targs);
        protected_set_expr_location (tid, EXPR_LOCATION (t));
 
@@ -21324,9 +21261,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
              qualified_p = true;
          }
 
-       if (function_contains_tu_local_entity (function))
-         RETURN (error_mark_node);
-
        nargs = call_expr_nargs (t);
        releasing_vec call_args;
        tsubst_call_args (t, args, complain, in_decl, call_args);
@@ -22122,7 +22056,16 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
       RETURN (t);
 
     case NAMESPACE_DECL:
+      RETURN (t);
+
     case OVERLOAD:
+      if (modules_p ())
+       for (tree ovl : lkp_range (t))
+         if (TREE_CODE (ovl) == TU_LOCAL_ENTITY)
+           {
+             complain_about_tu_local_entity (ovl);
+             RETURN (error_mark_node);
+           }
       RETURN (t);
 
     case TEMPLATE_DECL:
@@ -28990,6 +28933,11 @@ type_dependent_expression_p (tree expression)
 
   STRIP_ANY_LOCATION_WRAPPER (expression);
 
+  /* Assume a TU-local entity is not dependent, we'll error later when
+     instantiating anyway.  */
+  if (TREE_CODE (expression) == TU_LOCAL_ENTITY)
+    return false;
+
   /* An unresolved name is always dependent.  */
   if (identifier_p (expression)
       || TREE_CODE (expression) == USING_DECL)
-- 
2.47.0

Reply via email to