Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

more on destructors

  • Loading branch information...
commit 931100137ee60f5d269f6c0bcf2ae34d188d54db 1 parent 085715a
Walter Bright authored March 24, 2011
16  src/declaration.c
@@ -1114,6 +1114,8 @@ void VarDeclaration::semantic(Scope *sc)
1114 1114
                 Expression *e1 = new VarExp(loc, this);
1115 1115
 
1116 1116
                 Type *t = type->toBasetype();
  1117
+
  1118
+            Linit2:
1117 1119
                 if (t->ty == Tsarray && !(storage_class & (STCref | STCout)))
1118 1120
                 {
1119 1121
                     ei->exp = ei->exp->semantic(sc);
@@ -1174,6 +1176,15 @@ void VarDeclaration::semantic(Scope *sc)
1174 1176
                             }
1175 1177
                         }
1176 1178
                     }
  1179
+
  1180
+                    /* Look for ((S tmp = S()),tmp) and replace it with just S()
  1181
+                     */
  1182
+                    Expression *e2 = ei->exp->isTemp();
  1183
+                    if (e2)
  1184
+                    {
  1185
+                        ei->exp = e2;
  1186
+                        goto Linit2;
  1187
+                    }
1177 1188
 #endif
1178 1189
                     if (!ei->exp->implicitConvTo(type))
1179 1190
                     {
@@ -1351,6 +1362,11 @@ void VarDeclaration::semantic(Scope *sc)
1351 1362
     if (edtor)
1352 1363
     {
1353 1364
         edtor = edtor->semantic(sc);
  1365
+
  1366
+#if 0 // currently disabled because of std.stdio.stdin, stdout and stderr
  1367
+        if (isDataseg() && !(storage_class & STCextern))
  1368
+            error("static storage variables cannot have destructors");
  1369
+#endif
1354 1370
     }
1355 1371
 
1356 1372
     sem = SemanticDone;
7  src/dump.c
@@ -137,7 +137,12 @@ void DelegateExp::dump(int i)
137 137
 void BinExp::dump(int i)
138 138
 {
139 139
     indent(i);
140  
-    printf("%p %s type=%s e1=%p e2=%p\n", this, Token::toChars(op), type_print(type), e1, e2);
  140
+    const char *sop = Token::toChars(op);
  141
+    if (op == TOKblit)
  142
+        sop = "blit";
  143
+    else if (op == TOKconstruct)
  144
+        sop = "construct";
  145
+    printf("%p %s type=%s e1=%p e2=%p\n", this, sop, type_print(type), e1, e2);
141 146
     if (e1)
142 147
         e1->dump(i + 2);
143 148
     if (e2)
74  src/e2ir.c
@@ -49,7 +49,7 @@ elem *addressElem(elem *e, Type *t);
49 49
 elem *array_toPtr(Type *t, elem *e);
50 50
 elem *bit_assign(enum OPER op, elem *eb, elem *ei, elem *ev, int result);
51 51
 elem *bit_read(elem *eb, elem *ei, int result);
52  
-elem *exp2_copytotemp(elem *e);
  52
+elem *appendDtors(IRState *irs, elem *er, size_t starti, size_t endi);
53 53
 
54 54
 #define el_setLoc(e,loc)        ((e)->Esrcpos.Sfilename = (char *)(loc).filename, \
55 55
                                  (e)->Esrcpos.Slinnum = (loc).linnum)
@@ -1142,11 +1142,8 @@ elem *Dsymbol_toElem(Dsymbol *s, IRState *irs)
1142 1142
             vd->toObjFile(0);
1143 1143
         else
1144 1144
         {
1145  
-//printf("Dsymbol_toElem() %x\n", vd->storage_class);
1146 1145
             sp = s->toSymbol();
1147  
-//printf("test1 %d\n", cstate.CSpsymtab->top);
1148 1146
             symbol_add(sp);
1149  
-//printf("test2 %d\n", cstate.CSpsymtab->top);
1150 1147
             //printf("\tadding symbol '%s'\n", sp->Sident);
1151 1148
             if (vd->init)
1152 1149
             {
@@ -1156,14 +1153,18 @@ elem *Dsymbol_toElem(Dsymbol *s, IRState *irs)
1156 1153
                 if (ie)
1157 1154
                     e = ie->exp->toElem(irs);
1158 1155
             }
1159  
-#if 1
  1156
+
1160 1157
             /* Mark the point of construction of a variable that needs to be destructed.
1161 1158
              */
1162 1159
             if (vd->edtor && !vd->noscope)
1163 1160
             {
1164 1161
                 e = el_dctor(e, vd);
  1162
+
  1163
+                // Put vd on list of things needing destruction
  1164
+                if (!irs->varsInScope)
  1165
+                    irs->varsInScope = new Array();
  1166
+                irs->varsInScope->push(vd);
1165 1167
             }
1166  
-#endif
1167 1168
         }
1168 1169
     }
1169 1170
     else if ((cd = s->isClassDeclaration()) != NULL)
@@ -3217,7 +3218,21 @@ elem *XorAssignExp::toElem(IRState *irs)
3217 3218
 
3218 3219
 elem *AndAndExp::toElem(IRState *irs)
3219 3220
 {
3220  
-    elem *e = toElemBin(irs,OPandand);
  3221
+    tym_t tym = type->totym();
  3222
+
  3223
+    elem *el = e1->toElem(irs);
  3224
+
  3225
+    size_t starti = irs->varsInScope ? irs->varsInScope->dim : 0;
  3226
+    elem *er = e2->toElem(irs);
  3227
+    size_t endi = irs->varsInScope ? irs->varsInScope->dim : 0;
  3228
+
  3229
+    // Add destructors for e2
  3230
+    er = appendDtors(irs, er, starti, endi);
  3231
+
  3232
+    elem *e = el_bin(OPandand,tym,el,er);
  3233
+
  3234
+    el_setLoc(e,loc);
  3235
+
3221 3236
     if (global.params.cov && e2->loc.linnum)
3222 3237
         e->E2 = el_combine(incUsageElem(irs, e2->loc), e->E2);
3223 3238
     return e;
@@ -3229,7 +3244,21 @@ elem *AndAndExp::toElem(IRState *irs)
3229 3244
 
3230 3245
 elem *OrOrExp::toElem(IRState *irs)
3231 3246
 {
3232  
-    elem *e = toElemBin(irs,OPoror);
  3247
+    tym_t tym = type->totym();
  3248
+
  3249
+    elem *el = e1->toElem(irs);
  3250
+
  3251
+    size_t starti = irs->varsInScope ? irs->varsInScope->dim : 0;
  3252
+    elem *er = e2->toElem(irs);
  3253
+    size_t endi = irs->varsInScope ? irs->varsInScope->dim : 0;
  3254
+
  3255
+    // Add destructors for e2
  3256
+    er = appendDtors(irs, er, starti, endi);
  3257
+
  3258
+    elem *e = el_bin(OPoror,tym,el,er);
  3259
+
  3260
+    el_setLoc(e,loc);
  3261
+
3233 3262
     if (global.params.cov && e2->loc.linnum)
3234 3263
         e->E2 = el_combine(incUsageElem(irs, e2->loc), e->E2);
3235 3264
     return e;
@@ -5075,3 +5104,32 @@ elem *StructLiteralExp::toElem(IRState *irs)
5075 5104
     el_setLoc(e,loc);
5076 5105
     return e;
5077 5106
 }
  5107
+
  5108
+/********************************************
  5109
+ * Add destructors
  5110
+ */
  5111
+
  5112
+elem *appendDtors(IRState *irs, elem *er, size_t starti, size_t endi)
  5113
+{
  5114
+    //printf("appendDtors(%d .. %d)\n", starti, endi);
  5115
+    elem *edtors = NULL;
  5116
+    for (size_t i = endi; i != starti;)
  5117
+    {
  5118
+        --i;
  5119
+        VarDeclaration *vd = (VarDeclaration *)irs->varsInScope->data[i];
  5120
+        if (vd)
  5121
+        {
  5122
+            //printf("appending dtor\n");
  5123
+            irs->varsInScope->data[i] = NULL;
  5124
+            elem *ed = vd->edtor->toElem(irs);
  5125
+            edtors = el_combine(edtors, ed);
  5126
+        }
  5127
+    }
  5128
+    if (edtors)
  5129
+    {
  5130
+        elem *e = el_same(&er);
  5131
+        er = el_combine(er, edtors);
  5132
+        er = el_combine(er, e);
  5133
+    }
  5134
+    return er;
  5135
+}
42  src/eh.c
@@ -30,6 +30,11 @@
30 30
 static char __file__[] = __FILE__;      /* for tassert.h                */
31 31
 #include        "tassert.h"
32 32
 
  33
+/* If we do our own EH tables and stack walking scheme
  34
+ * (Otherwise use NT Structured Exception Handling)
  35
+ */
  36
+#define OUREH   (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS)
  37
+
33 38
 /****************************
34 39
  * Generate and output scope table.
35 40
  */
@@ -37,7 +42,7 @@ static char __file__[] = __FILE__;      /* for tassert.h                */
37 42
 symbol *except_gentables()
38 43
 {
39 44
     //printf("except_gentables()\n");
40  
-#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
  45
+#if OUREH
41 46
 
42 47
     // BUG: alloca() changes the stack size, which is not reflected
43 48
     // in the fixed eh tables.
@@ -61,6 +66,17 @@ symbol *except_gentables()
61 66
  * Initializes the symbol s with the contents of the exception handler table.
62 67
  */
63 68
 
  69
+struct Guard
  70
+{
  71
+#if OUREH
  72
+    unsigned offset;            // offset of start of guarded section (Linux)
  73
+    unsigned endoffset;         // ending offset of guarded section (Linux)
  74
+#endif
  75
+    int last_index;             // previous index (enclosing guarded section)
  76
+    unsigned catchoffset;       // offset to catch block from symbol
  77
+    void *finally;              // finally code to execute
  78
+};
  79
+
64 80
 void except_fillInEHTable(symbol *s)
65 81
 {
66 82
     unsigned fsize = NPTRSIZE;             // target size of function pointer
@@ -71,12 +87,7 @@ void except_fillInEHTable(symbol *s)
71 87
         unsigned        offset of ESP from EBP
72 88
         unsigned        offset from start of function to return code
73 89
         unsigned nguards;       // dimension of guard[] (Linux)
74  
-        {   unsigned offset;    // offset of start of guarded section (Linux)
75  
-            unsigned endoffset; // ending offset of guarded section (Linux)
76  
-            int last_index;     // previous index (enclosing guarded section)
77  
-            unsigned catchoffset;       // offset to catch block from symbol
78  
-            void *finally;      // finally code to execute
79  
-        } guard[];
  90
+        Guard guard[];
80 91
       catchoffset:
81 92
         unsigned ncatches;      // number of catch blocks
82 93
         {   void *type;         // symbol representing type
@@ -85,10 +96,13 @@ void except_fillInEHTable(symbol *s)
85 96
         } catch[];
86 97
      */
87 98
 
88  
-#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
89  
-#define GUARD_SIZE      (I64 ? 3*8 : 5*4)     // number of bytes in one guard
  99
+/* Be careful of this, as we need the sizeof Guard on the target, not
  100
+ * in the compiler.
  101
+ */
  102
+#if OUREH
  103
+#define GUARD_SIZE      (I64 ? 3*8 : 5*4)     // sizeof(Guard)
90 104
 #else
91  
-#define GUARD_SIZE      (3*4)
  105
+#define GUARD_SIZE      (sizeof(Guard))
92 106
 #endif
93 107
 
94 108
     int sz = 0;
@@ -119,7 +133,7 @@ void except_fillInEHTable(symbol *s)
119 133
 //              b->BC, b->Bscope_index, b->Blast_index, b->Boffset);
120 134
     }
121 135
 
122  
-#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
  136
+#if OUREH
123 137
     pdt = dtsize_t(pdt,guarddim);
124 138
     sz += NPTRSIZE;
125 139
 #endif
@@ -143,7 +157,7 @@ void except_fillInEHTable(symbol *s)
143 157
 
144 158
             int nsucc = list_nitems(b->Bsucc);
145 159
 
146  
-#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
  160
+#if OUREH
147 161
             //printf("DHandlerInfo: offset = %x", (int)(b->Boffset - startblock->Boffset));
148 162
             pdt = dtdword(pdt,b->Boffset - startblock->Boffset);        // offset to start of block
149 163
 
@@ -179,7 +193,7 @@ void except_fillInEHTable(symbol *s)
179 193
                 assert(bhandler->BC == BC_finally);
180 194
                 // To successor of BC_finally block
181 195
                 bhandler = list_block(bhandler->Bsucc);
182  
-#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
  196
+#if OUREH
183 197
                 pdt = dtxoff(pdt,funcsym_p,bhandler->Boffset - startblock->Boffset, TYnptr);    // finally handler address
184 198
 #else
185 199
                 pdt = dtcoff(pdt,bhandler->Boffset);  // finally handler address
@@ -211,7 +225,7 @@ void except_fillInEHTable(symbol *s)
211 225
 
212 226
                     pdt = dtsize_t(pdt,cod3_bpoffset(b->jcatchvar));     // EBP offset
213 227
 
214  
-#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
  228
+#if OUREH
215 229
                     pdt = dtxoff(pdt,funcsym_p,bcatch->Boffset - startblock->Boffset, TYnptr);  // catch handler address
216 230
 #else
217 231
                     pdt = dtcoff(pdt,bcatch->Boffset);        // catch handler address
59  src/expression.c
@@ -743,7 +743,12 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
743 743
                 }
744 744
             }
745 745
 
  746
+            // Do not allow types that need destructors
  747
+            if (arg->type->needsDestruction())
  748
+                arg->error("cannot pass types that need destruction as variadic arguments");
  749
+
746 750
             // Convert static arrays to dynamic arrays
  751
+            // BUG: I don't think this is right for D2
747 752
             tb = arg->type->toBasetype();
748 753
             if (tb->ty == Tsarray)
749 754
             {   TypeSArray *ts = (TypeSArray *)tb;
@@ -1412,6 +1417,44 @@ Expressions *Expression::arraySyntaxCopy(Expressions *exps)
1412 1417
     return a;
1413 1418
 }
1414 1419
 
  1420
+/***************************************************
  1421
+ * Recognize expressions of the form:
  1422
+ *      ((T v = init), v)
  1423
+ * where v is a temp.
  1424
+ * This is used in optimizing out unnecessary temporary generation.
  1425
+ * Returns initializer expression of v if so, NULL if not.
  1426
+ */
  1427
+
  1428
+Expression *Expression::isTemp()
  1429
+{
  1430
+    //printf("isTemp() %s\n", toChars());
  1431
+    if (op == TOKcomma)
  1432
+    {   CommaExp *ec = (CommaExp *)this;
  1433
+        if (ec->e1->op == TOKdeclaration &&
  1434
+            ec->e2->op == TOKvar)
  1435
+        {   DeclarationExp *de = (DeclarationExp *)ec->e1;
  1436
+            VarExp *ve = (VarExp *)ec->e2;
  1437
+            if (ve->var == de->declaration && ve->var->storage_class & STCctfe)
  1438
+            {   VarDeclaration *v = ve->var->isVarDeclaration();
  1439
+                if (v && v->init)
  1440
+                {
  1441
+                    ExpInitializer *ei = v->init->isExpInitializer();
  1442
+                    if (ei)
  1443
+                    {   Expression *e = ei->exp;
  1444
+                        if (e->op == TOKconstruct)
  1445
+                        {   ConstructExp *ce = (ConstructExp *)e;
  1446
+                            if (ce->e1->op == TOKvar && ((VarExp *)ce->e1)->var == ve->var)
  1447
+                                e = ce->e2;
  1448
+                        }
  1449
+                        return e;
  1450
+                    }
  1451
+                }
  1452
+            }
  1453
+        }
  1454
+    }
  1455
+    return NULL;
  1456
+}
  1457
+
1415 1458
 /******************************** IntegerExp **************************/
1416 1459
 
1417 1460
 IntegerExp::IntegerExp(Loc loc, dinteger_t value, Type *type)
@@ -3389,6 +3432,22 @@ Expression *StructLiteralExp::semantic(Scope *sc)
3389 3432
     }
3390 3433
 
3391 3434
     type = stype ? stype : sd->type;
  3435
+
  3436
+    /* If struct requires a destructor, rewrite as:
  3437
+     *    (S tmp = S()),tmp
  3438
+     * so that the destructor can be hung on tmp.
  3439
+     */
  3440
+    if (sd->dtor)
  3441
+    {
  3442
+        Identifier *idtmp = Lexer::uniqueId("__sl");
  3443
+        VarDeclaration *tmp = new VarDeclaration(loc, type, idtmp, new ExpInitializer(0, this));
  3444
+        tmp->storage_class |= STCctfe;
  3445
+        Expression *ae = new DeclarationExp(loc, tmp);
  3446
+        Expression *e = new CommaExp(loc, ae, new VarExp(loc, tmp));
  3447
+        e = e->semantic(sc);
  3448
+        return e;
  3449
+    }
  3450
+
3392 3451
     return this;
3393 3452
 }
3394 3453
 
4  src/expression.h
... ...
@@ -1,6 +1,6 @@
1 1
 
2 2
 // Compiler implementation of the D programming language
3  
-// Copyright (c) 1999-2010 by Digital Mars
  3
+// Copyright (c) 1999-2011 by Digital Mars
4 4
 // All Rights Reserved
5 5
 // written by Walter Bright
6 6
 // http://www.digitalmars.com
@@ -44,6 +44,7 @@ struct BinExp;
44 44
 struct InterState;
45 45
 struct Symbol;          // back end symbol
46 46
 struct OverloadSet;
  47
+struct Initializer;
47 48
 
48 49
 enum TOK;
49 50
 
@@ -131,6 +132,7 @@ struct Expression : Object
131 132
     Expression *addressOf(Scope *sc);
132 133
     Expression *deref();
133 134
     Expression *integralPromotions(Scope *sc);
  135
+    Expression *isTemp();
134 136
 
135 137
     Expression *toDelegate(Scope *sc, Type *t);
136 138
     virtual void scanForNestedRef(Scope *sc);
2  src/interpret.c
@@ -3106,7 +3106,7 @@ Expression *AssertExp::interpret(InterState *istate)
3106 3106
         if (ade->e1->op == TOKthis && istate->localThis)
3107 3107
             if (istate->localThis->op == TOKdotvar
3108 3108
                 && ((DotVarExp *)(istate->localThis))->e1->op == TOKthis)
3109  
-                return getVarExp(loc, istate, ((DotVarExp*)(istate->localThis))->var);                
  3109
+                return getVarExp(loc, istate, ((DotVarExp*)(istate->localThis))->var);
3110 3110
             else
3111 3111
                 return istate->localThis->interpret(istate);
3112 3112
     }
7  src/irstate.c
... ...
@@ -1,6 +1,6 @@
1 1
 
2 2
 // Compiler implementation of the D programming language
3  
-// Copyright (c) 1999-2009 by Digital Mars
  3
+// Copyright (c) 1999-2011 by Digital Mars
4 4
 // All Rights Reserved
5 5
 // written by Walter Bright
6 6
 // http://www.digitalmars.com
@@ -32,6 +32,7 @@ IRState::IRState(IRState *irs, Statement *s)
32 32
         sthis = irs->sthis;
33 33
         blx = irs->blx;
34 34
         deferToObj = irs->deferToObj;
  35
+        varsInScope = irs->varsInScope;
35 36
     }
36 37
     else
37 38
     {
@@ -41,6 +42,7 @@ IRState::IRState(IRState *irs, Statement *s)
41 42
         sthis = NULL;
42 43
         blx = NULL;
43 44
         deferToObj = NULL;
  45
+        varsInScope = NULL;
44 46
     }
45 47
 }
46 48
 
@@ -64,6 +66,7 @@ IRState::IRState(IRState *irs, Dsymbol *s)
64 66
         sthis = irs->sthis;
65 67
         blx = irs->blx;
66 68
         deferToObj = irs->deferToObj;
  69
+        varsInScope = irs->varsInScope;
67 70
     }
68 71
     else
69 72
     {
@@ -73,6 +76,7 @@ IRState::IRState(IRState *irs, Dsymbol *s)
73 76
         sthis = NULL;
74 77
         blx = NULL;
75 78
         deferToObj = NULL;
  79
+        varsInScope = NULL;
76 80
     }
77 81
 }
78 82
 
@@ -94,6 +98,7 @@ IRState::IRState(Module *m, Dsymbol *s)
94 98
     blx = NULL;
95 99
     deferToObj = NULL;
96 100
     startaddress = NULL;
  101
+    varsInScope = NULL;
97 102
 }
98 103
 
99 104
 block *IRState::getBreakBlock(Identifier *ident)
3  src/irstate.h
... ...
@@ -1,6 +1,6 @@
1 1
 
2 2
 // Compiler implementation of the D programming language
3  
-// Copyright (c) 1999-2008 by Digital Mars
  3
+// Copyright (c) 1999-2011 by Digital Mars
4 4
 // All Rights Reserved
5 5
 // written by Walter Bright
6 6
 // http://www.digitalmars.com
@@ -37,6 +37,7 @@ struct IRState
37 37
     Array *deferToObj;          // array of Dsymbol's to run toObjFile(int multiobj) on later
38 38
     elem *ehidden;              // transmit hidden pointer to CallExp::toElem()
39 39
     Symbol *startaddress;
  40
+    Array *varsInScope;         // variables that are in scope that will need destruction later
40 41
 
41 42
     block *breakBlock;
42 43
     block *contBlock;
8  src/mars.c
... ...
@@ -1,6 +1,6 @@
1 1
 
2 2
 // Compiler implementation of the D programming language
3  
-// Copyright (c) 1999-2010 by Digital Mars
  3
+// Copyright (c) 1999-2011 by Digital Mars
4 4
 // All Rights Reserved
5 5
 // written by Walter Bright
6 6
 // http://www.digitalmars.com
@@ -86,13 +86,13 @@ Global::Global()
86 86
 #error "fix this"
87 87
 #endif
88 88
 
89  
-    copyright = "Copyright (c) 1999-2010 by Digital Mars";
  89
+    copyright = "Copyright (c) 1999-2011 by Digital Mars";
90 90
     written = "written by Walter Bright"
91 91
 #if TARGET_NET
92 92
     "\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates.";
93 93
 #endif
94 94
     ;
95  
-    version = "v2.052";
  95
+    version = "v2.053";
96 96
     global.structalign = 8;
97 97
 
98 98
     memset(&params, 0, sizeof(Param));
@@ -831,7 +831,7 @@ int main(int argc, char *argv[])
831 831
 
832 832
         // Haven't investigated handling these options with multiobj
833 833
         if (!global.params.cov && !global.params.trace
834  
-#if TARGET_WINDOS
  834
+#if 0 && TARGET_WINDOS
835 835
             /* multiobj causes class/struct debug info to be attached to init-data,
836 836
              * but this will not be linked into the executable, so this info is lost.
837 837
              * Bugzilla 4014
29  src/mtype.c
@@ -1605,6 +1605,15 @@ int Type::checkBoolean()
1605 1605
     return isscalar();
1606 1606
 }
1607 1607
 
  1608
+/********************************
  1609
+ * TRUE if when type goes out of scope, it needs a destructor applied.
  1610
+ * Only applies to value types, not ref types.
  1611
+ */
  1612
+int Type::needsDestruction()
  1613
+{
  1614
+    return FALSE;
  1615
+}
  1616
+
1608 1617
 /*********************************
1609 1618
  * Check type to see if it is based on a deprecated symbol.
1610 1619
  */
@@ -3567,6 +3576,11 @@ int TypeSArray::isZeroInit(Loc loc)
3567 3576
     return next->isZeroInit(loc);
3568 3577
 }
3569 3578
 
  3579
+int TypeSArray::needsDestruction()
  3580
+{
  3581
+    return next->needsDestruction();
  3582
+}
  3583
+
3570 3584
 Expression *TypeSArray::defaultInitLiteral(Loc loc)
3571 3585
 {
3572 3586
 #if LOGDEFAULTINIT
@@ -6447,6 +6461,11 @@ int TypeEnum::checkBoolean()
6447 6461
     return sym->memtype->checkBoolean();
6448 6462
 }
6449 6463
 
  6464
+int TypeEnum::needsDestruction()
  6465
+{
  6466
+    return sym->memtype->needsDestruction();
  6467
+}
  6468
+
6450 6469
 MATCH TypeEnum::implicitConvTo(Type *to)
6451 6470
 {   MATCH m;
6452 6471
 
@@ -6650,6 +6669,11 @@ int TypeTypedef::checkBoolean()
6650 6669
     return sym->basetype->checkBoolean();
6651 6670
 }
6652 6671
 
  6672
+int TypeTypedef::needsDestruction()
  6673
+{
  6674
+    return sym->basetype->needsDestruction();
  6675
+}
  6676
+
6653 6677
 Type *TypeTypedef::toBasetype()
6654 6678
 {
6655 6679
     if (sym->inuse)
@@ -7110,6 +7134,11 @@ int TypeStruct::checkBoolean()
7110 7134
     return FALSE;
7111 7135
 }
7112 7136
 
  7137
+int TypeStruct::needsDestruction()
  7138
+{
  7139
+    return sym->dtor != NULL;
  7140
+}
  7141
+
7113 7142
 int TypeStruct::isAssignable()
7114 7143
 {
7115 7144
     /* If any of the fields are const or invariant,
5  src/mtype.h
@@ -313,6 +313,7 @@ struct Type : Object
313 313
     virtual TypeTuple *toArgTypes();
314 314
     virtual Type *nextOf();
315 315
     uinteger_t sizemask();
  316
+    virtual int needsDestruction();
316 317
 
317 318
     static void error(Loc loc, const char *format, ...);
318 319
     static void warning(Loc loc, const char *format, ...);
@@ -429,6 +430,7 @@ struct TypeSArray : TypeArray
429 430
     TypeInfoDeclaration *getTypeInfoDeclaration();
430 431
     Expression *toExpression();
431 432
     int hasPointers();
  433
+    int needsDestruction();
432 434
     TypeTuple *toArgTypes();
433 435
 #if CPP_MANGLE
434 436
     void toCppMangle(OutBuffer *buf, CppMangleState *cms);
@@ -716,6 +718,7 @@ struct TypeStruct : Type
716 718
     int isZeroInit(Loc loc);
717 719
     int isAssignable();
718 720
     int checkBoolean();
  721
+    int needsDestruction();
719 722
     dt_t **toDt(dt_t **pdt);
720 723
     MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
721 724
     TypeInfoDeclaration *getTypeInfoDeclaration();
@@ -755,6 +758,7 @@ struct TypeEnum : Type
755 758
     int isunsigned();
756 759
     int checkBoolean();
757 760
     int isAssignable();
  761
+    int needsDestruction();
758 762
     MATCH implicitConvTo(Type *to);
759 763
     MATCH constConv(Type *to);
760 764
     Type *toBasetype();
@@ -796,6 +800,7 @@ struct TypeTypedef : Type
796 800
     int isunsigned();
797 801
     int checkBoolean();
798 802
     int isAssignable();
  803
+    int needsDestruction();
799 804
     Type *toBasetype();
800 805
     MATCH implicitConvTo(Type *to);
801 806
     MATCH constConv(Type *to);
1  src/statement.c
@@ -344,6 +344,7 @@ Statement *ExpStatement::scopeCode(Scope *sc, Statement **sentry, Statement **se
344 344
 #endif
345 345
                     *sfinally = new ExpStatement(loc, e);
346 346
                 }
  347
+                v->noscope = 1;         // don't add in dtor again
347 348
             }
348 349
         }
349 350
     }

0 notes on commit 9311001

Please sign in to comment.
Something went wrong with that request. Please try again.