Skip to content

Commit 218c7a2

Browse files
authored
Merge branch 'master' into FixBaseClassList
2 parents 3ae1764 + 4d4d09a commit 218c7a2

File tree

140 files changed

+1186
-958
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

140 files changed

+1186
-958
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
Typesafe variadic class parameters have been deprecated
2+
3+
This obscure feature allowed a limited form of implicit construction:
4+
5+
---
6+
void check(bool x, Exception e...)
7+
{
8+
if (!x)
9+
throw e;
10+
}
11+
12+
void main(string[] args)
13+
{
14+
check(args.length > 1, "missing argument");
15+
}
16+
---
17+
18+
However, few uses of this feature have been found, and one project was actually mistakenly using it instead of the more common Typesafe variadic array parameter.
19+
Considering D doesn't support implicit construction and already has a confusing amount of different variadic parameter forms, it was decided to remove this feature.
20+
21+
As a corrective action, either call the constructor in the callee:
22+
23+
---
24+
void check(string msg)
25+
{
26+
if (!x)
27+
throw new Exception(msg);
28+
}
29+
---
30+
31+
Or let the caller construct the class instance:
32+
33+
---
34+
void check(bool x, Exception e);
35+
36+
void main(string[] args)
37+
{
38+
check(args.length > 1, new Exception("missing argument"));
39+
}
40+
---

changelog/dmd.error-messages.dd

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,23 @@ app.d(8): Error: function `attributediagnostic_nothrow.gc1` is not `nothrow`
1818
app.d(2): and `object.Exception` being thrown but not caught makes it fail to infer `nothrow`
1919
)
2020

21+
Function literals are now referred to by their (truncated) function body, instead of the internal `__lambda` name.
22+
23+
---
24+
/*
25+
BEFORE:
26+
27+
../test/test_.d(3): Error: function literal `__lambda1()` is not callable using argument types `(int)`
28+
(() => 42)(1);
29+
^
30+
AFTER:
31+
32+
../test/test_.d(3): Error: function literal `() => 42` is not callable using argument types `(int)`
33+
(() => 42)(1);
34+
^
35+
*/
36+
---
37+
2138
Match levels are now mentioned on ambiguous overloads: [#20637](https://github.com/dlang/dmd/pull/20637)
2239

2340
Before:

compiler/src/dmd/backend/arm/cod1.d

Lines changed: 31 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,40 +1162,28 @@ void getlvalue(ref CodeBuilder cdb,ref code pcs,elem* e,regm_t keepmsk,RM rm = R
11621162
// fltregs
11631163

11641164
/*****************************
1165-
* Given a result in registers, test it for true or false.
1166-
* Will fail if TYfptr and the reg is ES!
1167-
* If saveflag is true, preserve the contents of the
1168-
* registers.
1165+
* Given a result in registers regm, test it for true or false.
1166+
* Params:
1167+
* cdb = generated code sink
1168+
* regm = result register(s) and mPSW
1169+
* tym = type of result
1170+
* saveflag = true means preserve the contents of the registers
11691171
*/
11701172
@trusted
11711173
void tstresult(ref CodeBuilder cdb, regm_t regm, tym_t tym, bool saveflag)
11721174
{
1173-
reg_t scrreg; // scratch register
1174-
regm_t scrregm;
1175-
1176-
//if (!(regm & (mBP | ALLREGS)))
1177-
//printf("tstresult(regm = %s, tym = x%x, saveflag = %d)\n",
1178-
//regm_str(regm),tym,saveflag);
1175+
//printf("tstresult(regm = %s, tym = x%x, saveflag = %d)\n",regm_str(regm),tym,saveflag);
11791176

11801177
tym = tybasic(tym);
11811178
reg_t reg = findreg(regm);
11821179
uint sz = _tysize[tym];
1183-
assert(regm & cgstate.allregs);
1184-
static if (0)
1185-
{
1186-
assert(regm & (XMMREGS | mBP | ALLREGS));
1187-
if (sz == 1)
1188-
{
1189-
assert(regm & BYTEREGS);
1190-
genregs(cdb, 0x84, reg, reg); // TEST regL,regL
1191-
if (I64 && reg >= 4)
1192-
code_orrex(cdb.last(), REX);
1193-
return;
1194-
}
1180+
assert(regm & (cgstate.allregs | INSTR.FLOATREGS));
1181+
1182+
static if (0)
11951183
if (regm & XMMREGS)
11961184
{
11971185
regm_t xregs = XMMREGS & ~regm;
1198-
const xreg = allocreg(cdb,xregs, TYdouble);
1186+
const xreg = allocreg(cdb,xregs,TYdouble);
11991187
opcode_t op = 0;
12001188
if (tym == TYdouble || tym == TYidouble || tym == TYcdouble)
12011189
op = 0x660000;
@@ -1211,104 +1199,16 @@ static if (0)
12111199
}
12121200
return;
12131201
}
1214-
}
1215-
if (sz <= REGSIZE)
1216-
{
1217-
if (tym == TYfloat)
1218-
{
1219-
if (saveflag)
1220-
{
1221-
scrregm = cgstate.allregs & ~regm; // possible scratch regs
1222-
scrreg = allocreg(cdb, scrregm, TYoffset); // allocate scratch reg
1223-
genmovreg(cdb, scrreg, reg); // MOV scrreg,msreg
1224-
reg = scrreg;
1225-
}
1226-
getregs(cdb, mask(reg));
1227-
cdb.gen2(0xD1, modregrmx(3, 4, reg)); // SHL reg,1
1228-
return;
1229-
}
1230-
}
1231-
1232-
gentstreg(cdb,reg,sz == 8); // CMP reg,#0
1233-
12341202

1235-
static if (0)
1236-
{
1237-
if (saveflag || tyfv(tym))
1203+
if (tyfloating(tym))
12381204
{
1239-
L1:
1240-
scrregm = ALLREGS & ~regm; // possible scratch regs
1241-
scrreg = allocreg(cdb, scrregm, TYoffset); // allocate scratch reg
1242-
if (I32 || sz == REGSIZE * 2)
1243-
{
1244-
assert(regm & mMSW && regm & mLSW);
1245-
1246-
reg = findregmsw(regm);
1247-
if (I32)
1248-
{
1249-
if (tyfv(tym))
1250-
genregs(cdb, MOVZXw, scrreg, reg); // MOVZX scrreg,msreg
1251-
else
1252-
{
1253-
genmovreg(cdb, scrreg, reg); // MOV scrreg,msreg
1254-
if (tym == TYdouble || tym == TYdouble_alias)
1255-
cdb.gen2(0xD1, modregrm(3, 4, scrreg)); // SHL scrreg,1
1256-
}
1257-
}
1258-
else
1259-
{
1260-
genmovreg(cdb, scrreg, reg); // MOV scrreg,msreg
1261-
if (tym == TYfloat)
1262-
cdb.gen2(0xD1, modregrm(3, 4, scrreg)); // SHL scrreg,1
1263-
}
1264-
reg = findreglsw(regm);
1265-
genorreg(cdb, scrreg, reg); // OR scrreg,lsreg
1266-
}
1267-
else if (sz == 8)
1268-
{
1269-
// !I32
1270-
genmovreg(cdb, scrreg, AX); // MOV scrreg,AX
1271-
if (tym == TYdouble || tym == TYdouble_alias)
1272-
cdb.gen2(0xD1 ,modregrm(3, 4, scrreg)); // SHL scrreg,1
1273-
genorreg(cdb, scrreg, BX); // OR scrreg,BX
1274-
genorreg(cdb, scrreg, CX); // OR scrreg,CX
1275-
genorreg(cdb, scrreg, DX); // OR scrreg,DX
1276-
}
1277-
else
1278-
assert(0);
1205+
const ftype = INSTR.szToFtype(sz);
1206+
cdb.gen1(INSTR.fcmp_float(ftype,0,reg)); // FCMP Vn,#0.0
12791207
}
12801208
else
1281-
{
1282-
if (I32 || sz == REGSIZE * 2)
1283-
{
1284-
// can't test ES:LSW for 0
1285-
assert(regm & mMSW & ALLREGS && regm & (mLSW | mBP));
1286-
1287-
reg = findregmsw(regm);
1288-
if (cgstate.regcon.mvar & mask(reg)) // if register variable
1289-
goto L1; // don't trash it
1290-
getregs(cdb, mask(reg)); // we're going to trash reg
1291-
if (tyfloating(tym) && sz == 2 * _tysize[TYint])
1292-
cdb.gen2(0xD1, modregrm(3 ,4, reg)); // SHL reg,1
1293-
genorreg(cdb, reg, findreglsw(regm)); // OR reg,reg+1
1294-
if (I64)
1295-
code_orrex(cdb.last(), REX_W);
1296-
}
1297-
else if (sz == 8)
1298-
{ assert(regm == DOUBLEREGS_16);
1299-
getregs(cdb,mAX); // allocate AX
1300-
if (tym == TYdouble || tym == TYdouble_alias)
1301-
cdb.gen2(0xD1, modregrm(3, 4, AX)); // SHL AX,1
1302-
genorreg(cdb, AX, BX); // OR AX,BX
1303-
genorreg(cdb, AX, CX); // OR AX,CX
1304-
genorreg(cdb, AX, DX); // OR AX,DX
1305-
}
1306-
else
1307-
assert(0);
1308-
}
1209+
gentstreg(cdb,reg,sz == 8); // CMP reg,#0
13091210
code_orflag(cdb.last(),CFpsw);
13101211
}
1311-
}
13121212

13131213

13141214
/******************************
@@ -2300,22 +2200,10 @@ static if (1)
23002200
cdrelconst(cgstate,cdb,e,outretregs);
23012201
return;
23022202
}
2303-
if (tyfloating(tym))
2304-
{
2305-
objmod.fltused();
2306-
if (config.fpxmmregs &&
2307-
(tym == TYcfloat || tym == TYcdouble) &&
2308-
(outretregs & (XMMREGS | mPSW))
2309-
)
2310-
{
2311-
cloadxmm(cdb, e, outretregs);
2312-
return;
2313-
}
2314-
}
23152203

23162204
if (outretregs == mPSW)
23172205
{
2318-
regm_t retregs = cgstate.allregs;
2206+
regm_t retregs = tyfloating(tym) ? INSTR.FLOATREGS : cgstate.allregs;
23192207
loaddata(cdb, e, retregs);
23202208
fixresult(cdb, e, retregs, outretregs);
23212209
return;
@@ -2326,8 +2214,6 @@ static if (1)
23262214
cs.Iflags = 0;
23272215
flags = outretregs & mPSW; /* save original */
23282216
forregs = outretregs & (cgstate.allregs | INSTR.FLOATREGS); // XMMREGS ?
2329-
//if (outretregs & mSTACK)
2330-
//forregs |= DOUBLEREGS;
23312217
if (e.Eoper == OPconst)
23322218
{
23332219
if (tyvector(tym) && forregs & XMMREGS)
@@ -2397,7 +2283,7 @@ static if (1)
23972283
const reg_t preg = e.Voffset ? e.Vsym.Spreg2 : e.Vsym.Spreg;
23982284
const regm_t pregm = mask(preg);
23992285

2400-
if (!(sz <= 2 && pregm & XMMREGS)) // no SIMD instructions to load 1 or 2 byte quantities
2286+
//if (!(sz <= 2 && pregm & XMMREGS)) // no SIMD instructions to load 1 or 2 byte quantities
24012287
{
24022288
if (debugr)
24032289
printf("%s.%d is fastpar and using register %s\n",
@@ -2458,7 +2344,7 @@ static if (1)
24582344
}
24592345
}
24602346
}
2461-
else if (forregs & XMMREGS)
2347+
else if (0 && forregs & XMMREGS)
24622348
{
24632349
// Can't load from registers directly to XMM regs
24642350
//e.Vsym.Sflags &= ~GTregcand;
@@ -2477,10 +2363,18 @@ static if (1)
24772363
}
24782364
else if (sz <= REGSIZE)
24792365
{
2480-
// LDR reg,[sp,#offset]
2481-
// https://www.scs.stanford.edu/~zyedidia/arm64/ldr_imm_gen.html
2482-
opcode_t opmv = PSOP.ldr | (29 << 5);
2483-
loadea(cdb, e, cs, opmv, reg, 0, 0, 0, RM.load);
2366+
if (tyfloating(tym))
2367+
{
2368+
loadea(cdb,e,cs,0,reg,0,0,0,RM.load);
2369+
outretregs = mask(reg);
2370+
}
2371+
else
2372+
{
2373+
// LDR reg,[sp,#offset]
2374+
// https://www.scs.stanford.edu/~zyedidia/arm64/ldr_imm_gen.html
2375+
opcode_t opmv = PSOP.ldr | (29 << 5);
2376+
loadea(cdb, e, cs, opmv, reg, 0, 0, 0, RM.load);
2377+
}
24842378
}
24852379
else if (sz <= 2 * REGSIZE)
24862380
{
@@ -2515,6 +2409,7 @@ static if (1)
25152409
assert(0);
25162410
// Flags may already be set
25172411
outretregs &= flags | ~mPSW;
2412+
//printf("outretregs: %llx\n", outretregs);
25182413
fixresult(cdb, e, forregs, outretregs);
25192414
return;
25202415
}

compiler/src/dmd/backend/arm/cod2.d

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,8 @@ void cddiv(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
374374
@trusted
375375
void cdnot(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
376376
{
377-
//printf("cdnot()\n");
377+
//printf("cdnot() pretregs = %s\n", regm_str(pretregs));
378+
//elem_print(e);
378379
reg_t reg;
379380
regm_t forflags;
380381
elem* e1 = e.E1;
@@ -391,33 +392,23 @@ void cdnot(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
391392

392393
if (tyfloating(e1.Ety))
393394
{
394-
code* cnop = gen1(null, INSTR.nop);
395-
code* ctrue = gen1(null, INSTR.nop);
396-
logexp(cdb,e.E1,(op == OPnot) ? false : true,FL.code,ctrue);
397-
forflags = pretregs & mPSW;
398-
if (I64 && sz == 8)
399-
forflags |= 64;
400-
assert(tysize(e.Ety) <= REGSIZE); // result better be int
401-
CodeBuilder cdbfalse;
402-
cdbfalse.ctor();
403-
reg = allocreg(cdbfalse,pretregs,e.Ety); // allocate reg for result
404-
code* cfalse = cdbfalse.finish();
405-
CodeBuilder cdbtrue;
406-
cdbtrue.ctor();
407-
cdbtrue.append(ctrue);
408-
for (code* c1 = cfalse; c1; c1 = code_next(c1))
409-
cdbtrue.gen(c1); // duplicate reg save code
410-
CodeBuilder cdbfalse2;
411-
cdbfalse2.ctor();
412-
movregconst(cdbfalse2,reg,0,forflags); // mov 0 into reg
413-
cgstate.regcon.immed.mval &= ~mask(reg); // mark reg as unavail
414-
movregconst(cdbtrue,reg,1,forflags); // mov 1 into reg
415-
cgstate.regcon.immed.mval &= ~mask(reg); // mark reg as unavail
416-
genBranch(cdbfalse2,COND.al,FL.code,cast(block*) cnop); // JMP cnop
417-
cdb.append(cfalse);
418-
cdb.append(cdbfalse2);
419-
cdb.append(cdbtrue);
420-
cdb.append(cnop);
395+
regm_t retregs1 = INSTR.FLOATREGS;
396+
codelem(cgstate,cdb,e.E1,retregs1,1);
397+
const V1 = findreg(retregs1);
398+
const ftype = INSTR.szToFtype(sz);
399+
cdb.gen1(INSTR.fcmpe_float(ftype,0,V1)); // FCMPE V1,#0.0
400+
401+
regm_t retregs = pretregs & cgstate.allregs;
402+
if (!retregs)
403+
retregs = cgstate.allregs;
404+
const Rd = findreg(retregs);
405+
const cond = op == OPnot ? COND.ne : COND.eq;
406+
cdb.gen1(INSTR.cset(sz == 8,cond,Rd)); // CSET Rd,eq
407+
uint N,immr,imms;
408+
assert(encodeNImmrImms(0xFF,N,immr,imms));
409+
cdb.gen1(INSTR.log_imm(0,0,0,immr,imms,Rd,Rd)); // AND Rd,Rd,#0xFF
410+
pretregs &= ~mPSW; // flags already set
411+
fixresult(cdb,e,retregs,pretregs);
421412
}
422413
else
423414
{

0 commit comments

Comments
 (0)