mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
Merge remote-tracking branch 'upstream/stable' into merge_stable
This commit is contained in:
commit
53cd4b7c30
24 changed files with 431 additions and 109 deletions
19
.github/workflows/main.yml
vendored
19
.github/workflows/main.yml
vendored
|
@ -51,10 +51,12 @@ jobs:
|
|||
# macOS
|
||||
- job_name: macOS 13 x64, DMD (latest)
|
||||
os: macos-13
|
||||
host_dmd: dmd
|
||||
# FIXME: Revert this back to "dmd" after 2.107.1 is released.
|
||||
host_dmd: ldc
|
||||
- job_name: macOS 13 x64, DMD (coverage)
|
||||
os: macos-13
|
||||
host_dmd: dmd
|
||||
# FIXME: Revert this back to "dmd" after 2.107.1 is released.
|
||||
host_dmd: ldc
|
||||
coverage: true
|
||||
- job_name: macOS 12 x64, DMD (bootstrap)
|
||||
os: macos-12
|
||||
|
@ -104,6 +106,13 @@ jobs:
|
|||
with:
|
||||
arch: ${{ env.MODEL == '64' && 'x64' || 'x86' }}
|
||||
|
||||
# NOTE: Linker ICEs with Xcode 15.0.1 (default version on macos-13)
|
||||
# * https://issues.dlang.org/show_bug.cgi?id=24407
|
||||
# Remove this step if the default gets changed to 15.1 in actions/runner-images.
|
||||
- name: 'macOS 13: Switch to Xcode v15.1'
|
||||
if: matrix.os == 'macos-13'
|
||||
run: sudo xcode-select -switch /Applications/Xcode_15.1.app
|
||||
|
||||
- name: 'Posix: Install host compiler'
|
||||
if: runner.os != 'Windows'
|
||||
run: ci/run.sh install_host_compiler
|
||||
|
@ -174,18 +183,18 @@ jobs:
|
|||
freebsd_version: '13.2'
|
||||
host_dmd: dmd-2.095.0
|
||||
name: ${{ matrix.job_name }}
|
||||
runs-on: macos-latest
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 50
|
||||
- name: Run in VM
|
||||
uses: cross-platform-actions/action@v0.22.0
|
||||
uses: cross-platform-actions/action@v0.23.0
|
||||
with:
|
||||
operating_system: freebsd
|
||||
hypervisor: qemu
|
||||
memory: 8G
|
||||
memory: 12G
|
||||
sync_files: runner-to-vm
|
||||
version: ${{ matrix.freebsd_version }}
|
||||
shell: bash
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
v2.107.1-rc.1
|
||||
v2.107.1
|
||||
|
|
|
@ -5035,14 +5035,9 @@ private elem * el64_32(elem *e, goal_t goal)
|
|||
}
|
||||
break;
|
||||
|
||||
case OPmul:
|
||||
if (config.exe & (EX_OSX | EX_OSX64)) // https://issues.dlang.org/show_bug.cgi?id=21047
|
||||
break;
|
||||
else
|
||||
goto case;
|
||||
|
||||
case OPadd:
|
||||
case OPmin:
|
||||
case OPmul:
|
||||
case OPor:
|
||||
case OPand:
|
||||
case OPxor:
|
||||
|
|
|
@ -16,15 +16,19 @@
|
|||
Some generic information for debug info on macOS:
|
||||
|
||||
The linker on macOS will remove any debug info, i.e. every section with the
|
||||
`S_ATTR_DEBUG` flag, this includes everything in the `__DWARF` section. By using
|
||||
the `S_REGULAR` flag the linker will not remove this section. This allows to get
|
||||
the filenames and line numbers for backtraces from the executable.
|
||||
`S_ATTR_DEBUG` flag, this includes everything in the `__DWARF` section.
|
||||
Because of this, it is not possible to get filenames and line numbers for
|
||||
backtraces from the executable alone.
|
||||
|
||||
Normally the linker removes all the debug info but adds a reference to the
|
||||
object files. The debugger can then read the object files to get filename and
|
||||
line number information. It's also possible to use an additional tool that
|
||||
generates a separate `.dSYM` file. This file can then later be deployed with the
|
||||
application if debug info is needed when the application is deployed.
|
||||
|
||||
Support in core.runtime for getting filename and line number for backtraces
|
||||
from these `.dSYM` files will need to be investigated.
|
||||
See: https://issues.dlang.org/show_bug.cgi?id=20510
|
||||
*/
|
||||
|
||||
module dmd.backend.dwarfdbginf;
|
||||
|
@ -478,7 +482,7 @@ static if (1)
|
|||
{
|
||||
name = n;
|
||||
if (config.objfmt == OBJ_MACH)
|
||||
flags = S_ATTR_DEBUG;
|
||||
flags = S_REGULAR | S_ATTR_DEBUG;
|
||||
else
|
||||
flags = SHT_PROGBITS;
|
||||
}
|
||||
|
@ -552,10 +556,7 @@ static if (1)
|
|||
debug_abbrev = Section("__debug_abbrev");
|
||||
debug_info = Section("__debug_info");
|
||||
debug_str = Section("__debug_str");
|
||||
// We use S_REGULAR to make sure the linker doesn't remove this section. Needed
|
||||
// for filenames and line numbers in backtraces.
|
||||
debug_line = Section("__debug_line");
|
||||
debug_line.flags = S_REGULAR;
|
||||
}
|
||||
void elfDebugSectionsInit()
|
||||
{
|
||||
|
|
|
@ -94,6 +94,12 @@ enum
|
|||
LC_SYMTAB = 2,
|
||||
LC_DYSYMTAB = 11,
|
||||
LC_SEGMENT_64 = 0x19,
|
||||
|
||||
/// Build for MacOSX min OS version.
|
||||
LC_VERSION_MIN_MACOSX = 0x24,
|
||||
|
||||
/// Build for platform min OS version.
|
||||
LC_BUILD_VERSION = 0x32,
|
||||
}
|
||||
|
||||
struct load_command
|
||||
|
@ -407,3 +413,62 @@ struct scattered_relocation_info
|
|||
|
||||
int r_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The version_min_command contains the min OS version on which this binary was
|
||||
* built to run.
|
||||
*/
|
||||
struct version_min_command
|
||||
{
|
||||
///
|
||||
uint cmd = LC_VERSION_MIN_MACOSX;
|
||||
|
||||
///
|
||||
uint cmdsize = typeof(this).sizeof;
|
||||
|
||||
/// X.Y.Z is encoded in nibbles xxxx.yy.zz
|
||||
uint version_;
|
||||
|
||||
/// X.Y.Z is encoded in nibbles xxxx.yy.zz
|
||||
uint sdk = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `build_version_command` contains the min OS version on which this binary
|
||||
* was built to run for its platform.
|
||||
*/
|
||||
struct build_version_command
|
||||
{
|
||||
///
|
||||
uint cmd = LC_BUILD_VERSION;
|
||||
|
||||
///
|
||||
uint cmdsize = typeof(this).sizeof;
|
||||
|
||||
/// Platform
|
||||
uint platform = PLATFORM_MACOS;
|
||||
|
||||
/// X.Y.Z is encoded in nibbles xxxx.yy.zz
|
||||
uint minos;
|
||||
|
||||
/// X.Y.Z is encoded in nibbles xxxx.yy.zz
|
||||
uint sdk = 0;
|
||||
|
||||
/// Number of tool entries following this
|
||||
uint ntools = 0;
|
||||
}
|
||||
|
||||
/// Known values for the platform field in `build_version_command`
|
||||
enum
|
||||
{
|
||||
PLATFORM_MACOS = 1,
|
||||
PLATFORM_IOS = 2,
|
||||
PLATFORM_TVOS = 3,
|
||||
PLATFORM_WATCHOS = 4,
|
||||
PLATFORM_BRIDGEOS = 5,
|
||||
PLATFORM_MACCATALYST = 6,
|
||||
PLATFORM_IOSSIMULATOR = 7,
|
||||
PLATFORM_TVOSSIMULATOR = 8,
|
||||
PLATFORM_WATCHOSSIMULATOR = 9,
|
||||
PLATFORM_DRIVERKIT = 10
|
||||
}
|
||||
|
|
|
@ -625,6 +625,7 @@ void MachObj_term(const(char)* objfilename)
|
|||
* { sections }
|
||||
* symtab_command
|
||||
* dysymtab_command
|
||||
* build_version_command/version_min_command
|
||||
* { segment contents }
|
||||
* { relocations }
|
||||
* symbol table
|
||||
|
@ -632,6 +633,7 @@ void MachObj_term(const(char)* objfilename)
|
|||
* indirect symbol table
|
||||
*/
|
||||
|
||||
auto version_command = VersionCommand(operatingSystemVersion);
|
||||
uint foffset;
|
||||
uint headersize;
|
||||
uint sizeofcmds;
|
||||
|
@ -645,9 +647,10 @@ void MachObj_term(const(char)* objfilename)
|
|||
header.cputype = CPU_TYPE_X86_64;
|
||||
header.cpusubtype = CPU_SUBTYPE_I386_ALL;
|
||||
header.filetype = MH_OBJECT;
|
||||
header.ncmds = 3;
|
||||
header.ncmds = 4;
|
||||
header.sizeofcmds = cast(uint)(segment_command_64.sizeof +
|
||||
(section_cnt - 1) * section_64.sizeof +
|
||||
version_command.size +
|
||||
symtab_command.sizeof +
|
||||
dysymtab_command.sizeof);
|
||||
header.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
|
||||
|
@ -669,9 +672,10 @@ void MachObj_term(const(char)* objfilename)
|
|||
header.cputype = CPU_TYPE_I386;
|
||||
header.cpusubtype = CPU_SUBTYPE_I386_ALL;
|
||||
header.filetype = MH_OBJECT;
|
||||
header.ncmds = 3;
|
||||
header.ncmds = 4;
|
||||
header.sizeofcmds = cast(uint)(segment_command.sizeof +
|
||||
(section_cnt - 1) * section.sizeof +
|
||||
version_command.size +
|
||||
symtab_command.sizeof +
|
||||
dysymtab_command.sizeof);
|
||||
header.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
|
||||
|
@ -864,6 +868,8 @@ void MachObj_term(const(char)* objfilename)
|
|||
}
|
||||
|
||||
// Put out relocation data
|
||||
// See mach-o/reloc.h for some examples of what should be generated and when:
|
||||
// https://github.com/apple-oss-distributions/xnu/blob/rel/xnu-10002/EXTERNAL_HEADERS/mach-o/x86_64/reloc.h
|
||||
mach_numbersyms();
|
||||
for (int seg = 1; seg < SegData.length; seg++)
|
||||
{
|
||||
|
@ -975,12 +981,8 @@ void MachObj_term(const(char)* objfilename)
|
|||
rel.r_type = X86_64_RELOC_SIGNED;
|
||||
else if ((s.Sfl == FLfunc || s.Sfl == FLextern || s.Sclass == SC.global ||
|
||||
s.Sclass == SC.comdat || s.Sclass == SC.comdef) && r.rtype == RELaddr)
|
||||
{
|
||||
rel.r_type = X86_64_RELOC_GOT_LOAD;
|
||||
if (seg == eh_frame_seg ||
|
||||
seg == except_table_seg)
|
||||
rel.r_type = X86_64_RELOC_GOT;
|
||||
}
|
||||
|
||||
rel.r_address = cast(int)r.offset;
|
||||
rel.r_symbolnum = s.Sxtrnnum;
|
||||
rel.r_pcrel = 1;
|
||||
|
@ -1352,6 +1354,7 @@ void MachObj_term(const(char)* objfilename)
|
|||
sym32.n_sect = sym.n_sect;
|
||||
fobjbuf.write(&sym32, sym32.sizeof);
|
||||
}
|
||||
dysymtab_cmd.nundefsym++;
|
||||
symtab_cmd.nsyms++;
|
||||
}
|
||||
foffset += symtab_cmd.nsyms * (I64 ? nlist_64.sizeof : nlist.sizeof);
|
||||
|
@ -1399,6 +1402,7 @@ void MachObj_term(const(char)* objfilename)
|
|||
fobjbuf.write(&segment_cmd, segment_cmd.sizeof);
|
||||
fobjbuf.write(SECbuf.buf + section.sizeof, cast(uint)((section_cnt - 1) * section.sizeof));
|
||||
}
|
||||
fobjbuf.write(version_command.data, version_command.size);
|
||||
fobjbuf.write(&symtab_cmd, symtab_cmd.sizeof);
|
||||
fobjbuf.write(&dysymtab_cmd, dysymtab_cmd.sizeof);
|
||||
fobjbuf.position(foffset, 0);
|
||||
|
@ -2823,3 +2827,170 @@ int dwarf_eh_frame_fixup(int dfseg, targ_size_t offset, Symbol *s, targ_size_t v
|
|||
|
||||
return I64 ? 8 : 4;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Encapsulates the build_version_command/version_min_command load commands.
|
||||
*
|
||||
* For the 10.14 and later SDK, the `build_version_command` load command is used.
|
||||
* For earlier versions, the `version_min_command` load command is used.
|
||||
*/
|
||||
const struct VersionCommand
|
||||
{
|
||||
pure:
|
||||
nothrow:
|
||||
@nogc:
|
||||
@safe:
|
||||
|
||||
private
|
||||
{
|
||||
/**
|
||||
* This is the absolute minimum supported version of macOS (64 bit) for DMD,
|
||||
* as documented at: https://dlang.org/dmd-osx.html#requirements
|
||||
* NOTE: Versions earlier than 10.7 do not support thread local storage.
|
||||
*/
|
||||
enum fallbackOSVersion = Version(10, 9).encode;
|
||||
|
||||
/// The first minor version that uses the `build_version_command`.
|
||||
enum firstMinorUsingBuildVersionCommand = 14;
|
||||
|
||||
/// `true` if the `build_version_command` load command should be used.
|
||||
bool useBuild;
|
||||
|
||||
/// The `build_version_command` load command.
|
||||
build_version_command buildVersionCommand;
|
||||
|
||||
/// The `version_min_command` load command.
|
||||
version_min_command versionMinCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the VersionCommand.
|
||||
*
|
||||
* Params:
|
||||
* os = the version of the operating system
|
||||
*/
|
||||
this(Version os)
|
||||
{
|
||||
useBuild = os.minor >= firstMinorUsingBuildVersionCommand;
|
||||
|
||||
const encodedOs = os.isValid ? os.encode : fallbackOSVersion;
|
||||
|
||||
const build_version_command buildVersionCommand = { minos: encodedOs };
|
||||
const version_min_command versionMinCommand = { version_: encodedOs };
|
||||
|
||||
this.buildVersionCommand = buildVersionCommand;
|
||||
this.versionMinCommand = versionMinCommand;
|
||||
}
|
||||
|
||||
/// Returns: the size of the load command.
|
||||
size_t size()
|
||||
{
|
||||
return useBuild ? build_version_command.sizeof : version_min_command.sizeof;
|
||||
}
|
||||
|
||||
/// Returns: the data for the load command.
|
||||
const(void)* data() return
|
||||
{
|
||||
return useBuild ? cast(const(void)*) &buildVersionCommand : cast(const(void)*) &versionMinCommand;
|
||||
}
|
||||
}
|
||||
|
||||
/// Holds an operating system version or a SDK version.
|
||||
immutable struct Version
|
||||
{
|
||||
///
|
||||
int major;
|
||||
|
||||
///
|
||||
int minor;
|
||||
|
||||
///
|
||||
int build;
|
||||
|
||||
/// Returns: `true` if the version is valid
|
||||
bool isValid() pure nothrow @nogc @safe
|
||||
{
|
||||
return major >= 10 && major < 100 &&
|
||||
minor >= 0 && minor < 100 &&
|
||||
build >= 0 && build < 100;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given version encoded as a single integer.
|
||||
*
|
||||
* Params:
|
||||
* version_ = the version to encode. Needs to be a valid version
|
||||
* (`version_.isValid`)
|
||||
*
|
||||
* Returns: the encoded version
|
||||
*/
|
||||
int encode(Version version_) pure @nogc @safe
|
||||
in
|
||||
{
|
||||
assert(version_.isValid);
|
||||
}
|
||||
do
|
||||
{
|
||||
with (version_)
|
||||
return major * 2^^16 + minor * 2^^8 + build * 2^^0;
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
assert(Version(10, 14, 0).encode == 0x0a0e00);
|
||||
assert(Version(10, 14, 1).encode == 0x0a0e01);
|
||||
assert(Version(10, 14, 6).encode == 0x0a0e06);
|
||||
assert(Version(10, 14, 99).encode == 0x0a0e63);
|
||||
|
||||
assert(Version(10, 15, 6).encode == 0x0a0f06);
|
||||
|
||||
assert(Version(10, 16, 0).encode == 0x0a1000);
|
||||
assert(Version(10, 16, 6).encode == 0x0a1006);
|
||||
|
||||
assert(Version(10, 17, 0).encode == 0x0a1100);
|
||||
}
|
||||
|
||||
/// Returns: the version of the currently running operating system.
|
||||
@trusted
|
||||
Version operatingSystemVersion()
|
||||
{
|
||||
if (const deploymentTarget = getenv("MACOSX_DEPLOYMENT_TARGET"))
|
||||
{
|
||||
const version_ = toVersion(deploymentTarget);
|
||||
|
||||
if (version_.isValid)
|
||||
return version_;
|
||||
|
||||
error(null, 0, 0, "invalid version number in 'MACOSX_DEPLOYMENT_TARGET=%s'", deploymentTarget);
|
||||
}
|
||||
return Version();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given string to a `Version`.
|
||||
*
|
||||
* Params:
|
||||
* str = the string to convert. Should have the format `XX.YY(.ZZ)`. Needs to
|
||||
* be `\0` terminated.
|
||||
*
|
||||
* Returns: the converted `Version`.
|
||||
*/
|
||||
@trusted
|
||||
Version toVersion(const char* str) @nogc
|
||||
{
|
||||
import core.stdc.stdio : sscanf;
|
||||
|
||||
if (!str)
|
||||
return Version();
|
||||
|
||||
Version version_;
|
||||
|
||||
with (version_)
|
||||
str.sscanf("%d.%d.%d", &major, &minor, &build);
|
||||
|
||||
return version_;
|
||||
}
|
||||
|
|
|
@ -2155,7 +2155,7 @@ final class CParser(AST) : Parser!AST
|
|||
error("function identifier-list cannot end with `...`");
|
||||
ft.parameterList.varargs = AST.VarArg.KRvariadic; // but C11 allows extra arguments
|
||||
auto plLength = pl.length;
|
||||
if (symbols.length != plLength)
|
||||
if (symbols && symbols.length != plLength)
|
||||
error(token.loc, "%d identifiers does not match %d declarations", cast(int)plLength, cast(int)symbols.length);
|
||||
|
||||
/* Transfer the types and storage classes from symbols[] to pl[]
|
||||
|
@ -2176,6 +2176,12 @@ final class CParser(AST) : Parser!AST
|
|||
|
||||
if (p.type || !(p.storageClass & STC.parameter))
|
||||
error("storage class and type are not allowed in identifier-list");
|
||||
if (!symbols)
|
||||
{
|
||||
// Error already given in cparseDeclaration
|
||||
p.type = AST.Type.terror;
|
||||
continue;
|
||||
}
|
||||
foreach (s; (*symbols)[]) // yes, quadratic
|
||||
{
|
||||
auto ad = s.isAttribDeclaration();
|
||||
|
|
|
@ -3787,7 +3787,7 @@ public:
|
|||
if (v is v2 || !v.isOverlappedWith(v2))
|
||||
continue;
|
||||
auto e = (*sle.elements)[i];
|
||||
if (e.op != EXP.void_)
|
||||
if (e !is null && e.op != EXP.void_)
|
||||
(*sle.elements)[i] = voidInitLiteral(e.type, v).copy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1394,6 +1394,7 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
|||
{
|
||||
enum SourceEncoding { utf16, utf32}
|
||||
enum Endian { little, big}
|
||||
immutable loc = mod.getLoc();
|
||||
|
||||
/*
|
||||
* Convert a buffer from UTF32 to UTF8
|
||||
|
@ -1413,7 +1414,7 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
|||
|
||||
if (buf.length & 3)
|
||||
{
|
||||
.error(mod.loc, "%s `%s` odd length of UTF-32 char source %llu",
|
||||
.error(loc, "%s `%s` odd length of UTF-32 char source %llu",
|
||||
mod.kind, mod.toPrettyChars, cast(ulong) buf.length);
|
||||
return null;
|
||||
}
|
||||
|
@ -1430,7 +1431,7 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
|||
{
|
||||
if (u > 0x10FFFF)
|
||||
{
|
||||
.error(mod.loc, "%s `%s` UTF-32 value %08x greater than 0x10FFFF", mod.kind, mod.toPrettyChars, u);
|
||||
.error(loc, "%s `%s` UTF-32 value %08x greater than 0x10FFFF", mod.kind, mod.toPrettyChars, u);
|
||||
return null;
|
||||
}
|
||||
dbuf.writeUTF8(u);
|
||||
|
@ -1460,7 +1461,7 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
|||
|
||||
if (buf.length & 1)
|
||||
{
|
||||
.error(mod.loc, "%s `%s` odd length of UTF-16 char source %llu", mod.kind, mod.toPrettyChars, cast(ulong) buf.length);
|
||||
.error(loc, "%s `%s` odd length of UTF-16 char source %llu", mod.kind, mod.toPrettyChars, cast(ulong) buf.length);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1480,13 +1481,13 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
|||
i++;
|
||||
if (i >= eBuf.length)
|
||||
{
|
||||
.error(mod.loc, "%s `%s` surrogate UTF-16 high value %04x at end of file", mod.kind, mod.toPrettyChars, u);
|
||||
.error(loc, "%s `%s` surrogate UTF-16 high value %04x at end of file", mod.kind, mod.toPrettyChars, u);
|
||||
return null;
|
||||
}
|
||||
const u2 = readNext(&eBuf[i]);
|
||||
if (u2 < 0xDC00 || 0xE000 <= u2)
|
||||
{
|
||||
.error(mod.loc, "%s `%s` surrogate UTF-16 low value %04x out of range", mod.kind, mod.toPrettyChars, u2);
|
||||
.error(loc, "%s `%s` surrogate UTF-16 low value %04x out of range", mod.kind, mod.toPrettyChars, u2);
|
||||
return null;
|
||||
}
|
||||
u = (u - 0xD7C0) << 10;
|
||||
|
@ -1494,12 +1495,12 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
|||
}
|
||||
else if (u >= 0xDC00 && u <= 0xDFFF)
|
||||
{
|
||||
.error(mod.loc, "%s `%s` unpaired surrogate UTF-16 value %04x", mod.kind, mod.toPrettyChars, u);
|
||||
.error(loc, "%s `%s` unpaired surrogate UTF-16 value %04x", mod.kind, mod.toPrettyChars, u);
|
||||
return null;
|
||||
}
|
||||
else if (u == 0xFFFE || u == 0xFFFF)
|
||||
{
|
||||
.error(mod.loc, "%s `%s` illegal UTF-16 value %04x", mod.kind, mod.toPrettyChars, u);
|
||||
.error(loc, "%s `%s` illegal UTF-16 value %04x", mod.kind, mod.toPrettyChars, u);
|
||||
return null;
|
||||
}
|
||||
dbuf.writeUTF8(u);
|
||||
|
@ -1558,7 +1559,6 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
|||
// It's UTF-8
|
||||
if (buf[0] >= 0x80)
|
||||
{
|
||||
auto loc = mod.getLoc();
|
||||
.error(loc, "%s `%s` source file must start with BOM or ASCII character, not \\x%02X", mod.kind, mod.toPrettyChars, buf[0]);
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -12357,8 +12357,16 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
return result;
|
||||
}
|
||||
|
||||
void handleCatArgument(Expressions *arguments, Expression e)
|
||||
void handleCatArgument(Expressions *arguments, Expression e, Type catType, bool isRightArg)
|
||||
{
|
||||
auto tb = e.type.toBasetype();
|
||||
|
||||
if ((isRightArg && e.parens) || (!isRightArg && !tb.equals(catType)))
|
||||
{
|
||||
arguments.push(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto ce = e.isCatExp())
|
||||
{
|
||||
Expression lowering = ce.lowering;
|
||||
|
@ -12388,8 +12396,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
arguments.push(new StringExp(exp.loc, funcname.toDString()));
|
||||
}
|
||||
|
||||
handleCatArgument(arguments, exp.e1);
|
||||
handleCatArgument(arguments, exp.e2);
|
||||
handleCatArgument(arguments, exp.e1, exp.type.toBasetype(), false);
|
||||
handleCatArgument(arguments, exp.e2, exp.type.toBasetype(), true);
|
||||
|
||||
Expression id = new IdentifierExp(exp.loc, Id.empty);
|
||||
id = new DotIdExp(exp.loc, id, Id.object);
|
||||
|
|
|
@ -338,7 +338,7 @@ struct Segments
|
|||
immutable(char*) sectionName;
|
||||
immutable(char*) segmentName;
|
||||
immutable int flags;
|
||||
immutable int alignment;
|
||||
immutable int p2align;
|
||||
|
||||
this(typeof(this.tupleof) tuple) @safe
|
||||
{
|
||||
|
@ -388,7 +388,7 @@ struct Segments
|
|||
return segments[id] = Obj.getsegment(
|
||||
seg.sectionName,
|
||||
seg.segmentName,
|
||||
seg.alignment,
|
||||
seg.p2align,
|
||||
seg.flags
|
||||
);
|
||||
}
|
||||
|
@ -1159,7 +1159,7 @@ private:
|
|||
const symbolName = prefix ~ classDeclaration.objc.identifier.toString();
|
||||
auto symbol = Symbols.getStatic(symbolName);
|
||||
symbol.Sseg = Segments[Segments.Id.const_];
|
||||
symbol.Salignment = 3;
|
||||
symbol.Salignment = 8;
|
||||
symbol.Sdt = dtb.finish();
|
||||
|
||||
return symbol;
|
||||
|
@ -1311,7 +1311,7 @@ struct ProtocolDeclaration
|
|||
symbol.Sseg = Segments[Segments.Id.protolist];
|
||||
symbol.Sclass = SC.comdat;
|
||||
symbol.Sflags |= SFLhidden;
|
||||
symbol.Salignment = 3;
|
||||
symbol.Salignment = 8;
|
||||
|
||||
auto dtb = DtBuilder(0);
|
||||
dtb.xoff(protocol, 0);
|
||||
|
@ -1326,7 +1326,7 @@ struct ProtocolDeclaration
|
|||
symbol.Sseg = Segments[Segments.Id.data];
|
||||
symbol.Sclass = SC.comdat;
|
||||
symbol.Sflags |= SFLhidden;
|
||||
symbol.Salignment = 3;
|
||||
symbol.Salignment = 8;
|
||||
|
||||
auto dtb = DtBuilder(0);
|
||||
toDt(dtb);
|
||||
|
@ -1478,7 +1478,7 @@ private:
|
|||
|
||||
symbol.Sdt = dtb.finish();
|
||||
symbol.Sseg = Segments[Segments.Id.const_];
|
||||
symbol.Salignment = 3;
|
||||
symbol.Salignment = 8;
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
@ -1512,7 +1512,7 @@ private:
|
|||
|
||||
symbol.Sdt = dtb.finish();
|
||||
symbol.Sseg = Segments[Segments.Id.const_];
|
||||
symbol.Salignment = 3;
|
||||
symbol.Salignment = 8;
|
||||
|
||||
outdata(symbol);
|
||||
|
||||
|
@ -1546,7 +1546,7 @@ private:
|
|||
|
||||
symbol.Sdt = dtb.finish();
|
||||
symbol.Sseg = Segments[Segments.Id.const_];
|
||||
symbol.Salignment = 3;
|
||||
symbol.Salignment = 8;
|
||||
|
||||
outdata(symbol);
|
||||
|
||||
|
|
|
@ -92,6 +92,11 @@ void Initializer_toDt(Initializer init, ref DtBuilder dtb, bool isCfile)
|
|||
if (tb.ty == Tvector)
|
||||
tb = (cast(TypeVector)tb).basetype;
|
||||
|
||||
if (ai.dim == 0 && tb.isZeroInit(ai.loc))
|
||||
{
|
||||
dtb.nzeros(cast(uint)ai.type.size());
|
||||
return;
|
||||
}
|
||||
Type tn = tb.nextOf().toBasetype();
|
||||
|
||||
//printf("\tdim = %d\n", ai.dim);
|
||||
|
|
9
compiler/test/compilable/issue24399.d
Normal file
9
compiler/test/compilable/issue24399.d
Normal file
|
@ -0,0 +1,9 @@
|
|||
// REQUIRED_ARGS: -main
|
||||
// LINK:
|
||||
template rt_options()
|
||||
{
|
||||
__gshared string[] rt_options = [];
|
||||
string[] rt_options_tls = [];
|
||||
}
|
||||
|
||||
alias _ = rt_options!();
|
17
compiler/test/compilable/issue24409.d
Normal file
17
compiler/test/compilable/issue24409.d
Normal file
|
@ -0,0 +1,17 @@
|
|||
static struct S
|
||||
{
|
||||
union
|
||||
{
|
||||
int i;
|
||||
long l;
|
||||
}
|
||||
}
|
||||
|
||||
int f()
|
||||
{
|
||||
S* r = new S();
|
||||
r.i = 5;
|
||||
return r.i;
|
||||
}
|
||||
|
||||
enum X = f();
|
7
compiler/test/fail_compilation/fail24422.c
Normal file
7
compiler/test/fail_compilation/fail24422.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail24422.c(7): Error: type-specifier missing for declaration of `a`
|
||||
---
|
||||
*/
|
||||
void f24422(a) a; { }
|
|
@ -1,50 +0,0 @@
|
|||
// REQUIRED_ARGS: -g
|
||||
|
||||
void main()
|
||||
{
|
||||
version(OSX) testDebugLineMacOS();
|
||||
}
|
||||
|
||||
version (OSX):
|
||||
|
||||
struct mach_header;
|
||||
struct mach_header_64;
|
||||
struct section;
|
||||
struct section_64;
|
||||
|
||||
version (D_LP64)
|
||||
{
|
||||
alias MachHeader = mach_header_64;
|
||||
alias Section = section_64;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
alias MachHeader = mach_header;
|
||||
alias Section = section;
|
||||
}
|
||||
|
||||
extern (C)
|
||||
{
|
||||
MachHeader* _dyld_get_image_header(uint image_index);
|
||||
const(section)* getsectbynamefromheader(scope const mach_header* mhp, scope const char* segname, scope const char* sectname);
|
||||
const(section_64)* getsectbynamefromheader_64(scope const mach_header_64* mhp, scope const char* segname, scope const char* sectname);
|
||||
}
|
||||
|
||||
const(Section)* getSectByNameFromHeader(MachHeader* mhp, in char* segname, in char* sectname)
|
||||
{
|
||||
version (D_LP64)
|
||||
return getsectbynamefromheader_64(mhp, segname, sectname);
|
||||
else
|
||||
return getsectbynamefromheader(mhp, segname, sectname);
|
||||
}
|
||||
|
||||
void testDebugLineMacOS()
|
||||
{
|
||||
auto header = _dyld_get_image_header(0);
|
||||
assert(header);
|
||||
|
||||
auto section = getSectByNameFromHeader(header, "__DWARF", "__debug_line");
|
||||
// verify that the __debug_line section is present in the final executable
|
||||
assert(section);
|
||||
}
|
8
compiler/test/runnable/extra-files/link20802a.d
Normal file
8
compiler/test/runnable/extra-files/link20802a.d
Normal file
|
@ -0,0 +1,8 @@
|
|||
import link20802b;
|
||||
void main()
|
||||
{
|
||||
// First test from https://issues.dlang.org/show_bug.cgi?id=20802#c3
|
||||
CodepointSet('a', 'z');
|
||||
dstring s;
|
||||
decodeGrapheme(s);
|
||||
}
|
30
compiler/test/runnable/extra-files/link20802b.d
Normal file
30
compiler/test/runnable/extra-files/link20802b.d
Normal file
|
@ -0,0 +1,30 @@
|
|||
module link20802b;
|
||||
|
||||
// First test from https://issues.dlang.org/show_bug.cgi?id=20802#c3
|
||||
|
||||
enum TransformRes { goOn }
|
||||
|
||||
void writeAligned()()
|
||||
{
|
||||
final switch (TransformRes.goOn) { case TransformRes.goOn: break; }
|
||||
}
|
||||
|
||||
struct GcPolicy {}
|
||||
alias CodepointSet = InversionList!GcPolicy;
|
||||
struct InversionList(SP=GcPolicy)
|
||||
{
|
||||
this()(uint[] intervals...)
|
||||
{
|
||||
sanitize();
|
||||
}
|
||||
|
||||
void sanitize()
|
||||
{
|
||||
writeAligned();
|
||||
}
|
||||
}
|
||||
|
||||
void decodeGrapheme(Input)(ref Input inp)
|
||||
{
|
||||
final switch (TransformRes.goOn) { case TransformRes.goOn: break; }
|
||||
}
|
6
compiler/test/runnable/issue24401.d
Normal file
6
compiler/test/runnable/issue24401.d
Normal file
|
@ -0,0 +1,6 @@
|
|||
// PERMUTE_ARGS:
|
||||
// https://issues.dlang.org/show_bug.cgi?id=24401
|
||||
int main()
|
||||
{
|
||||
return (() @trusted => 0)();
|
||||
}
|
14
compiler/test/runnable/link20802.sh
Executable file
14
compiler/test/runnable/link20802.sh
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
dir=${RESULTS_DIR}${SEP}runnable
|
||||
|
||||
libname=${OUTPUT_BASE}${LIBEXT}
|
||||
exename=${OUTPUT_BASE}${EXE}
|
||||
|
||||
$DMD -m${MODEL} -I${EXTRA_FILES} -lib -release -of${libname} ${EXTRA_FILES}${SEP}link20802b.d
|
||||
$DMD -m${MODEL} -I${EXTRA_FILES} -of${exename} ${EXTRA_FILES}${SEP}link20802a.d ${libname}
|
||||
|
||||
${exename}
|
||||
|
||||
rm_retry ${OUTPUT_BASE}{${LIBEXT},${EXE},${OBJ}}
|
15
compiler/test/runnable/test24371.d
Normal file
15
compiler/test/runnable/test24371.d
Normal file
|
@ -0,0 +1,15 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=24371
|
||||
|
||||
void main()
|
||||
{
|
||||
assert("b" ~ "c" == "bc");
|
||||
assert(["a"] ~ "b" == ["a", "b"]);
|
||||
assert(["a"] ~ ("b" ~ "c") == ["a", "bc"]);
|
||||
|
||||
auto strArr = ["a"];
|
||||
assert(strArr ~ ("b" ~ "c") == ["a", "bc"]);
|
||||
auto str = "c";
|
||||
assert(["a"] ~ ("b" ~ str) == ["a", "bc"]);
|
||||
|
||||
assert(strArr ~ ("b" ~ str) == ["a", "bc"]);
|
||||
}
|
|
@ -1,12 +1,5 @@
|
|||
// EXTRA_CPP_SOURCES: cpp7925.cpp
|
||||
|
||||
/*
|
||||
Exclude -O/-inline due to a codegen bug on OSX:
|
||||
https://issues.dlang.org/show_bug.cgi?id=22556
|
||||
|
||||
PERMUTE_ARGS(osx): -release -g
|
||||
*/
|
||||
|
||||
import core.vararg;
|
||||
|
||||
extern(C++) class C1
|
||||
|
|
|
@ -19,6 +19,19 @@ void __switch_errorT()(string file = __FILE__, size_t line = __LINE__) @trusted
|
|||
assert(0, "No appropriate switch clause found");
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure template __switch_errorT is always instantiated when building
|
||||
* druntime. This works around https://issues.dlang.org/show_bug.cgi?id=20802.
|
||||
* When druntime and phobos are compiled with -release, the instance for
|
||||
* __switch_errorT is not needed. An application compiled with -release
|
||||
* could need the instance for __switch_errorT, but the compiler would
|
||||
* not generate code for it, because it assumes, that it was already
|
||||
* generated for druntime. Always including the instance in a compiled
|
||||
* druntime allows to use an application without -release with druntime
|
||||
* with -release.
|
||||
*/
|
||||
private alias dummy__switch_errorT = __switch_errorT!();
|
||||
|
||||
/**
|
||||
* Thrown on a range error.
|
||||
*/
|
||||
|
|
|
@ -20,7 +20,7 @@ ifeq ($(OS)-$(BUILD),dragonflybsd-debug)
|
|||
LINE_TRACE_DFLAGS:=-L--export-dynamic
|
||||
endif
|
||||
ifeq ($(OS)-$(BUILD),osx-debug)
|
||||
TESTS+=line_trace line_trace_21656 long_backtrace_trunc cpp_demangle
|
||||
TESTS+=line_trace line_trace_21656 cpp_demangle
|
||||
LINE_TRACE_DFLAGS:=
|
||||
endif
|
||||
ifeq ($(OS)-$(BUILD),windows-debug)
|
||||
|
@ -42,7 +42,7 @@ $(ROOT)/line_trace.done: $(ROOT)/line_trace$(DOTEXE)
|
|||
@echo Testing line_trace
|
||||
$(QUIET)$(TIMELIMIT)$(ROOT)/line_trace $(RUN_ARGS) > $(ROOT)/line_trace.output
|
||||
# Use sed to canonicalize line_trace.output and compare against expected output in line_trace.exp
|
||||
$(QUIET)$(SED) "s/\[0x[0-9a-f]*\]/\[ADDR\]/g; s/scope //g; s/Nl//g" $(ROOT)/line_trace.output | $(DIFF) line_trace.exp -
|
||||
$(QUIET)$(SED) "s|^.*/src/|src/|g; s/\[0x[0-9a-f]*\]/\[ADDR\]/g; s/scope //g; s/Nl//g" $(ROOT)/line_trace.output | $(DIFF) line_trace.exp -
|
||||
@rm -f $(ROOT)/line_trace.output
|
||||
@touch $@
|
||||
|
||||
|
@ -52,7 +52,7 @@ $(ROOT)/line_trace_21656.done: $(ROOT)/line_trace$(DOTEXE)
|
|||
@mkdir -p $(ROOT)/line_trace_21656
|
||||
@touch $(ROOT)/line_trace_21656/line_trace
|
||||
$(QUIET)cd $(ROOT)/line_trace_21656 && PATH="..:$$PATH" $(TIMELIMIT)line_trace $(RUN_ARGS) > line_trace.output
|
||||
$(QUIET)$(SED) "s/\[0x[0-9a-f]*\]/\[ADDR\]/g; s/scope //g; s/Nl//g" $(ROOT)/line_trace_21656/line_trace.output | $(DIFF) line_trace.exp -
|
||||
$(QUIET)$(SED) "s|^.*/src/|src/|g; s/\[0x[0-9a-f]*\]/\[ADDR\]/g; s/scope //g; s/Nl//g" $(ROOT)/line_trace_21656/line_trace.output | $(DIFF) line_trace.exp -
|
||||
@rm -rf $(ROOT)/line_trace_21656
|
||||
@touch $@
|
||||
|
||||
|
@ -60,7 +60,7 @@ $(ROOT)/long_backtrace_trunc.done: $(ROOT)/long_backtrace_trunc$(DOTEXE)
|
|||
@echo Testing long_backtrace_trunc
|
||||
$(QUIET)$(TIMELIMIT)$(ROOT)/long_backtrace_trunc $(RUN_ARGS) > $(ROOT)/long_backtrace_trunc.output
|
||||
# Use sed to canonicalize long_backtrace_trunc.output and compare against expected output in long_backtrace_trunc.exp
|
||||
$(QUIET)$(SED) "s/\[0x[0-9a-f]*\]/\[ADDR\]/g; s/scope //g; s/Nl//g" $(ROOT)/long_backtrace_trunc.output | $(DIFF) long_backtrace_trunc.exp -
|
||||
$(QUIET)$(SED) "s|^.*/src/|src/|g; s/\[0x[0-9a-f]*\]/\[ADDR\]/g; s/scope //g; s/Nl//g" $(ROOT)/long_backtrace_trunc.output | $(DIFF) long_backtrace_trunc.exp -
|
||||
@rm -f $(ROOT)/long_backtrace_trunc.output
|
||||
@touch $@
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue