@@ -525,7 +525,8 @@ d_save_expr (tree exp)
525525tree
526526stabilize_expr (tree *valuep)
527527{
528- const enum tree_code code = TREE_CODE (*valuep);
528+ tree expr = *valuep;
529+ const enum tree_code code = TREE_CODE (expr);
529530 tree lhs;
530531 tree rhs;
531532
@@ -534,12 +535,21 @@ stabilize_expr (tree *valuep)
534535 case COMPOUND_EXPR:
535536 /* Given ((e1, ...), eN):
536537 Store the last RHS 'eN' expression in VALUEP. */
537- lhs = TREE_OPERAND (*valuep , 0 );
538- rhs = TREE_OPERAND (*valuep , 1 );
538+ lhs = TREE_OPERAND (expr , 0 );
539+ rhs = TREE_OPERAND (expr , 1 );
539540 lhs = compound_expr (lhs, stabilize_expr (&rhs));
540541 *valuep = rhs;
541542 return lhs;
542543
544+ case MODIFY_EXPR:
545+ case INIT_EXPR:
546+ /* Given e1 = e2:
547+ Store the leftmost 'e1' expression in VALUEP. */
548+ lhs = TREE_OPERAND (expr, 0 );
549+ stabilize_expr (&lhs);
550+ *valuep = lhs;
551+ return expr;
552+
543553 default :
544554 return NULL_TREE;
545555 }
@@ -1761,7 +1771,7 @@ build_bounds_condition (const Loc& loc, tree index, tree len, bool inclusive)
17611771bool
17621772array_bounds_check (void )
17631773{
1764- FuncDeclaration *func ;
1774+ FuncDeclaration *fd ;
17651775
17661776 switch (global.params .useArrayBounds )
17671777 {
@@ -1773,10 +1783,10 @@ array_bounds_check (void)
17731783
17741784 case BOUNDSCHECKsafeonly:
17751785 /* For D2 safe functions only. */
1776- func = d_function_chain->function ;
1777- if (func && func ->type ->ty == Tfunction)
1786+ fd = d_function_chain->function ;
1787+ if (fd && fd ->type ->ty == Tfunction)
17781788 {
1779- TypeFunction *tf = (TypeFunction *) func ->type ;
1789+ TypeFunction *tf = (TypeFunction *) fd ->type ;
17801790 if (tf->trust == TRUSTsafe)
17811791 return true ;
17821792 }
@@ -2120,26 +2130,32 @@ build_vthis_function (tree basetype, tree type)
21202130tree
21212131get_frame_for_symbol (Dsymbol *sym)
21222132{
2123- FuncDeclaration *func = d_function_chain ? d_function_chain->function : NULL ;
2124- FuncDeclaration *thisfd = sym->isFuncDeclaration ();
2125- FuncDeclaration *parentfd = NULL ;
2133+ FuncDeclaration *thisfd
2134+ = d_function_chain ? d_function_chain->function : NULL ;
2135+ FuncDeclaration *fd = sym->isFuncDeclaration ();
2136+ FuncDeclaration *fdparent = NULL ;
2137+ FuncDeclaration *fdoverride = NULL ;
21262138
2127- if (thisfd != NULL )
2139+ if (fd != NULL )
21282140 {
21292141 /* Check that the nested function is properly defined. */
2130- if (!thisfd ->fbody )
2142+ if (!fd ->fbody )
21312143 {
2132- /* Should instead error on line that references 'thisfd '. */
2133- thisfd ->error (" nested function missing body" );
2144+ /* Should instead error on line that references 'fd '. */
2145+ fd ->error (" nested function missing body" );
21342146 return null_pointer_node;
21352147 }
21362148
2149+ fdparent = fd->toParent2 ()->isFuncDeclaration ();
2150+
21372151 /* Special case for __ensure and __require. */
2138- if (thisfd->ident == Identifier::idPool (" __ensure" )
2139- || thisfd->ident == Identifier::idPool (" __require" ))
2140- parentfd = func;
2141- else
2142- parentfd = thisfd->toParent2 ()->isFuncDeclaration ();
2152+ if ((fd->ident == Identifier::idPool (" __ensure" )
2153+ || fd->ident == Identifier::idPool (" __require" ))
2154+ && fdparent != thisfd)
2155+ {
2156+ fdoverride = fdparent;
2157+ fdparent = thisfd;
2158+ }
21432159 }
21442160 else
21452161 {
@@ -2148,33 +2164,33 @@ get_frame_for_symbol (Dsymbol *sym)
21482164 while (sym && !sym->isFuncDeclaration ())
21492165 sym = sym->toParent2 ();
21502166
2151- parentfd = (FuncDeclaration *) sym;
2167+ fdparent = (FuncDeclaration *) sym;
21522168 }
21532169
2154- gcc_assert (parentfd != NULL );
2170+ gcc_assert (fdparent != NULL );
21552171
2156- if (func != parentfd )
2172+ if (thisfd != fdparent )
21572173 {
21582174 /* If no frame pointer for this function. */
2159- if (!func ->vthis )
2175+ if (!thisfd ->vthis )
21602176 {
21612177 sym->error (" is a nested function and cannot be accessed from %s" ,
2162- func ->toChars ());
2178+ thisfd ->toChars ());
21632179 return null_pointer_node;
21642180 }
21652181
21662182 /* Make sure we can get the frame pointer to the outer function.
21672183 Go up each nesting level until we find the enclosing function. */
2168- Dsymbol *dsym = func ;
2184+ Dsymbol *dsym = thisfd ;
21692185
2170- while (thisfd != dsym)
2186+ while (fd != dsym)
21712187 {
21722188 /* Check if enclosing function is a function. */
21732189 FuncDeclaration *fd = dsym->isFuncDeclaration ();
21742190
21752191 if (fd != NULL )
21762192 {
2177- if (parentfd == fd->toParent2 ())
2193+ if (fdparent == fd->toParent2 ())
21782194 break ;
21792195
21802196 gcc_assert (fd->isNested () || fd->vthis );
@@ -2188,26 +2204,70 @@ get_frame_for_symbol (Dsymbol *sym)
21882204
21892205 if (ad == NULL )
21902206 goto Lnoframe;
2191- if (ad->isClassDeclaration () && parentfd == ad->toParent2 ())
2207+ if (ad->isClassDeclaration () && fdparent == ad->toParent2 ())
21922208 break ;
2193- if (ad->isStructDeclaration () && parentfd == ad->toParent2 ())
2209+ if (ad->isStructDeclaration () && fdparent == ad->toParent2 ())
21942210 break ;
21952211
21962212 if (!ad->isNested () || !ad->vthis )
21972213 {
21982214 Lnoframe:
2199- func ->error (" cannot get frame pointer to %s" ,
2200- sym->toPrettyChars ());
2215+ thisfd ->error (" cannot get frame pointer to %s" ,
2216+ sym->toPrettyChars ());
22012217 return null_pointer_node;
22022218 }
22032219
22042220 dsym = dsym->toParent2 ();
22052221 }
22062222 }
22072223
2208- tree ffo = get_frameinfo (parentfd );
2224+ tree ffo = get_frameinfo (fdparent );
22092225 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo))
2210- return get_framedecl (func, parentfd);
2226+ {
2227+ tree frame_ref = get_framedecl (thisfd, fdparent);
2228+
2229+ /* If 'thisfd' is a derived member function, then 'fdparent' is the
2230+ overridden member function in the base class. Even if there's a
2231+ closure environment, we should give the original stack data as the
2232+ nested function frame. */
2233+ if (fdoverride)
2234+ {
2235+ ClassDeclaration *cdo = fdoverride->isThis ()->isClassDeclaration ();
2236+ ClassDeclaration *cd = thisfd->isThis ()->isClassDeclaration ();
2237+ gcc_assert (cdo && cd);
2238+
2239+ int offset;
2240+ if (cdo->isBaseOf (cd, &offset) && offset != 0 )
2241+ {
2242+ /* Generate a new frame to pass to the overriden function that
2243+ has the 'this' pointer adjusted. */
2244+ gcc_assert (offset != OFFSET_RUNTIME);
2245+
2246+ tree type = FRAMEINFO_TYPE (get_frameinfo (fdoverride));
2247+ tree fields = TYPE_FIELDS (type);
2248+ /* The 'this' field comes immediately after the '__chain'. */
2249+ tree thisfield = chain_index (1 , fields);
2250+ vec<constructor_elt, va_gc> *ve = NULL ;
2251+
2252+ tree framefields = TYPE_FIELDS (FRAMEINFO_TYPE (ffo));
2253+ frame_ref = build_deref (frame_ref);
2254+
2255+ for (tree field = fields; field; field = DECL_CHAIN (field))
2256+ {
2257+ tree value = component_ref (frame_ref, framefields);
2258+ if (field == thisfield)
2259+ value = build_offset (value, size_int (offset));
2260+
2261+ CONSTRUCTOR_APPEND_ELT (ve, field, value);
2262+ framefields = DECL_CHAIN (framefields);
2263+ }
2264+
2265+ frame_ref = build_address (build_constructor (type, ve));
2266+ }
2267+ }
2268+
2269+ return frame_ref;
2270+ }
22112271
22122272 return null_pointer_node;
22132273}
@@ -2247,39 +2307,39 @@ d_nested_struct (StructDeclaration *sd)
22472307}
22482308
22492309
2250- /* Starting from the current function FUNC , try to find a suitable value of
2310+ /* Starting from the current function FD , try to find a suitable value of
22512311 'this' in nested function instances. A suitable 'this' value is an
22522312 instance of OCD or a class that has OCD as a base. */
22532313
22542314static tree
22552315find_this_tree (ClassDeclaration *ocd)
22562316{
2257- FuncDeclaration *func = d_function_chain ? d_function_chain->function : NULL ;
2317+ FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL ;
22582318
2259- while (func )
2319+ while (fd )
22602320 {
2261- AggregateDeclaration *ad = func ->isThis ();
2321+ AggregateDeclaration *ad = fd ->isThis ();
22622322 ClassDeclaration *cd = ad ? ad->isClassDeclaration () : NULL ;
22632323
22642324 if (cd != NULL )
22652325 {
22662326 if (ocd == cd)
2267- return get_decl_tree (func ->vthis );
2327+ return get_decl_tree (fd ->vthis );
22682328 else if (ocd->isBaseOf (cd, NULL ))
2269- return convert_expr (get_decl_tree (func ->vthis ),
2329+ return convert_expr (get_decl_tree (fd ->vthis ),
22702330 cd->type , ocd->type );
22712331
2272- func = d_nested_class (cd);
2332+ fd = d_nested_class (cd);
22732333 }
22742334 else
22752335 {
2276- if (func ->isNested ())
2336+ if (fd ->isNested ())
22772337 {
2278- func = func ->toParent2 ()->isFuncDeclaration ();
2338+ fd = fd ->toParent2 ()->isFuncDeclaration ();
22792339 continue ;
22802340 }
22812341
2282- func = NULL ;
2342+ fd = NULL ;
22832343 }
22842344 }
22852345
0 commit comments