Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 603

Show
Ignore:
Timestamp:
08/06/10 06:09:13 (14 years ago)
Author:
walter
Message:

bugzilla 1678 ref with varargs generates invalid code

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmd-1.x/src/func.c

    r567 r603  
    11991199                    if (v->storage_class & STCout) 
    12001200                    { 
    12011201                        assert(v->init); 
    12021202                        ExpInitializer *ie = v->init->isExpInitializer(); 
    12031203                        assert(ie); 
    12041204                        ie->exp->op = TOKassign; // construction occurred in parameter processing 
    12051205                        a->push(new ExpStatement(0, ie->exp)); 
    12061206                    } 
    12071207                } 
    12081208            } 
    12091209 
    12101210            if (argptr) 
    12111211            {   // Initialize _argptr to point past non-variadic arg 
    12121212#if IN_GCC 
    12131213                // Handled in FuncDeclaration::toObjFile 
    12141214                v_argptr = argptr; 
    12151215                v_argptr->init = new VoidInitializer(loc); 
    12161216#else 
    12171217                Type *t = argptr->type; 
    12181218                VarDeclaration *p; 
    1219                 unsigned offset
     1219                unsigned offset = 0
    12201220 
    12211221                Expression *e1 = new VarExp(0, argptr); 
     1222                // Find the last non-ref parameter 
    12221223                if (parameters && parameters->dim) 
    1223                     p = (VarDeclaration *)parameters->data[parameters->dim - 1]; 
     1224                { 
     1225                    int lastNonref = parameters->dim -1; 
     1226                    p = (VarDeclaration *)parameters->data[lastNonref]; 
     1227                    /* The trouble with out and ref parameters is that taking 
     1228                     * the address of it doesn't work, because later processing 
     1229                     * adds in an extra level of indirection. So we skip over them. 
     1230                     */ 
     1231                    while (p->storage_class & (STCout | STCref)) 
     1232                    { 
     1233                        --lastNonref; 
     1234                        offset += PTRSIZE; 
     1235                        if (lastNonref < 0) 
     1236                        { 
     1237                            p = v_arguments; 
     1238                            break; 
     1239                        } 
     1240                        p = (VarDeclaration *)parameters->data[lastNonref]; 
     1241                    } 
     1242                } 
    12241243                else 
    12251244                    p = v_arguments;            // last parameter is _arguments[] 
    12261245                if (p->storage_class & STClazy) 
    12271246                    // If the last parameter is lazy, it's the size of a delegate 
    1228                     offset = PTRSIZE * 2; 
     1247                    offset += PTRSIZE * 2; 
    12291248                else 
    1230                     offset = p->type->size(); 
    1231                 offset = (offset + 3) & ~3;     // assume stack aligns on 4 
     1249                    offset += p->type->size(); 
     1250                offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1);  // assume stack aligns on pointer size 
    12321251                Expression *e = new SymOffExp(0, p, offset); 
    12331252                e->type = Type::tvoidptr; 
    12341253                //e = e->semantic(sc); 
    12351254                e = new AssignExp(0, e1, e); 
    12361255                e->type = t; 
    12371256                a->push(new ExpStatement(0, e)); 
    12381257#endif 
    12391258            } 
    12401259 
    12411260            if (_arguments) 
    12421261            { 
    12431262                /* Advance to elements[] member of TypeInfo_Tuple with: 
    12441263                 *  _arguments = v_arguments.elements; 
    12451264                 */ 
    12461265                Expression *e = new VarExp(0, v_arguments); 
    12471266                e = new DotIdExp(0, e, Id::elements); 
    12481267                Expression *e1 = new VarExp(0, _arguments); 
    12491268                e = new AssignExp(0, e1, e); 
    12501269                e->op = TOKconstruct; 
    12511270                e = e->semantic(sc2); 
  • trunk/src/func.c

    r567 r603  
    13501350                    { 
    13511351                        assert(v->init); 
    13521352                        ExpInitializer *ie = v->init->isExpInitializer(); 
    13531353                        assert(ie); 
    13541354                        if (ie->exp->op == TOKconstruct) 
    13551355                            ie->exp->op = TOKassign; // construction occured in parameter processing 
    13561356                        a->push(new ExpStatement(0, ie->exp)); 
    13571357                    } 
    13581358                } 
    13591359            } 
    13601360 
    13611361            if (argptr) 
    13621362            {   // Initialize _argptr to point past non-variadic arg 
    13631363#if IN_GCC 
    13641364                // Handled in FuncDeclaration::toObjFile 
    13651365                v_argptr = argptr; 
    13661366                v_argptr->init = new VoidInitializer(loc); 
    13671367#else 
    13681368                Type *t = argptr->type; 
    13691369                VarDeclaration *p; 
    1370                 unsigned offset
     1370                unsigned offset = 0
    13711371 
    13721372                Expression *e1 = new VarExp(0, argptr); 
     1373                // Find the last non-ref parameter 
    13731374                if (parameters && parameters->dim) 
    1374                     p = (VarDeclaration *)parameters->data[parameters->dim - 1]; 
     1375                { 
     1376                    int lastNonref = parameters->dim -1; 
     1377                    p = (VarDeclaration *)parameters->data[lastNonref]; 
     1378                    /* The trouble with out and ref parameters is that taking 
     1379                     * the address of it doesn't work, because later processing 
     1380                     * adds in an extra level of indirection. So we skip over them. 
     1381                     */ 
     1382                    while (p->storage_class & (STCout | STCref)) 
     1383                    { 
     1384                        --lastNonref; 
     1385                        offset += PTRSIZE; 
     1386                        if (lastNonref < 0) 
     1387                        { 
     1388                            p = v_arguments; 
     1389                            break; 
     1390                        } 
     1391                        p = (VarDeclaration *)parameters->data[lastNonref]; 
     1392                    } 
     1393                } 
    13751394                else 
    13761395                    p = v_arguments;            // last parameter is _arguments[] 
    13771396                if (p->storage_class & STClazy) 
    13781397                    // If the last parameter is lazy, it's the size of a delegate 
    1379                     offset = PTRSIZE * 2; 
     1398                    offset += PTRSIZE * 2; 
    13801399                else 
    1381                     offset = p->type->size(); 
    1382                 offset = (offset + 3) & ~3;     // assume stack aligns on 4 
     1400                    offset += p->type->size(); 
     1401                offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1);  // assume stack aligns on pointer size 
    13831402                Expression *e = new SymOffExp(0, p, offset); 
    13841403                e->type = Type::tvoidptr; 
    13851404                //e = e->semantic(sc); 
    13861405                e = new AssignExp(0, e1, e); 
    13871406                e->type = t; 
    13881407                a->push(new ExpStatement(0, e)); 
    13891408                p->isargptr = TRUE; 
    13901409#endif 
    13911410            } 
    13921411 
    13931412            if (_arguments) 
    13941413            { 
    13951414                /* Advance to elements[] member of TypeInfo_Tuple with: 
    13961415                 *  _arguments = v_arguments.elements; 
    13971416                 */ 
    13981417                Expression *e = new VarExp(0, v_arguments); 
    13991418                e = new DotIdExp(0, e, Id::elements); 
    14001419                Expression *e1 = new VarExp(0, _arguments); 
    14011420                e = new ConstructExp(0, e1, e); 
    14021421                e = e->semantic(sc2);