mirror of
https://github.com/dlang/dmd.git
synced 2025-04-27 21:51:03 +03:00
Merge remote-tracking branch 'upstream/stable' into merge_stable
This commit is contained in:
commit
543d7524db
20 changed files with 78 additions and 130 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
v2.084.0-rc.1
|
v2.084.0
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
Aliases can be created directly from a `__trait`.
|
|
||||||
|
|
||||||
Aliases can be created directly from the traits that return symbol(s) or tuples.
|
|
||||||
This includes `getMember`, `allMembers`, `derivedMembers`, `parent`, `getOverloads`,
|
|
||||||
`getVirtualFunctions`, `getVirtualMethods`, `getUnitTests`, `getAttributes` and finally `getAliasThis`.
|
|
||||||
Previously an `AliasSeq` was necessary in order to alias their return.
|
|
||||||
Now the grammar allows to write shorter declarations:
|
|
||||||
|
|
||||||
---
|
|
||||||
struct Foo
|
|
||||||
{
|
|
||||||
static int a;
|
|
||||||
}
|
|
||||||
|
|
||||||
alias oldWay = AliasSeq!(__traits(getMember, Foo, "a"))[0];
|
|
||||||
alias newWay = __traits(getMember, Foo, "a");
|
|
||||||
---
|
|
||||||
|
|
||||||
To permit this it was more interesting to include `__trait` in the basic types
|
|
||||||
rather than just changing the alias syntax. So additionally, wherever a type appears
|
|
||||||
a `__trait` can be used, for example in a variable declaration:
|
|
||||||
|
|
||||||
---
|
|
||||||
struct Foo { static struct Bar {} }
|
|
||||||
const(__traits(getMember, Foo, "Bar")) fooBar;
|
|
||||||
static assert(is(typeof(fooBar) == const(Foo.Bar)));
|
|
||||||
---
|
|
|
@ -1,18 +0,0 @@
|
||||||
Added -check switch to turn on and off each category of runtime checks.
|
|
||||||
|
|
||||||
Option("check=[assert|bounds|in|invariant|out|switch][=[on|off]]",
|
|
||||||
`Overrides default, -boundscheck, -release and -unittest options to enable or disable specific checks.
|
|
||||||
$(UL
|
|
||||||
$(LI $(B assert): assertion checking)
|
|
||||||
$(LI $(B bounds): array bounds)
|
|
||||||
$(LI $(B in): in contracts)
|
|
||||||
$(LI $(B invariant): class/struct invariants)
|
|
||||||
$(LI $(B out): out contracts)
|
|
||||||
$(LI $(B switch): switch default)
|
|
||||||
)
|
|
||||||
$(UL
|
|
||||||
$(LI $(B on) or not specified: specified check is enabled.)
|
|
||||||
$(LI $(B off): specified check is disabled.)
|
|
||||||
)`
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
Add `-checkaction=D|C|halt` compiler switch.
|
|
||||||
|
|
||||||
It covers action taken when an assert fails, a bounds check fails,
|
|
||||||
or a final switch error happens. D means the usual D behavior of
|
|
||||||
throwing an `Error`, C means call the C runtime library assert failure
|
|
||||||
function, and halt means halt the program execution.
|
|
||||||
|
|
||||||
The halt is the main addition here, it enables very lightweight assert's.
|
|
|
@ -1,21 +0,0 @@
|
||||||
`-color` and `-color=on` will now always output colorized console output
|
|
||||||
|
|
||||||
Before this release `-color` wouldn't output colorized console output if
|
|
||||||
the terminal detection failed.
|
|
||||||
With this release, a new option `auto` is introduced for `-color=<value>`
|
|
||||||
which will continue to be the default:
|
|
||||||
|
|
||||||
$(UL
|
|
||||||
$(LI `auto`: enable colorized output if a tty is detected (default))
|
|
||||||
$(LI `on`: always use colored output.)
|
|
||||||
$(LI `off`: never use colored output.)
|
|
||||||
)
|
|
||||||
|
|
||||||
Hence, it is now possible to use `-color` (a shortcut for `-color=on`) to
|
|
||||||
force DMD to emit colorized console output.
|
|
||||||
For example, this will now use colorized console output:
|
|
||||||
|
|
||||||
$(CONSOLE
|
|
||||||
> echo $(DOLLAR)(echo "test" | dmd -color - 2>&1)
|
|
||||||
__stdin.d(2): $(RED Error): no identifier for declarator $(B test)
|
|
||||||
)
|
|
|
@ -1,3 +0,0 @@
|
||||||
The code generated by `mixin` statements can now be saved with -mixin
|
|
||||||
|
|
||||||
This is useful to debug errors in compilation and provides source for debuggers to show when requested.
|
|
|
@ -1,9 +0,0 @@
|
||||||
Deprecate invalid binary literals
|
|
||||||
|
|
||||||
Prior to this release, binary literals without any digits after the prefix `0b`
|
|
||||||
were considered valid. This has now been deprecated.
|
|
||||||
---
|
|
||||||
auto foo = 0b; // deprecated
|
|
||||||
auto bar = 0b_; // deprecated
|
|
||||||
auto baz = 0b0; // conforming equivalent
|
|
||||||
---
|
|
|
@ -1,4 +0,0 @@
|
||||||
Deprecated `extern(Pascal)` linkage
|
|
||||||
|
|
||||||
This linkage is completely unused, being an heritage from a few decades ago.
|
|
||||||
Additionally, it's only supported by DMD and cause mangling ambiguity.
|
|
|
@ -1,20 +0,0 @@
|
||||||
The deprecation phase for fully qualified names that bypassed private imports is finished
|
|
||||||
|
|
||||||
---
|
|
||||||
// a.d
|
|
||||||
import std.stdio;
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
// b.d
|
|
||||||
import a;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
std.stdio.writefln("foo"); // deprecation before patch, now errors
|
|
||||||
}
|
|
||||||
---
|
|
||||||
|
|
||||||
In order to compile the example successfully, `public` needs to be added
|
|
||||||
to the import located in `a.d` : `public import std.stdio;` or `import std.stdio;`
|
|
||||||
needs to be added to `b.d`.
|
|
|
@ -1,4 +0,0 @@
|
||||||
Templates are now mangled correctly on POSIX
|
|
||||||
|
|
||||||
Before this version, anything including `extern(C++)` templates
|
|
||||||
was not correctly mangled on OSX, Linux, and FreeBSD, leading to linker errors.
|
|
|
@ -1,5 +0,0 @@
|
||||||
Added `__c_wchar_t` as a correct mangling type for C's `wchar_t`
|
|
||||||
|
|
||||||
This allows code interfacing with C++ that uses `wchar_t` to link correctly.
|
|
||||||
It replaces `wchar` (Windows) and `dchar` (Posix) as the memory type for the
|
|
||||||
DRuntime alias `wchar_t`.
|
|
|
@ -443,7 +443,7 @@ void cdeq(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
postinc = e11.EV.E2.EV.Vint;
|
postinc = e11.EV.E2.EV.Vint;
|
||||||
if (e11.Eoper == OPpostdec)
|
if (e11.Eoper == OPpostdec)
|
||||||
postinc = -postinc;
|
postinc = -postinc;
|
||||||
getlvalue(cdb,&cs,e11,RMstore);
|
getlvalue(cdb,&cs,e1,RMstore);
|
||||||
freenode(e11.EV.E2);
|
freenode(e11.EV.E2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -710,10 +710,8 @@ void cdeq(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
||||||
postinc = e11.EV.E2.EV.Vint;
|
postinc = e11.EV.E2.EV.Vint;
|
||||||
if (e11.Eoper == OPpostdec)
|
if (e11.Eoper == OPpostdec)
|
||||||
postinc = -postinc;
|
postinc = -postinc;
|
||||||
getlvalue(cdb,&cs,e11,RMstore | retregs);
|
getlvalue(cdb,&cs,e1,RMstore | retregs);
|
||||||
freenode(e11.EV.E2);
|
freenode(e11.EV.E2);
|
||||||
if (I64 && sz < 8)
|
|
||||||
cs.Irex &= ~REX_W; // incorrectly set by getlvalue()
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -483,6 +483,8 @@ public:
|
||||||
bool naked; // true if naked
|
bool naked; // true if naked
|
||||||
bool generated; // true if function was generated by the compiler rather than
|
bool generated; // true if function was generated by the compiler rather than
|
||||||
// supplied by the user
|
// supplied by the user
|
||||||
|
unsigned char isCrtCtorDtor; // has attribute pragma(crt_constructor(1)/crt_destructor(2))
|
||||||
|
// not set before the glue layer
|
||||||
ILS inlineStatusStmt;
|
ILS inlineStatusStmt;
|
||||||
ILS inlineStatusExp;
|
ILS inlineStatusExp;
|
||||||
PINLINE inlining;
|
PINLINE inlining;
|
||||||
|
|
|
@ -231,6 +231,9 @@ extern (C++) class FuncDeclaration : Declaration
|
||||||
bool naked; /// true if naked
|
bool naked; /// true if naked
|
||||||
bool generated; /// true if function was generated by the compiler rather than
|
bool generated; /// true if function was generated by the compiler rather than
|
||||||
/// supplied by the user
|
/// supplied by the user
|
||||||
|
ubyte isCrtCtorDtor; /// has attribute pragma(crt_constructor(1)/crt_destructor(2))
|
||||||
|
/// not set before the glue layer
|
||||||
|
|
||||||
ILS inlineStatusStmt = ILS.uninitialized;
|
ILS inlineStatusStmt = ILS.uninitialized;
|
||||||
ILS inlineStatusExp = ILS.uninitialized;
|
ILS inlineStatusExp = ILS.uninitialized;
|
||||||
PINLINE inlining = PINLINE.default_;
|
PINLINE inlining = PINLINE.default_;
|
||||||
|
|
|
@ -762,7 +762,7 @@ void FuncDeclaration_toObjFile(FuncDeclaration fd, bool multiobj)
|
||||||
if (ud && !global.params.useUnitTests)
|
if (ud && !global.params.useUnitTests)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (multiobj && !fd.isStaticDtorDeclaration() && !fd.isStaticCtorDeclaration())
|
if (multiobj && !fd.isStaticDtorDeclaration() && !fd.isStaticCtorDeclaration() && !fd.isCrtCtorDtor)
|
||||||
{
|
{
|
||||||
obj_append(fd);
|
obj_append(fd);
|
||||||
return;
|
return;
|
||||||
|
@ -1244,6 +1244,11 @@ void FuncDeclaration_toObjFile(FuncDeclaration fd, bool multiobj)
|
||||||
if (fd.isExport())
|
if (fd.isExport())
|
||||||
objmod.export_symbol(s, cast(uint)Para.offset);
|
objmod.export_symbol(s, cast(uint)Para.offset);
|
||||||
|
|
||||||
|
if (fd.isCrtCtorDtor & 1)
|
||||||
|
objmod.setModuleCtorDtor(s, true);
|
||||||
|
if (fd.isCrtCtorDtor & 2)
|
||||||
|
objmod.setModuleCtorDtor(s, false);
|
||||||
|
|
||||||
foreach (sd; *irs.deferToObj)
|
foreach (sd; *irs.deferToObj)
|
||||||
{
|
{
|
||||||
toObjFile(sd, false);
|
toObjFile(sd, false);
|
||||||
|
|
|
@ -772,10 +772,7 @@ void toObjFile(Dsymbol ds, bool multiobj)
|
||||||
|
|
||||||
obj_linkerdirective(directive);
|
obj_linkerdirective(directive);
|
||||||
}
|
}
|
||||||
|
else if (pd.ident == Id.crt_constructor || pd.ident == Id.crt_destructor)
|
||||||
visit(cast(AttribDeclaration)pd);
|
|
||||||
|
|
||||||
if (pd.ident == Id.crt_constructor || pd.ident == Id.crt_destructor)
|
|
||||||
{
|
{
|
||||||
immutable isCtor = pd.ident == Id.crt_constructor;
|
immutable isCtor = pd.ident == Id.crt_constructor;
|
||||||
|
|
||||||
|
@ -794,7 +791,7 @@ void toObjFile(Dsymbol ds, bool multiobj)
|
||||||
}
|
}
|
||||||
else if (auto f = s.isFuncDeclaration())
|
else if (auto f = s.isFuncDeclaration())
|
||||||
{
|
{
|
||||||
objmod.setModuleCtorDtor(s.csym, isCtor);
|
f.isCrtCtorDtor |= isCtor ? 1 : 2;
|
||||||
if (f.linkage != LINK.c)
|
if (f.linkage != LINK.c)
|
||||||
f.error("must be `extern(C)` for `pragma(%s)`", isCtor ? "crt_constructor".ptr : "crt_destructor".ptr);
|
f.error("must be `extern(C)` for `pragma(%s)`", isCtor ? "crt_constructor".ptr : "crt_destructor".ptr);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -807,6 +804,8 @@ void toObjFile(Dsymbol ds, bool multiobj)
|
||||||
if (recurse(pd, isCtor) > 1)
|
if (recurse(pd, isCtor) > 1)
|
||||||
pd.error("can only apply to a single declaration");
|
pd.error("can only apply to a single declaration");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
visit(cast(AttribDeclaration)pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(TemplateInstance ti)
|
override void visit(TemplateInstance ti)
|
||||||
|
|
8
test/runnable/extra-files/lib18456.d
Normal file
8
test/runnable/extra-files/lib18456.d
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
__gshared int initVar;
|
||||||
|
|
||||||
|
pragma(crt_constructor)
|
||||||
|
extern(C) void mir_cpuid_crt_init()
|
||||||
|
{
|
||||||
|
initVar = 42;
|
||||||
|
}
|
6
test/runnable/extra-files/test18456.d
Normal file
6
test/runnable/extra-files/test18456.d
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import lib18456;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
assert(initVar == 42);
|
||||||
|
}
|
|
@ -1838,6 +1838,44 @@ void test18730() // https://issues.dlang.org/show_bug.cgi?id=18730
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void test19497() // https://issues.dlang.org/show_bug.cgi?id=19497
|
||||||
|
{
|
||||||
|
{
|
||||||
|
ubyte[1024] data;
|
||||||
|
ushort* ushortPtr = cast(ushort*) data.ptr;
|
||||||
|
*ushortPtr++ = 0xfe00;
|
||||||
|
printf("ushortPtr(%p)\n", ushortPtr);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
alias Seq(stuff ...) = stuff;
|
||||||
|
static foreach (T; Seq!(ubyte, ushort, uint, ulong, byte, short, int, long))
|
||||||
|
{{
|
||||||
|
T[2] data = 0x2A;
|
||||||
|
T* q = &data[0];
|
||||||
|
*q++ = cast(T) 0x1122334455667788;
|
||||||
|
if (*q != 0x2A) assert(false);
|
||||||
|
}}
|
||||||
|
|
||||||
|
{
|
||||||
|
static int toStringz(string s) { return s.length > 0 ? s[0] : 0; }
|
||||||
|
static void toAStringz(in string[] a, int* az)
|
||||||
|
{
|
||||||
|
foreach (string s; a)
|
||||||
|
{
|
||||||
|
*az++ = toStringz(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
string[1] sa = ["abc"];
|
||||||
|
int[2] tgt = 0x2a;
|
||||||
|
toAStringz(sa[], tgt.ptr);
|
||||||
|
if (tgt[0] != 'a') assert(false);
|
||||||
|
if (tgt[1] != 0x2a) assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
testgoto();
|
testgoto();
|
||||||
|
@ -1903,6 +1941,7 @@ int main()
|
||||||
test18315();
|
test18315();
|
||||||
test18461();
|
test18461();
|
||||||
test18730();
|
test18730();
|
||||||
|
test19497();
|
||||||
|
|
||||||
printf("Success\n");
|
printf("Success\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
7
test/runnable/test18456.sh
Normal file
7
test/runnable/test18456.sh
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
$DMD -m${MODEL} -I${EXTRA_FILES} -of${OUTPUT_BASE}${LIBEXT} -lib ${EXTRA_FILES}/lib18456.d
|
||||||
|
$DMD -m${MODEL} -I${EXTRA_FILES} -of${OUTPUT_BASE}${EXE} ${EXTRA_FILES}/test18456.d ${OUTPUT_BASE}${LIBEXT}
|
||||||
|
${OUTPUT_BASE}${EXE}
|
||||||
|
|
||||||
|
rm ${OUTPUT_BASE}{${LIBEXT},${EXE}}
|
Loading…
Add table
Add a link
Reference in a new issue