Skip to content

Commit 65fe0cb

Browse files
committed
Merge upstream stable (dlang/dmd@58e4db9880)
1 parent 22e8a8c commit 65fe0cb

30 files changed

+264
-114
lines changed

dmd/aggregate.d

+25-19
Original file line numberDiff line numberDiff line change
@@ -483,31 +483,36 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
483483
* Align sizes of 0, as we may not know array sizes yet.
484484
* Params:
485485
* alignment = struct alignment that is in effect
486-
* size = alignment requirement of field
486+
* memalignsize = natural alignment of field
487487
* poffset = pointer to offset to be aligned
488488
*/
489-
extern (D) static void alignmember(structalign_t alignment, uint size, uint* poffset) pure nothrow @safe
489+
extern (D) static void alignmember(structalign_t alignment, uint memalignsize, uint* poffset) pure nothrow @safe
490490
{
491-
//printf("alignment = %d, size = %d, offset = %d\n",alignment,size,offset);
492-
switch (alignment)
493-
{
494-
case cast(structalign_t)1:
495-
// No alignment
496-
break;
491+
//debug printf("alignment = %u %d, size = %u, offset = %u\n", alignment.get(), alignment.isPack(), memalignsize, *poffset);
492+
uint alignvalue;
497493

498-
case cast(structalign_t)STRUCTALIGN_DEFAULT:
494+
if (alignment.isDefault())
495+
{
499496
// Alignment in Target::fieldalignsize must match what the
500497
// corresponding C compiler's default alignment behavior is.
501-
assert(size > 0 && !(size & (size - 1)));
502-
*poffset = (*poffset + size - 1) & ~(size - 1);
503-
break;
504-
505-
default:
498+
alignvalue = memalignsize;
499+
}
500+
else if (alignment.isPack()) // #pragma pack semantics
501+
{
502+
alignvalue = alignment.get();
503+
if (memalignsize < alignvalue)
504+
alignvalue = memalignsize; // align to min(memalignsize, alignment)
505+
}
506+
else if (alignment.get() > 1)
507+
{
506508
// Align on alignment boundary, which must be a positive power of 2
507-
assert(alignment > 0 && !(alignment & (alignment - 1)));
508-
*poffset = (*poffset + alignment - 1) & ~(alignment - 1);
509-
break;
509+
alignvalue = alignment.get();
510510
}
511+
else
512+
return;
513+
514+
assert(alignvalue > 0 && !(alignvalue & (alignvalue - 1)));
515+
*poffset = (*poffset + alignvalue - 1) & ~(alignvalue - 1);
511516
}
512517

513518
/****************************************
@@ -529,7 +534,8 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
529534
uint ofs = *nextoffset;
530535

531536
const uint actualAlignment =
532-
alignment == STRUCTALIGN_DEFAULT ? memalignsize : alignment;
537+
alignment.isDefault() || alignment.isPack() && memalignsize < alignment.get()
538+
? memalignsize : alignment.get();
533539

534540
// Ensure no overflow
535541
bool overflow;
@@ -538,7 +544,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
538544
if (overflow) assert(0);
539545

540546
// Skip no-op for noreturn without custom aligment
541-
if (memsize != 0 || alignment != STRUCTALIGN_DEFAULT)
547+
if (memsize != 0 || !alignment.isDefault())
542548
alignmember(alignment, memalignsize, &ofs);
543549

544550
uint memoffset = ofs;

dmd/attrib.d

+3-6
Original file line numberDiff line numberDiff line change
@@ -696,12 +696,9 @@ extern (C++) final class AlignDeclaration : AttribDeclaration
696696
{
697697
Expressions* exps; /// Expression(s) yielding the desired alignment,
698698
/// the largest value wins
699-
enum structalign_t UNKNOWN = 0; /// alignment not yet computed
700-
static assert(STRUCTALIGN_DEFAULT != UNKNOWN);
701-
702-
/// the actual alignment, `UNKNOWN` until it's either set to the value of `ealign`
703-
/// or `STRUCTALIGN_DEFAULT` if `ealign` is null ( / an error ocurred)
704-
structalign_t salign = UNKNOWN;
699+
/// the actual alignment is Unknown until it's either set to the value of `ealign`
700+
/// or the default if `ealign` is null ( / an error ocurred)
701+
structalign_t salign;
705702

706703

707704
extern (D) this(const ref Loc loc, Expression exp, Dsymbols* decl)

dmd/clone.d

+10-11
Original file line numberDiff line numberDiff line change
@@ -1079,17 +1079,16 @@ private DtorDeclaration buildWindowsCppDtor(AggregateDeclaration ad, DtorDeclara
10791079
auto ftype = new TypeFunction(ParameterList(params), Type.tvoidptr, LINK.cpp, dtor.storage_class);
10801080
auto func = new DtorDeclaration(dtor.loc, dtor.loc, dtor.storage_class, Id.cppdtor);
10811081
func.type = ftype;
1082-
if (dtor.fbody)
1083-
{
1084-
const loc = dtor.loc;
1085-
auto stmts = new Statements;
1086-
auto call = new CallExp(loc, dtor, null);
1087-
call.directcall = true;
1088-
stmts.push(new ExpStatement(loc, call));
1089-
stmts.push(new ReturnStatement(loc, new CastExp(loc, new ThisExp(loc), Type.tvoidptr)));
1090-
func.fbody = new CompoundStatement(loc, stmts);
1091-
func.generated = true;
1092-
}
1082+
1083+
// Always generate the function with body, because it is not exported from DLLs.
1084+
const loc = dtor.loc;
1085+
auto stmts = new Statements;
1086+
auto call = new CallExp(loc, dtor, null);
1087+
call.directcall = true;
1088+
stmts.push(new ExpStatement(loc, call));
1089+
stmts.push(new ReturnStatement(loc, new CastExp(loc, new ThisExp(loc), Type.tvoidptr)));
1090+
func.fbody = new CompoundStatement(loc, stmts);
1091+
func.generated = true;
10931092

10941093
auto sc2 = sc.push();
10951094
sc2.stc &= ~STC.static_; // not a static destructor

dmd/cparse.d

+12-2
Original file line numberDiff line numberDiff line change
@@ -2524,6 +2524,7 @@ final class CParser(AST) : Parser!AST
25242524
AST.Type cparseTypeName()
25252525
{
25262526
Specifier specifier;
2527+
specifier.packalign.setDefault();
25272528
auto tspec = cparseSpecifierQualifierList(LVL.global, specifier);
25282529
Identifier id;
25292530
return cparseDeclarator(DTR.xabstract, tspec, id, specifier);
@@ -2583,6 +2584,7 @@ final class CParser(AST) : Parser!AST
25832584
}
25842585

25852586
Specifier specifier;
2587+
specifier.packalign.setDefault();
25862588
auto tspec = cparseDeclarationSpecifiers(LVL.prototype, specifier);
25872589
if (tspec && specifier.mod & MOD.xconst)
25882590
{
@@ -2960,6 +2962,7 @@ final class CParser(AST) : Parser!AST
29602962
* enum gnu-attributes (opt) identifier
29612963
*/
29622964
Specifier specifier;
2965+
specifier.packalign.setDefault();
29632966
if (token.value == TOK.__attribute__)
29642967
cparseGnuAttributes(specifier);
29652968

@@ -2996,6 +2999,7 @@ final class CParser(AST) : Parser!AST
29962999
* https://gcc.gnu.org/onlinedocs/gcc/Enumerator-Attributes.html
29973000
*/
29983001
Specifier specifierx;
3002+
specifierx.packalign.setDefault();
29993003
cparseGnuAttributes(specifierx);
30003004
}
30013005

@@ -3013,6 +3017,7 @@ final class CParser(AST) : Parser!AST
30133017
* https://gcc.gnu.org/onlinedocs/gcc/Enumerator-Attributes.html
30143018
*/
30153019
Specifier specifierx;
3020+
specifierx.packalign.setDefault();
30163021
cparseGnuAttributes(specifierx);
30173022
}
30183023

@@ -3451,6 +3456,11 @@ final class CParser(AST) : Parser!AST
34513456
return false;
34523457
continue;
34533458

3459+
case TOK.leftCurly:
3460+
if (!skipBraces(t))
3461+
return false;
3462+
continue;
3463+
34543464
default:
34553465
any = true; // assume token was part of an a-e
34563466
t = peek(t);
@@ -4142,7 +4152,7 @@ final class CParser(AST) : Parser!AST
41424152
SCW scw; /// storage-class specifiers
41434153
MOD mod; /// type qualifiers
41444154
AST.Expressions* alignExps; /// alignment
4145-
structalign_t packalign = STRUCTALIGN_DEFAULT; /// #pragma pack alignment value
4155+
structalign_t packalign; /// #pragma pack alignment value
41464156
}
41474157

41484158
/***********************
@@ -4318,7 +4328,7 @@ final class CParser(AST) : Parser!AST
43184328
(*decls)[0] = s;
43194329
s = new AST.AlignDeclaration(s.loc, specifier.alignExps, decls);
43204330
}
4321-
else if (specifier.packalign != STRUCTALIGN_DEFAULT)
4331+
else if (!specifier.packalign.isDefault())
43224332
{
43234333
//printf(" applying packalign %d\n", cast(int)specifier.packalign);
43244334
// Wrap #pragma pack in an AlignDeclaration

dmd/dcast.d

+31-1
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,29 @@ MATCH implicitConvTo(Expression e, Type t)
14461446
if (tb.ty == Tpointer && e.e1.op == TOK.string_)
14471447
e.e1.accept(this);
14481448
}
1449+
1450+
override void visit(TupleExp e)
1451+
{
1452+
result = e.type.implicitConvTo(t);
1453+
if (result != MATCH.nomatch)
1454+
return;
1455+
1456+
/* If target type is a tuple of same length, test conversion of
1457+
* each expression to the corresponding type in the tuple.
1458+
*/
1459+
TypeTuple totuple = t.isTypeTuple();
1460+
if (totuple && e.exps.length == totuple.arguments.length)
1461+
{
1462+
result = MATCH.exact;
1463+
foreach (i, ex; *e.exps)
1464+
{
1465+
auto to = (*totuple.arguments)[i].type;
1466+
MATCH mi = ex.implicitConvTo(to);
1467+
if (mi < result)
1468+
result = mi;
1469+
}
1470+
}
1471+
}
14491472
}
14501473

14511474
scope ImplicitConvTo v = new ImplicitConvTo(t);
@@ -2182,13 +2205,20 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
21822205
return;
21832206
}
21842207

2208+
/* If target type is a tuple of same length, cast each expression to
2209+
* the corresponding type in the tuple.
2210+
*/
2211+
TypeTuple totuple;
2212+
if (auto tt = t.isTypeTuple())
2213+
totuple = e.exps.length == tt.arguments.length ? tt : null;
2214+
21852215
TupleExp te = e.copy().isTupleExp();
21862216
te.e0 = e.e0 ? e.e0.copy() : null;
21872217
te.exps = e.exps.copy();
21882218
for (size_t i = 0; i < te.exps.dim; i++)
21892219
{
21902220
Expression ex = (*te.exps)[i];
2191-
ex = ex.castTo(sc, t);
2221+
ex = ex.castTo(sc, totuple ? (*totuple.arguments)[i].type : t);
21922222
(*te.exps)[i] = ex;
21932223
}
21942224
result = te;

dmd/dclass.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ version (IN_LLVM) {} else
611611

612612
if (!b.sym.alignsize)
613613
b.sym.alignsize = target.ptrsize;
614-
alignmember(b.sym.alignsize, b.sym.alignsize, &offset);
614+
alignmember(structalign_t(cast(ushort)b.sym.alignsize), b.sym.alignsize, &offset);
615615
assert(bi < vtblInterfaces.dim);
616616

617617
BaseClass* bv = (*vtblInterfaces)[bi];

dmd/declaration.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -1982,7 +1982,7 @@ extern (C++) class TypeInfoDeclaration : VarDeclaration
19821982
storage_class = STC.static_ | STC.gshared;
19831983
visibility = Visibility(Visibility.Kind.public_);
19841984
linkage = LINK.c;
1985-
alignment = target.ptrsize;
1985+
alignment.set(target.ptrsize);
19861986
}
19871987

19881988
static TypeInfoDeclaration create(Type tinfo)

dmd/dinterpret.d

+14-2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import dmd.mtype;
4242
import dmd.printast;
4343
import dmd.root.rmem;
4444
import dmd.root.array;
45+
import dmd.root.ctfloat;
4546
import dmd.root.region;
4647
import dmd.root.rootobject;
4748
import dmd.statement;
@@ -6023,12 +6024,23 @@ version (IN_LLVM)
60236024
}
60246025
if (e.to.ty == Tsarray)
60256026
e1 = resolveSlice(e1);
6026-
if (e.to.toBasetype().ty == Tbool && e1.type.ty == Tpointer)
6027+
6028+
auto tobt = e.to.toBasetype();
6029+
if (tobt.ty == Tbool && e1.type.ty == Tpointer)
60276030
{
60286031
emplaceExp!(IntegerExp)(pue, e.loc, e1.op != TOK.null_, e.to);
60296032
result = pue.exp();
60306033
return;
60316034
}
6035+
else if (tobt.isTypeBasic() && e1.op == TOK.null_)
6036+
{
6037+
if (tobt.isintegral())
6038+
emplaceExp!(IntegerExp)(pue, e.loc, 0, e.to);
6039+
else if (tobt.isreal())
6040+
emplaceExp!(RealExp)(pue, e.loc, CTFloat.zero, e.to);
6041+
result = pue.exp();
6042+
return;
6043+
}
60326044
result = ctfeCast(pue, e.loc, e.type, e.to, e1);
60336045
}
60346046

@@ -6305,7 +6317,7 @@ version (IN_LLVM)
63056317
auto tsa = cast(TypeSArray)v.type;
63066318
auto len = cast(size_t)tsa.dim.toInteger();
63076319
UnionExp ue = void;
6308-
result = createBlockDuplicatedArrayLiteral(&ue, ex.loc, v.type, ex, len);
6320+
result = createBlockDuplicatedArrayLiteral(&ue, e.loc, v.type, result, len);
63096321
if (result == ue.exp())
63106322
result = ue.copy();
63116323
(*se.elements)[i] = result;

dmd/dscope.d

+5-1
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,11 @@ version (IN_LLVM)
745745
return ad.salign;
746746
}
747747
else
748-
return STRUCTALIGN_DEFAULT;
748+
{
749+
structalign_t sa;
750+
sa.setDefault();
751+
return sa;
752+
}
749753
}
750754

751755
/**********************************

dmd/dstruct.d

+2-2
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,10 @@ version (IN_LLVM) {} else
343343
// Round struct size up to next alignsize boundary.
344344
// This will ensure that arrays of structs will get their internals
345345
// aligned properly.
346-
if (alignment == STRUCTALIGN_DEFAULT)
346+
if (alignment.isDefault() || alignment.isPack())
347347
structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
348348
else
349-
structsize = (structsize + alignment - 1) & ~(alignment - 1);
349+
structsize = (structsize + alignment.get() - 1) & ~(alignment.get() - 1);
350350

351351
sizeok = Sizeok.done;
352352

dmd/dsymbolsem.d

+9-7
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,12 @@ else
123123
*/
124124
AlignDeclaration getAlignment(AlignDeclaration ad, Scope* sc)
125125
{
126-
if (ad.salign != ad.UNKNOWN) // UNKNOWN is 0
126+
if (!ad.salign.isUnknown()) // UNKNOWN is 0
127127
return ad;
128128

129129
if (!ad.exps)
130130
{
131-
ad.salign = STRUCTALIGN_DEFAULT;
131+
ad.salign.setDefault();
132132
return ad;
133133
}
134134

@@ -151,7 +151,7 @@ AlignDeclaration getAlignment(AlignDeclaration ad, Scope* sc)
151151
if (sc.flags & SCOPE.Cfile && n == 0) // C11 6.7.5-6 allows 0 for alignment
152152
continue;
153153

154-
if (n < 1 || n & (n - 1) || structalign_t.max < n || !e.type.isintegral())
154+
if (n < 1 || n & (n - 1) || ushort.max < n || !e.type.isintegral())
155155
{
156156
error(ad.loc, "alignment must be an integer positive power of 2, not 0x%llx", cast(ulong)n);
157157
errors = true;
@@ -161,9 +161,11 @@ AlignDeclaration getAlignment(AlignDeclaration ad, Scope* sc)
161161
}
162162
}
163163

164-
ad.salign = (errors || strictest == 0) // C11 6.7.5-6 says alignment of 0 means no effect
165-
? STRUCTALIGN_DEFAULT
166-
: cast(structalign_t) strictest;
164+
if (errors || strictest == 0) // C11 6.7.5-6 says alignment of 0 means no effect
165+
ad.salign.setDefault();
166+
else
167+
ad.salign.set(cast(uint) strictest);
168+
167169
return ad;
168170
}
169171

@@ -451,7 +453,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
451453
* otherwise the scope overrrides.
452454
*/
453455
dsym.alignment = sc.alignment();
454-
if (dsym.alignment == STRUCTALIGN_DEFAULT)
456+
if (dsym.alignment.isDefault())
455457
dsym.alignment = dsym.type.alignment(); // use type's alignment
456458

457459
//printf("sc.stc = %x\n", sc.stc);

0 commit comments

Comments
 (0)