On Wed, Dec 02, 2020 at 01:13:26PM +0100, Jakub Jelinek via Gcc-patches wrote: > On Tue, Dec 01, 2020 at 04:05:22PM -0500, Jason Merrill via Gcc-patches wrote: > > Or simpler might be to always defer immediate evaluation of > > source_location::current() until genericize time. > > That works. > I had to change constexpr.c too so that it temporarily adjusts > current_function_decl from the constexpr evaluation context, but we do the > same already from __builtin_FUNCTION (). > > Tested on x86_64-linux and i686-linux, ok for trunk if it passes full > bootstrap/regtest?
I have a few comments, but only minor things; please feel free to ignore them. > --- gcc/cp/tree.c.jj 2020-12-01 16:13:01.717818429 +0100 > +++ gcc/cp/tree.c 2020-12-02 11:53:19.032696933 +0100 > @@ -2968,6 +2968,37 @@ array_type_nelts_total (tree type) > return sz; > } > > +/* Return true if FNDECL is std::source_location::current () method. */ > + > +bool > +source_location_current_p (tree fndecl) > +{ > + gcc_checking_assert (TREE_CODE (fndecl) == FUNCTION_DECL > + && DECL_IMMEDIATE_FUNCTION_P (fndecl)); > + if (DECL_NAME (fndecl) == NULL_TREE > + || TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE > + || TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != RECORD_TYPE > + || DECL_CONTEXT (fndecl) != TREE_TYPE (TREE_TYPE (fndecl))) > + return false; > + > + if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "current") != 0) > + return false; You could use id_equal. > + tree source_location = DECL_CONTEXT (fndecl); > + if (TYPE_NAME (source_location) == NULL_TREE > + || TREE_CODE (TYPE_NAME (source_location)) != TYPE_DECL > + || DECL_NAME (TYPE_NAME (source_location)) == NULL_TREE > + || strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME > (source_location))), > + "source_location") != 0) > + return false; And here too. > + tree decl > + = lookup_qualified_name (std_node, > + DECL_NAME (TYPE_NAME (source_location)), > + LOOK_want::TYPE, tf_none); > + return TYPE_NAME (source_location) == decl; Can this be decl_in_std_namespace_p? > --- gcc/cp/constexpr.c.jj 2020-11-26 16:22:24.250407040 +0100 > +++ gcc/cp/constexpr.c 2020-12-02 12:35:11.458852298 +0100 > @@ -1332,7 +1332,14 @@ cxx_eval_builtin_function_call (const co > } > > if (fndecl_built_in_p (fun, CP_BUILT_IN_SOURCE_LOCATION, > BUILT_IN_FRONTEND)) > - return fold_builtin_source_location (EXPR_LOCATION (t)); > + { > + tree save_cur_fn = current_function_decl; You could use temp_override<tree> ovr (current_function_decl); to avoid having to restore c_f_d manually. > + if (ctx->call && ctx->call->fundef) > + current_function_decl = ctx->call->fundef->decl; > + t = fold_builtin_source_location (EXPR_LOCATION (t)); > + current_function_decl = save_cur_fn; > + return t; > + } > > int strops = 0; > int strret = 0; > --- gcc/cp/cp-gimplify.c.jj 2020-11-26 16:22:24.250407040 +0100 > +++ gcc/cp/cp-gimplify.c 2020-12-02 12:26:21.596922205 +0100 > @@ -1374,6 +1374,15 @@ cp_genericize_r (tree *stmt_p, int *walk > break; > } > > + if (call_expr_nargs (stmt) == 0) > + if (tree fndecl = cp_get_callee_fndecl (stmt)) > + if (DECL_IMMEDIATE_FUNCTION_P (fndecl) > + && source_location_current_p (fndecl)) > + { > + *stmt_p = cxx_constant_value (stmt, NULL_TREE); You can drop the ", NULL_TREE". Thanks, Marek