Skip to content

Commit f0d1d4f

Browse files
committed
Merge remote-tracking branch 'upstream/stable' into merge_stable
2 parents 623e9a3 + 7af5ba3 commit f0d1d4f

36 files changed

Lines changed: 480 additions & 97 deletions

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v2.112.0
1+
v2.112.1

compiler/src/dmd/common/charactertables.d

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,13 @@ bool c_isalnum(const int c)
185185
( c >= 'A' && c <= 'Z'));
186186
}
187187

188+
///
189+
bool isAlphaASCII(const dchar c)
190+
{
191+
return (( c >= 'a' && c <= 'z') ||
192+
( c >= 'A' && c <= 'Z'));
193+
}
194+
188195
extern(D) private:
189196

190197
// originally from dmd.root.utf

compiler/src/dmd/expressionsem.d

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6992,8 +6992,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
69926992

69936993
if (!global.params.useGC && sc.needsCodegen())
69946994
{
6995-
error(exp.loc, "expression `%s` allocates with the GC and cannot be used with switch `-%s`", exp.toErrMsg(), SwitchVariadic.ptr);
6996-
return setError();
6995+
if (sc.func)
6996+
{
6997+
sc.func.skipCodegen = true; // same net result as calling checkGC
6998+
goto LskipNewArrayLowering; // not checked in sc.needsCodegen() !?
6999+
}
69977000
}
69987001

69997002
if (!sc.needsCodegen())
@@ -8516,7 +8519,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
85168519
{
85178520
exp.type = tf.next;
85188521
auto casted_exp = exp.castTo(sc, t);
8519-
if (auto cex = casted_exp.isCastExp())
8522+
if (auto cex = lastComma(casted_exp).isCastExp())
85208523
{
85218524
lowerCastExp(cex, sc);
85228525
}
@@ -10933,7 +10936,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
1093310936
}
1093410937
}
1093510938

10936-
if (auto cex = ex.isCastExp())
10939+
if (auto cex = lastComma(ex).isCastExp())
1093710940
{
1093810941
lowerCastExp(cex, sc);
1093910942
}
@@ -15079,12 +15082,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
1507915082
return;
1508015083
}
1508115084

15082-
// When array comparison is not lowered to `__equals`, `memcmp` is used, but
15083-
// GC checks occur before the expression is lowered to `memcmp` in e2ir.d.
15084-
// Thus, we will consider the literal arrays as on-stack arrays to avoid issues
15085-
// during GC checks.
15085+
// Remaining array comparisons are trivially memcmp-able.
15086+
// Allocate array-literal operands on the stack, since they don't
15087+
// escape during the comparison; enabling @nogc for these.
1508615088
if (isArrayComparison)
1508715089
{
15090+
exp.e1 = exp.e1.optimize(WANTvalue);
15091+
exp.e2 = exp.e2.optimize(WANTvalue);
15092+
1508815093
if (auto ale1 = exp.e1.isArrayLiteralExp())
1508915094
{
1509015095
ale1.onstack = true;
@@ -19745,12 +19750,12 @@ private Expression buildAAIndexRValueX(Type t, Expression eaa, Expression ekey,
1974519750
auto call = new CallExp(loc, func, arguments);
1974619751
e0 = Expression.combine(e0, call);
1974719752

19748-
if (arrayBoundsCheck(sc.func))
19753+
if (sc.func && arrayBoundsCheck(sc.func))
1974919754
{
1975019755
// __aaget = _d_aaGetRvalueX(aa, key), __aaget ? __aaget : onRangeError(__FILE__, __LINE__)
1975119756
auto ei = new ExpInitializer(loc, e0);
19752-
auto vartmp = Identifier.generateId("__aaget");
19753-
auto vardecl = new VarDeclaration(loc, null, vartmp, ei, STC.exptemp);
19757+
auto id = Identifier.generateId("__aaget");
19758+
auto vardecl = new VarDeclaration(loc, null, id, ei, STC.exptemp);
1975419759
auto declexp = new DeclarationExp(loc, vardecl);
1975519760

1975619761
//Expression idrange = new IdentifierExp(loc, Identifier.idPool("_d_arraybounds"));
@@ -19760,9 +19765,9 @@ private Expression buildAAIndexRValueX(Type t, Expression eaa, Expression ekey,
1976019765
auto locargs = new Expressions(new FileInitExp(loc, EXP.file), new LineInitExp(loc));
1976119766
auto ex = new CallExp(loc, idrange, locargs);
1976219767

19763-
auto idvar1 = new IdentifierExp(loc, vartmp);
19764-
auto idvar2 = new IdentifierExp(loc, vartmp);
19765-
auto cond = new CondExp(loc, idvar1, idvar2, ex);
19768+
auto ve1 = new VarExp(loc, vardecl);
19769+
auto ve2 = new VarExp(loc, vardecl);
19770+
auto cond = new CondExp(loc, ve1, ve2, ex);
1976619771
auto comma = new CommaExp(loc, declexp, cond);
1976719772
return comma;
1976819773
}
@@ -19795,6 +19800,26 @@ Expression revertIndexAssignToRvalues(IndexExp ie, Scope* sc)
1979519800
return lowerAAIndexRead(ie, sc);
1979619801
}
1979719802

19803+
// Ditto, but traverses DotVarExp from `alias this` rewrites.
19804+
private Expression revertModifiableAAIndexReads(Expression e, Scope* sc)
19805+
{
19806+
// Recurse through dot-accesses (alias this produces DotVarExp on an inner IndexExp)
19807+
if (auto dve = e.isDotVarExp())
19808+
{
19809+
dve.e1 = revertModifiableAAIndexReads(dve.e1, sc);
19810+
return e;
19811+
}
19812+
if (auto ie = e.isIndexExp())
19813+
{
19814+
// Recurse first to handle deeper nesting
19815+
ie.e1 = revertModifiableAAIndexReads(ie.e1, sc);
19816+
// Lower a modifiable AA IndexExp to an rvalue read
19817+
if (ie.modifiable && ie.e1.type.isTypeAArray())
19818+
return lowerAAIndexRead(ie, sc);
19819+
}
19820+
return e;
19821+
}
19822+
1979819823
// helper for rewriteAAIndexAssign
1979919824
private Expression implicitConvertToStruct(Expression ev, StructDeclaration sd, Scope* sc)
1980019825
{
@@ -19845,6 +19870,7 @@ private Expression rewriteAAIndexAssign(BinExp exp, Scope* sc, ref Type[2] alias
1984519870
// find the AA of multi dimensional access
1984619871
for (auto ieaa = ie.e1.isIndexExp(); ieaa && ieaa.e1.type.isTypeAArray(); ieaa = ieaa.e1.isIndexExp())
1984719872
eaa = ieaa.e1;
19873+
eaa = revertModifiableAAIndexReads(eaa, sc);
1984819874
eaa = extractSideEffect(sc, "__aatmp", e0, eaa);
1984919875
// collect all keys of multi dimensional access
1985019876
Expressions ekeys;
@@ -19883,7 +19909,7 @@ private Expression rewriteAAIndexAssign(BinExp exp, Scope* sc, ref Type[2] alias
1988319909
auto tiargs = new Objects(taa.index, taa.next);
1988419910
func = new DotTemplateInstanceExp(loc, func, hook, tiargs);
1988519911

19886-
auto arguments = new Expressions(eaa, ekeys[i-1], new IdentifierExp(loc, idfound));
19912+
auto arguments = new Expressions(eaa, ekeys[i-1], new VarExp(loc, varfound));
1988719913
eaa = new CallExp(loc, func, arguments);
1988819914
if (i > 1)
1988919915
{
@@ -19940,7 +19966,7 @@ private Expression rewriteAAIndexAssign(BinExp exp, Scope* sc, ref Type[2] alias
1994019966
ex = new CastExp(ex.loc, ex, Type.tvoid);
1994119967
ey = new CastExp(ey.loc, ey, Type.tvoid);
1994219968
}
19943-
Expression condfound = new IdentifierExp(loc, idfound);
19969+
Expression condfound = new VarExp(loc, varfound);
1994419970
ex = new CondExp(loc, condfound, ex, ey);
1994519971
ex = Expression.combine(e0, ex);
1994619972
ex.isCommaExp().originalExp = exp;

compiler/src/dmd/frontend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7979,6 +7979,8 @@ extern bool c_isxdigit(const int32_t c);
79797979

79807980
extern bool c_isalnum(const int32_t c);
79817981

7982+
extern bool isAlphaASCII(const char32_t c);
7983+
79827984
extern void error(Loc loc, const char* format, ...);
79837985

79847986
extern void error(const char* filename, uint32_t linnum, uint32_t charnum, const char* format, ...);

compiler/src/dmd/glue/toobj.d

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,17 +1348,13 @@ private void ClassInfoToDt(ref DtBuilder dtb, ClassDeclaration cd, Symbol* sinit
13481348
Louter:
13491349
for (ClassDeclaration pc = cd; pc; pc = pc.baseClass)
13501350
{
1351-
if (pc.members)
1351+
foreach (vd; pc.fields)
13521352
{
1353-
for (size_t i = 0; i < pc.members.length; i++)
1353+
//printf("vd = %s %s\n", vd.kind(), vd.toChars());
1354+
if (vd.hasPointers())
13541355
{
1355-
Dsymbol sm = (*pc.members)[i];
1356-
//printf("sm = %s %s\n", sm.kind(), sm.toChars());
1357-
if (sm.hasPointers())
1358-
{
1359-
flags &= ~ClassFlags.noPointers; // not no-how, not no-way
1360-
break Louter;
1361-
}
1356+
flags &= ~ClassFlags.noPointers; // not no-how, not no-way
1357+
break Louter;
13621358
}
13631359
}
13641360
}

compiler/src/dmd/initsem.d

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1468,6 +1468,22 @@ Expression initializerToExpression(Initializer init, Type itype = null, const bo
14681468
}
14691469
}
14701470

1471+
// enforce the element type only if the dimensions match, otherwise the value
1472+
// might be used as an initializer for the whole array at another dimension
1473+
Type isTypeArray(Type tn)
1474+
{
1475+
auto ty = tn ? tn.ty : Tnone;
1476+
return ty == Tarray || ty == Tsarray || ty == Taarray || ty == Tvector ? tn : null;
1477+
}
1478+
Type tnext = isTypeArray(itype);
1479+
auto initn = init;
1480+
while (tnext && initn)
1481+
{
1482+
tnext = isTypeArray(tnext.nextOf());
1483+
initn = initn.value.length ? initn.value[0].isArrayInitializer() : null;
1484+
}
1485+
Type telem = itype && !tnext && !initn ? itype.nextOf() : null;
1486+
14711487
auto elements = new Expressions(edim);
14721488
elements.zero();
14731489
size_t j = 0;
@@ -1478,7 +1494,7 @@ Expression initializerToExpression(Initializer init, Type itype = null, const bo
14781494
assert(j < edim);
14791495
if (Initializer iz = init.value[i])
14801496
{
1481-
if (Expression ex = iz.initializerToExpression(null, isCfile))
1497+
if (Expression ex = iz.initializerToExpression(telem, isCfile))
14821498
{
14831499
(*elements)[j] = ex;
14841500
++j;

compiler/src/dmd/lexer.d

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,11 @@ struct CompileEnv
6262
*/
6363
class Lexer
6464
{
65-
private __gshared OutBuffer stringbuffer;
65+
private __gshared
66+
{
67+
OutBuffer stringbuffer;
68+
OutBuffer stringbuffersecondary; // functions that use stringbuffer can call scan that needs this.
69+
}
6670

6771
BaseLoc* baseLoc; // Used to generate `scanloc`, which is just an index into this data structure
6872
Loc scanloc; // for error messages
@@ -1431,7 +1435,7 @@ class Lexer
14311435
p++;
14321436
break;
14331437
default:
1434-
if (isalpha(*p) || (p != idstart && isdigit(*p)))
1438+
if (isAlphaASCII(*p) || (p != idstart && isdigit(*p)))
14351439
continue;
14361440
error(loc, "unterminated named entity &%.*s;", cast(int)(p - idstart + 1), idstart);
14371441
c = '?';
@@ -1766,7 +1770,7 @@ class Lexer
17661770
uint blankrol = 0;
17671771
uint startline = 0;
17681772
p++;
1769-
stringbuffer.setsize(0);
1773+
stringbuffersecondary.setsize(0);
17701774
while (1)
17711775
{
17721776
const s = p;
@@ -1785,7 +1789,7 @@ class Lexer
17851789
}
17861790
if (hereid)
17871791
{
1788-
stringbuffer.writeUTF8(c);
1792+
stringbuffersecondary.writeUTF8(c);
17891793
continue;
17901794
}
17911795
break;
@@ -1825,7 +1829,7 @@ class Lexer
18251829
delimright = ']';
18261830
else if (c == '<')
18271831
delimright = '>';
1828-
else if (isalpha(c) || c == '_' || (c >= 0x80 && charLookup.isStart(c)))
1832+
else if (isAlphaASCII(c) || c == '_' || (c >= 0x80 && charLookup.isStart(c)))
18291833
{
18301834
// Start of identifier; must be a heredoc
18311835
Token tok;
@@ -1875,7 +1879,7 @@ class Lexer
18751879
goto Ldone;
18761880

18771881
// we're looking for a new identifier token
1878-
if (startline && (isalpha(c) || c == '_' || (c >= 0x80 && charLookup.isStart(c))) && hereid)
1882+
if (startline && (isAlphaASCII(c) || c == '_' || (c >= 0x80 && charLookup.isStart(c))) && hereid)
18791883
{
18801884
Token tok;
18811885
auto psave = p;
@@ -1890,7 +1894,7 @@ class Lexer
18901894
}
18911895
p = psave;
18921896
}
1893-
stringbuffer.writeUTF8(c);
1897+
stringbuffersecondary.writeUTF8(c);
18941898
startline = 0;
18951899
}
18961900
}
@@ -1903,7 +1907,7 @@ class Lexer
19031907
error("delimited string must end in `\"`");
19041908
else
19051909
error(token.loc, "delimited string must end in `%c\"`", delimright);
1906-
result.setString(stringbuffer);
1910+
result.setString(stringbuffersecondary);
19071911
stringPostfix(result);
19081912
}
19091913

@@ -2404,7 +2408,7 @@ class Lexer
24042408
case '.':
24052409
if (p[1] == '.')
24062410
goto Ldone; // if ".."
2407-
if (isalpha(p[1]) || p[1] == '_' || p[1] & 0x80)
2411+
if (isAlphaASCII(p[1]) || p[1] == '_' || p[1] & 0x80)
24082412
{
24092413
if (Ccompile && (p[1] == 'f' || p[1] == 'F' || p[1] == 'l' || p[1] == 'L'))
24102414
goto Lreal; // if `0.f` or `0.L`
@@ -2477,7 +2481,7 @@ class Lexer
24772481
case '.':
24782482
if (p[1] == '.')
24792483
goto Ldone; // if ".."
2480-
if (base <= 10 && n > 0 && (isalpha(p[1]) || p[1] == '_' || p[1] & 0x80))
2484+
if (base <= 10 && n > 0 && (isAlphaASCII(p[1]) || p[1] == '_' || p[1] & 0x80))
24812485
{
24822486
if (Ccompile && base == 10 &&
24832487
(p[1] == 'e' || p[1] == 'E' || p[1] == 'f' || p[1] == 'F' || p[1] == 'l' || p[1] == 'L'))

compiler/src/dmd/link.d

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -962,9 +962,13 @@ public int runPreprocessor(Loc loc, const(char)[] cpp, const(char)[] filename, c
962962
version (Windows)
963963
{
964964
// generate unique temporary file name for preprocessed output
965-
const(char)* tmpname = tmpnam(null);
966-
assert(tmpname);
967-
const(char)[] ifilename = tmpname[0 .. strlen(tmpname) + 1];
965+
char[MAX_PATH] tempDir = void;
966+
char[MAX_PATH] tempFile = void;
967+
if (GetTempPathA(MAX_PATH, tempDir.ptr) == 0)
968+
return STATUS_FAILED;
969+
if (GetTempFileNameA(tempDir.ptr, "dmd", 0, tempFile.ptr) == 0)
970+
return STATUS_FAILED;
971+
const(char)[] ifilename = tempFile[0 .. strlen(tempFile.ptr) + 1];
968972
ifilename = xarraydup(ifilename);
969973
const(char)[] output = ifilename;
970974

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module immports.test22480b;
2+
3+
auto parseAA()
4+
{
5+
bool[string] aa;
6+
aa["key"] = true;
7+
assert("key" in aa);
8+
assert(aa["key"]);
9+
assert(aa.length == 1);
10+
assert(aa == aa);
11+
aa.rehash();
12+
return true;
13+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import imports.test22480b;
2+
3+
@nogc nothrow:
4+
enum a = parseAA();
5+
6+
extern(C) int main()
7+
{
8+
return 0;
9+
}

0 commit comments

Comments
 (0)