On Fri, 1 Oct 2021, Qing Zhao wrote: > > > > On Oct 1, 2021, at 10:33 AM, Jason Merrill <ja...@redhat.com> wrote: > > > > On 10/1/21 10:54, Qing Zhao wrote: > >>> On Sep 30, 2021, at 2:31 PM, Jason Merrill <ja...@redhat.com> wrote: > >>> > >>> On 9/30/21 11:42, Qing Zhao wrote: > >>>>> On Sep 30, 2021, at 1:54 AM, Richard Biener <rguent...@suse.de> wrote: > >>>>> > >>>>> On Thu, 30 Sep 2021, Jason Merrill wrote: > >>>>> > >>>>>> On 9/29/21 17:30, Qing Zhao wrote: > >>>>>>> Hi, > >>>>>>> > >>>>>>> PR102359 (ICE gimplification failed since r12-3433-ga25e0b5e6ac8a77a) > >>>>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102359 > >>>>>>> > >>>>>>> Is due to -ftrivial-auto-var-init adding initialization for READONLY > >>>>>>> variable “this” in the following routine: (t.cpp.005t.original) > >>>>>>> > >>>>>>> ======= > >>>>>>> > >>>>>>> ;; Function A::foo()::<lambda()> (null) > >>>>>>> ;; enabled by -tree-original > >>>>>>> > >>>>>>> { > >>>>>>> const struct A * const this [value-expr: &__closure->__this]; > >>>>>>> const struct A * const this [value-expr: &__closure->__this]; > >>>>>>> return <retval> = (double) ((const struct A *) this)->a; > >>>>>>> } > >>>>>>> ======= > >>>>>>> > >>>>>>> However, in the above routine, “this” is NOT marked as READONLY, but > >>>>>>> its > >>>>>>> value-expr "&__closure->__this” is marked as READONLY. > >>>>>>> > >>>>>>> There are two major issues: > >>>>>>> > >>>>>>> 1. In the routine “is_var_need_auto_init”, we should exclude “decl” > >>>>>>> that is > >>>>>>> marked as READONLY; > >>>>>>> 2. In the C++ FE, “this” should be marked as READONLY. > >>>>>>> > >>>>>>> The idea solution will be: > >>>>>>> > >>>>>>> 1. Fix “is_var_need_auto_init” to exclude TREE_READONLY (decl); > >>>>>>> 2. Fix C++ FE to mark “this” as TREE_READONLY (decl)==true; > >>>>>>> > >>>>>>> Not sure whether it’s hard for C++ FE to fix the 2nd issue or not? > >>>>>>> > >>>>>>> In the case it’s not a quick fix in C++FE, I proposed the following > >>>>>>> fix in > >>>>>>> middle end: > >>>>>>> > >>>>>>> Let me know your comments or suggestions on this. > >>>>>>> > >>>>>>> Thanks a lot for the help. > >>>>>> > >>>>>> I'd think is_var_need_auto_init should be false for any variable with > >>>>>> DECL_HAS_VALUE_EXPR_P, as they aren't really variables, just ways of > >>>>>> naming > >>>>>> objects that are initialized elsewhere. > >>>>> > >>>>> IIRC handing variables with DECL_HAS_VALUE_EXPR_P is necessary to > >>>>> auto-init VLAs, otherwise I tend to agree - would we handle those > >>>>> when we see a DECL_EXPR then? > >>>> The current implementation is: > >>>> gimplify_decl_expr: > >>>> For each DECL_EXPR “decl” > >>>> If (VAR_P (decl) && !DECL_EXTERNAL (decl)) > >>>> { > >>>> if (is_vla (decl)) > >>>> gimplify_vla_decl (decl, …); /* existing handling: create > >>>> a VALUE_EXPR for this vla decl*/ > >>>> … > >>>> if (has_explicit_init (decl)) > >>>> { > >>>> …; /* existing handling. */ > >>>> } > >>>> else if (is_var_need_auto_init (decl)) /*. New code. */ > >>>> { > >>>> gimple_add_init_for_auto_var (….); /* new code. */ > >>>> ... > >>>> } > >>>> } > >>>> Since the “DECL_VALUE_EXPR (decl)” is NOT a DECL_EXPR, it will not be > >>>> scanned and added initialization. > >>>> if we do not add initialization for a decl that has DECL_VALUE_EXPR, > >>>> then the “DECL_VALUE_EXPR (decl)” will not be added an initialization > >>>> either. We will miss adding initializations for these decls. > >>>> So, I think that the current implementation is correct. > >>>> And if C++ FE will not mark “this” as READONLY, only mark > >>>> DECL_VALUE_EXPR(this) as READONLY, the proposed fix is correct too. > >>>> Let me know your opinion on this. > >>> > >>> The problem with this test is not whether the 'this' proxy is marked > >>> READONLY, the problem is that you're trying to initialize lambda capture > >>> proxies at all; the lambda capture objects were already initialized when > >>> forming the closure object. So this test currently aborts with > >>> -ftrivial-auto-var-init=zero because you "initialize" the i capture field > >>> to 0 after it was previously initialized to 42: > >>> > >>> int main() > >>> { > >>> int i = 42; > >>> auto l = [=]() mutable { return i; }; > >>> if (l() != i) > >>> __builtin_abort (); > >>> } > >>> > >>> I believe the same issue applies to the proxy variables in coroutines > >>> that work much like lambdas. > > > >> So, how should the middle end determine that a variable is “proxy > >> variable”? > > > > In the front end, is_capture_proxy will identify a lambda capture proxy > > variable. But that won't be true for the similar proxies used by > > coroutines. > > Does this mean that in middle end, especially in gimplification phase, there > is Not a simple way to determine whether a variable is a proxy variable? > > > >> Have all “proxy variables” been initialized by C++ FE already? > > > > Yes. > > > >>> You can't just assume that a VAR_DECL with DECL_VALUE_EXPR is > >>> uninitialized. > >> So, all the VAR_DECLs with DECL_VALUE_EXPR (except the ones created by > >> “gimplify_decl_expr”) are initialized by FE already? > > > > In general I'd expect them to refer to previously created objects which may > > or may not have been initialized, but if they haven't been, the place to > > deal with that is at their previous creation. > > Still a little confuse..., do you mean, even for VAL_DECLS with > DECL_VALUE_EXPR that were created by FE, we cannot guarantee they have been > initialized? > > What did you mean by “the place to deal with that is at there previous > creation”? > > > > > >>> Since there's already VLA handling in gimplify_decl_expr, you could > >>> remember whether you added DECL_VALUE_EXPR in that function, and only > >>> then do the initialization. > >> Yes, if we can guarantee that all the VAR_DECLs with DECL_VALUE_EXPR > >> created from FEs have been initialized already by FE, we can fix this > >> issue as this way. > > > > Or more generally, check whether the argument to gimplify_decl_expr has > > DECL_VALUE_EXPR when we enter the function, and don't do the initialization > > in that case. > > Yes, we can do that. > > However, the major thing I need to make sure is: > > can we guarantee that for All the VAL_DECLS with DECL_VALUE_EXPR created > by FE are initialized already?
I think so. Richard.