@@ -525,7 +525,8 @@ d_save_expr (tree exp)
525
525
tree
526
526
stabilize_expr (tree *valuep)
527
527
{
528
- const enum tree_code code = TREE_CODE (*valuep);
528
+ tree expr = *valuep;
529
+ const enum tree_code code = TREE_CODE (expr);
529
530
tree lhs;
530
531
tree rhs;
531
532
@@ -534,12 +535,21 @@ stabilize_expr (tree *valuep)
534
535
case COMPOUND_EXPR:
535
536
/* Given ((e1, ...), eN):
536
537
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 );
539
540
lhs = compound_expr (lhs, stabilize_expr (&rhs));
540
541
*valuep = rhs;
541
542
return lhs;
542
543
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
+
543
553
default :
544
554
return NULL_TREE;
545
555
}
@@ -1761,7 +1771,7 @@ build_bounds_condition (const Loc& loc, tree index, tree len, bool inclusive)
1761
1771
bool
1762
1772
array_bounds_check (void )
1763
1773
{
1764
- FuncDeclaration *func ;
1774
+ FuncDeclaration *fd ;
1765
1775
1766
1776
switch (global.params .useArrayBounds )
1767
1777
{
@@ -1773,10 +1783,10 @@ array_bounds_check (void)
1773
1783
1774
1784
case BOUNDSCHECKsafeonly:
1775
1785
/* 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)
1778
1788
{
1779
- TypeFunction *tf = (TypeFunction *) func ->type ;
1789
+ TypeFunction *tf = (TypeFunction *) fd ->type ;
1780
1790
if (tf->trust == TRUSTsafe)
1781
1791
return true ;
1782
1792
}
@@ -2120,26 +2130,32 @@ build_vthis_function (tree basetype, tree type)
2120
2130
tree
2121
2131
get_frame_for_symbol (Dsymbol *sym)
2122
2132
{
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 ;
2126
2138
2127
- if (thisfd != NULL )
2139
+ if (fd != NULL )
2128
2140
{
2129
2141
/* Check that the nested function is properly defined. */
2130
- if (!thisfd ->fbody )
2142
+ if (!fd ->fbody )
2131
2143
{
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" );
2134
2146
return null_pointer_node;
2135
2147
}
2136
2148
2149
+ fdparent = fd->toParent2 ()->isFuncDeclaration ();
2150
+
2137
2151
/* 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
+ }
2143
2159
}
2144
2160
else
2145
2161
{
@@ -2148,33 +2164,33 @@ get_frame_for_symbol (Dsymbol *sym)
2148
2164
while (sym && !sym->isFuncDeclaration ())
2149
2165
sym = sym->toParent2 ();
2150
2166
2151
- parentfd = (FuncDeclaration *) sym;
2167
+ fdparent = (FuncDeclaration *) sym;
2152
2168
}
2153
2169
2154
- gcc_assert (parentfd != NULL );
2170
+ gcc_assert (fdparent != NULL );
2155
2171
2156
- if (func != parentfd )
2172
+ if (thisfd != fdparent )
2157
2173
{
2158
2174
/* If no frame pointer for this function. */
2159
- if (!func ->vthis )
2175
+ if (!thisfd ->vthis )
2160
2176
{
2161
2177
sym->error (" is a nested function and cannot be accessed from %s" ,
2162
- func ->toChars ());
2178
+ thisfd ->toChars ());
2163
2179
return null_pointer_node;
2164
2180
}
2165
2181
2166
2182
/* Make sure we can get the frame pointer to the outer function.
2167
2183
Go up each nesting level until we find the enclosing function. */
2168
- Dsymbol *dsym = func ;
2184
+ Dsymbol *dsym = thisfd ;
2169
2185
2170
- while (thisfd != dsym)
2186
+ while (fd != dsym)
2171
2187
{
2172
2188
/* Check if enclosing function is a function. */
2173
2189
FuncDeclaration *fd = dsym->isFuncDeclaration ();
2174
2190
2175
2191
if (fd != NULL )
2176
2192
{
2177
- if (parentfd == fd->toParent2 ())
2193
+ if (fdparent == fd->toParent2 ())
2178
2194
break ;
2179
2195
2180
2196
gcc_assert (fd->isNested () || fd->vthis );
@@ -2188,26 +2204,70 @@ get_frame_for_symbol (Dsymbol *sym)
2188
2204
2189
2205
if (ad == NULL )
2190
2206
goto Lnoframe;
2191
- if (ad->isClassDeclaration () && parentfd == ad->toParent2 ())
2207
+ if (ad->isClassDeclaration () && fdparent == ad->toParent2 ())
2192
2208
break ;
2193
- if (ad->isStructDeclaration () && parentfd == ad->toParent2 ())
2209
+ if (ad->isStructDeclaration () && fdparent == ad->toParent2 ())
2194
2210
break ;
2195
2211
2196
2212
if (!ad->isNested () || !ad->vthis )
2197
2213
{
2198
2214
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 ());
2201
2217
return null_pointer_node;
2202
2218
}
2203
2219
2204
2220
dsym = dsym->toParent2 ();
2205
2221
}
2206
2222
}
2207
2223
2208
- tree ffo = get_frameinfo (parentfd );
2224
+ tree ffo = get_frameinfo (fdparent );
2209
2225
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
+ }
2211
2271
2212
2272
return null_pointer_node;
2213
2273
}
@@ -2247,39 +2307,39 @@ d_nested_struct (StructDeclaration *sd)
2247
2307
}
2248
2308
2249
2309
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
2251
2311
'this' in nested function instances. A suitable 'this' value is an
2252
2312
instance of OCD or a class that has OCD as a base. */
2253
2313
2254
2314
static tree
2255
2315
find_this_tree (ClassDeclaration *ocd)
2256
2316
{
2257
- FuncDeclaration *func = d_function_chain ? d_function_chain->function : NULL ;
2317
+ FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL ;
2258
2318
2259
- while (func )
2319
+ while (fd )
2260
2320
{
2261
- AggregateDeclaration *ad = func ->isThis ();
2321
+ AggregateDeclaration *ad = fd ->isThis ();
2262
2322
ClassDeclaration *cd = ad ? ad->isClassDeclaration () : NULL ;
2263
2323
2264
2324
if (cd != NULL )
2265
2325
{
2266
2326
if (ocd == cd)
2267
- return get_decl_tree (func ->vthis );
2327
+ return get_decl_tree (fd ->vthis );
2268
2328
else if (ocd->isBaseOf (cd, NULL ))
2269
- return convert_expr (get_decl_tree (func ->vthis ),
2329
+ return convert_expr (get_decl_tree (fd ->vthis ),
2270
2330
cd->type , ocd->type );
2271
2331
2272
- func = d_nested_class (cd);
2332
+ fd = d_nested_class (cd);
2273
2333
}
2274
2334
else
2275
2335
{
2276
- if (func ->isNested ())
2336
+ if (fd ->isNested ())
2277
2337
{
2278
- func = func ->toParent2 ()->isFuncDeclaration ();
2338
+ fd = fd ->toParent2 ()->isFuncDeclaration ();
2279
2339
continue ;
2280
2340
}
2281
2341
2282
- func = NULL ;
2342
+ fd = NULL ;
2283
2343
}
2284
2344
}
2285
2345
0 commit comments