mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +03:00
commit
59e224a2da
16 changed files with 171 additions and 42 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
v2.105.1-beta.1
|
||||
v2.105.2
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1280,10 +1280,16 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
|
|||
//printf("CatExp::optimize(%d) %s\n", result, e.toChars());
|
||||
if (binOptimize(e, result))
|
||||
return;
|
||||
|
||||
if (e.type == Type.tstring)
|
||||
if (auto ce1 = e.e1.isCatExp())
|
||||
{
|
||||
// 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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
17
compiler/test/compilable/test24109.d
Normal file
17
compiler/test/compilable/test24109.d
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
compiler/test/compilable/test24118.d
Normal file
15
compiler/test/compilable/test24118.d
Normal 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] );
|
||||
}
|
||||
}
|
12
compiler/test/fail_compilation/test24110.d
Normal file
12
compiler/test/fail_compilation/test24110.d
Normal 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));
|
6
compiler/test/runnable/test24078.d
Normal file
6
compiler/test/runnable/test24078.d
Normal file
|
@ -0,0 +1,6 @@
|
|||
//https://issues.dlang.org/show_bug.cgi?id=24078
|
||||
|
||||
void main()
|
||||
{
|
||||
assert(["c"] ~ "a" ~ "b" == ["c", "a", "b"]);
|
||||
}
|
25
compiler/test/runnable/test24139.d
Normal file
25
compiler/test/runnable/test24139.d
Normal 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);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue