Merge pull request #15609 from ibuclaw/merge_stable

merge stable
This commit is contained in:
Iain Buclaw 2023-09-16 09:31:00 +02:00 committed by GitHub
commit 59e224a2da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 171 additions and 42 deletions

View file

@ -1 +1 @@
v2.105.1-beta.1
v2.105.2

View file

@ -1128,7 +1128,7 @@ private DtorDeclaration buildExternDDtor(AggregateDeclaration ad, Scope* sc)
return null;
// Generate shim only when ABI incompatible on target platform
if (ad.classKind != ClassKind.cpp || !target.cpp.wrapDtorInExternD)
if (dtor._linkage != LINK.cpp || !target.cpp.wrapDtorInExternD)
return dtor;
// generate member function that adjusts calling convention

View file

@ -1197,6 +1197,11 @@ private bool haveSameThis(FuncDeclaration outerFunc, FuncDeclaration calledFunc)
if (thisAd == requiredAd)
return true;
// if outerfunc is the member of a nested aggregate, then let
// getRightThis take care of this.
if (thisAd.isNested())
return true;
// outerfunc is the member of a base class that contains calledFunc,
// then we consider that they have the same this.
auto cd = requiredAd.isClassDeclaration();
@ -1206,11 +1211,6 @@ private bool haveSameThis(FuncDeclaration outerFunc, FuncDeclaration calledFunc)
if (cd.isBaseOf2(thisAd.isClassDeclaration()))
return true;
// if outerfunc is the member of a nested aggregate, then let
// getRightThis take care of this.
if (thisAd.isNested())
return true;
return false;
}
@ -11042,7 +11042,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
(exp.e2.isStringExp() && (exp.e1.isIntegerExp() || exp.e1.isStringExp())))
return exp;
Identifier hook = global.params.tracegc ? Id._d_arraycatnTXTrace : Id._d_arraycatnTX;
bool useTraceGCHook = global.params.tracegc && sc.needsCodegen();
Identifier hook = useTraceGCHook ? Id._d_arraycatnTXTrace : Id._d_arraycatnTX;
if (!verifyHookExist(exp.loc, *sc, hook, "concatenating arrays"))
{
setError();
@ -11071,7 +11073,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
auto arguments = new Expressions();
if (global.params.tracegc)
if (useTraceGCHook)
{
auto funcname = (sc.callsc && sc.callsc.func) ?
sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
@ -11098,7 +11100,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
/* `_d_arraycatnTX` canot be used with `-betterC`, but `CatExp`s may be
* used with `-betterC`, but only during CTFE.
*/
if (!global.params.useGC || !sc.needsCodegen())
if (!global.params.useGC)
return;
if (auto ce = exp.isCatExp())
@ -12097,8 +12099,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}
if (sc.needsCodegen() &&
(t1.ty == Tarray || t1.ty == Tsarray) &&
if ((t1.ty == Tarray || t1.ty == Tsarray) &&
(t2.ty == Tarray || t2.ty == Tsarray))
{
if (!verifyHookExist(exp.loc, *sc, Id.__cmp, "comparing arrays"))

View file

@ -379,8 +379,8 @@ struct Loc final
{
private:
uint32_t _linnum;
uint16_t _charnum;
uint16_t fileIndex;
uint32_t _charnum;
uint32_t fileIndex;
public:
static bool showColumns;
static MessageStyle messageStyle;
@ -7076,9 +7076,9 @@ struct UnionExp final
private:
union __AnonStruct__u
{
char exp[25LLU];
char exp[29LLU];
char integerexp[40LLU];
char errorexp[25LLU];
char errorexp[29LLU];
char realexp[48LLU];
char complexexp[64LLU];
char symoffexp[64LLU];
@ -7087,7 +7087,7 @@ private:
char assocarrayliteralexp[56LLU];
char structliteralexp[76LLU];
char compoundliteralexp[40LLU];
char nullexp[25LLU];
char nullexp[29LLU];
char dotvarexp[49LLU];
char addrexp[40LLU];
char indexexp[74LLU];

View file

@ -367,8 +367,8 @@ struct Loc
{
private:
unsigned _linnum;
unsigned short _charnum;
unsigned short fileIndex;
unsigned _charnum;
unsigned fileIndex;
public:
static void set(bool showColumns, MessageStyle messageStyle);

View file

@ -38,8 +38,8 @@ debug info etc.
struct Loc
{
private uint _linnum;
private ushort _charnum;
private ushort fileIndex; // index into filenames[], starting from 1 (0 means no filename)
private uint _charnum;
private uint fileIndex; // index into filenames[], starting from 1 (0 means no filename)
version (LocOffset)
uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0
@ -67,7 +67,7 @@ nothrow:
extern (D) this(const(char)* filename, uint linnum, uint charnum) @safe
{
this._linnum = linnum;
this._charnum = cast(ushort) charnum;
this._charnum = charnum;
this.filename = filename;
}
@ -80,7 +80,7 @@ nothrow:
/// ditto
extern (C++) uint charnum(uint num) @nogc @safe
{
return _charnum = cast(ushort) num;
return _charnum = num;
}
/// line number, starting from 1
@ -114,8 +114,16 @@ nothrow:
{
//printf("setting %s\n", name);
filenames.push(name);
fileIndex = cast(ushort)filenames.length;
assert(fileIndex); // no overflow
fileIndex = cast(uint)filenames.length;
if (!fileIndex)
{
import dmd.globals : global;
import dmd.errors : error, fatal;
global.gag = 0; // ensure error message gets printed
error(Loc.initial, "internal compiler error: file name index overflow!");
fatal();
}
}
else
fileIndex = 0;

View file

@ -1280,19 +1280,25 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
//printf("CatExp::optimize(%d) %s\n", result, e.toChars());
if (binOptimize(e, result))
return;
if (auto ce1 = e.e1.isCatExp())
{
// https://issues.dlang.org/show_bug.cgi?id=12798
// optimize ((expr ~ str1) ~ str2)
scope CatExp cex = new CatExp(e.loc, ce1.e2, e.e2);
cex.type = e.type;
Expression ex = Expression_optimize(cex, result, false);
if (ex != cex)
if (e.type == Type.tstring)
if (auto ce1 = e.e1.isCatExp())
{
e.e1 = ce1.e1;
e.e2 = ex;
// https://issues.dlang.org/show_bug.cgi?id=12798
// optimize ((expr ~ str1) ~ str2)
// https://issues.dlang.org/show_bug.cgi?id=24078
// This optimization is only valid if `expr` is a string.
// Otherwise it leads to:
// `["c"] ~ "a" ~ "b"` becoming `["c"] ~ "ab"`
scope CatExp cex = new CatExp(e.loc, ce1.e2, e.e2);
cex.type = e.type;
Expression ex = Expression_optimize(cex, result, false);
if (ex != cex)
{
e.e1 = ce1.e1;
e.e2 = ex;
}
}
}
// optimize "str"[] -> "str"
if (auto se1 = e.e1.isSliceExp())
{

View file

@ -7596,7 +7596,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
continue;
// Valid tokens that follow a declaration
// Valid tokens that follow the start of a declaration
case TOK.rightParenthesis:
case TOK.rightBracket:
case TOK.assign:
@ -7615,6 +7615,23 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
return false;
// To recognize the shortened function declaration syntax
case TOK.goesTo:
/*
1. https://issues.dlang.org/show_bug.cgi?id=24088
2. We need to make sure the would-be
declarator has an identifier otherwise function literals
are handled incorrectly. Some special treatment is required
here, it turns out that a lot of code in the compiler relies
on this mess (in the parser), i.e. having isDeclarator be more
precise the parsing of other things go kaboom, so we do it in a
separate case.
*/
if (*haveId)
goto case TOK.do_;
goto default;
case TOK.identifier:
if (t.ident == Id._body)
{

View file

@ -27,7 +27,12 @@ string test() => "hello"; // works at any scope
static assert(test() == "hello"); // works normally
static assert(is(typeof(&test) == string function())); // same normal type
struct S(T) {}
void func() {
int a;
int nested() => a; // and at nested scopes too
// Issue 24088 - https://issues.dlang.org/show_bug.cgi?id=24088
S!int f() => S!int();
}

View file

@ -0,0 +1,17 @@
// https://issues.dlang.org/show_bug.cgi?id=24109
struct Outer
{
void method1() {}
void method2()
{
class Inner
{
void innerMethod()
{
method1();
}
}
}
}

View file

@ -0,0 +1,15 @@
// https://issues.dlang.org/show_bug.cgi?id=24118
void map(alias fun, T)(T[] arr)
{
fun(arr);
}
void foo()
{
if( __ctfe )
{
["a", "b", "c"].map!( a => " " ~ a[0] );
}
}

View file

@ -0,0 +1,12 @@
// https://issues.dlang.org/show_bug.cgi?id=24110
/*
TEST_OUTPUT:
---
fail_compilation/test24110.d(12): Error: static assert: `__traits(compiles, __error)` is false
---
*/
struct S { int x; }
alias T = shared S;
static assert(__traits(compiles, (T[] a, T[] b) => a < b));

View file

@ -0,0 +1,6 @@
//https://issues.dlang.org/show_bug.cgi?id=24078
void main()
{
assert(["c"] ~ "a" ~ "b" == ["c", "a", "b"]);
}

View file

@ -0,0 +1,25 @@
// https://issues.dlang.org/show_bug.cgi?id=24139
struct S1
{
int x;
extern(C++) ~this() { assert(&this == s1); }
}
extern(C++) struct S2
{
int x;
~this() { assert(&this == s2); }
}
S1* s1;
S2* s2;
void main()
{
s1 = new S1;
s2 = new S2;
typeid(S1).destroy(s1);
typeid(S2).destroy(s2);
}

View file

@ -4129,7 +4129,18 @@ else version (CRuntime_UClibc)
///
pure float modff(float value, float* iptr);
///
extern(D) pure real modfl(real value, real *iptr) { return modf(cast(double) value, cast(double*) iptr); }
extern(D) pure real modfl(real value, real *iptr)
{
static if (double.sizeof == real.sizeof)
return modf(cast(double) value, cast(double*) iptr);
else
{
double i;
double r = modf(cast(double) value, &i);
*iptr = i;
return r;
}
}
///
double scalbn(double x, int n);

View file

@ -267,10 +267,16 @@ struct ModuleGroup
edge[nEdges++] = *impidx;
}
}
// trim space to what is needed.
edges[i] = nEdges > 0
? (cast(int*)realloc(edge, int.sizeof * nEdges))[0 .. nEdges]
: null;
if (nEdges > 0)
{
// trim space to what is needed
edges[i] = (cast(int*)realloc(edge, int.sizeof * nEdges))[0 .. nEdges];
}
else
{
edges[i] = null;
.free(edge);
}
}
}