On Wed, 12 Feb 2025, Nathaniel Shead wrote: > 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?
Nice, LGTM! > > -- >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 > >