mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
commit
bb59a07e65
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
|
# macOS
|
||||||
- job_name: macOS 13 x64, DMD (latest)
|
- job_name: macOS 13 x64, DMD (latest)
|
||||||
os: macos-13
|
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)
|
- job_name: macOS 13 x64, DMD (coverage)
|
||||||
os: macos-13
|
os: macos-13
|
||||||
host_dmd: dmd
|
# FIXME: Revert this back to "dmd" after 2.107.1 is released.
|
||||||
|
host_dmd: ldc
|
||||||
coverage: true
|
coverage: true
|
||||||
- job_name: macOS 12 x64, DMD (bootstrap)
|
- job_name: macOS 12 x64, DMD (bootstrap)
|
||||||
os: macos-12
|
os: macos-12
|
||||||
|
@ -104,6 +106,13 @@ jobs:
|
||||||
with:
|
with:
|
||||||
arch: ${{ env.MODEL == '64' && 'x64' || 'x86' }}
|
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'
|
- name: 'Posix: Install host compiler'
|
||||||
if: runner.os != 'Windows'
|
if: runner.os != 'Windows'
|
||||||
run: ci/run.sh install_host_compiler
|
run: ci/run.sh install_host_compiler
|
||||||
|
@ -174,18 +183,18 @@ jobs:
|
||||||
freebsd_version: '13.2'
|
freebsd_version: '13.2'
|
||||||
host_dmd: dmd-2.095.0
|
host_dmd: dmd-2.095.0
|
||||||
name: ${{ matrix.job_name }}
|
name: ${{ matrix.job_name }}
|
||||||
runs-on: macos-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 50
|
fetch-depth: 50
|
||||||
- name: Run in VM
|
- name: Run in VM
|
||||||
uses: cross-platform-actions/action@v0.22.0
|
uses: cross-platform-actions/action@v0.23.0
|
||||||
with:
|
with:
|
||||||
operating_system: freebsd
|
operating_system: freebsd
|
||||||
hypervisor: qemu
|
hypervisor: qemu
|
||||||
memory: 8G
|
memory: 12G
|
||||||
sync_files: runner-to-vm
|
sync_files: runner-to-vm
|
||||||
version: ${{ matrix.freebsd_version }}
|
version: ${{ matrix.freebsd_version }}
|
||||||
shell: bash
|
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;
|
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 OPadd:
|
||||||
case OPmin:
|
case OPmin:
|
||||||
|
case OPmul:
|
||||||
case OPor:
|
case OPor:
|
||||||
case OPand:
|
case OPand:
|
||||||
case OPxor:
|
case OPxor:
|
||||||
|
|
|
@ -16,15 +16,19 @@
|
||||||
Some generic information for debug info on macOS:
|
Some generic information for debug info on macOS:
|
||||||
|
|
||||||
The linker on macOS will remove any debug info, i.e. every section with the
|
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
|
`S_ATTR_DEBUG` flag, this includes everything in the `__DWARF` section.
|
||||||
the `S_REGULAR` flag the linker will not remove this section. This allows to get
|
Because of this, it is not possible to get filenames and line numbers for
|
||||||
the filenames and line numbers for backtraces from the executable.
|
backtraces from the executable alone.
|
||||||
|
|
||||||
Normally the linker removes all the debug info but adds a reference to the
|
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
|
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
|
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
|
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.
|
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;
|
module dmd.backend.dwarfdbginf;
|
||||||
|
@ -478,7 +482,7 @@ static if (1)
|
||||||
{
|
{
|
||||||
name = n;
|
name = n;
|
||||||
if (config.objfmt == OBJ_MACH)
|
if (config.objfmt == OBJ_MACH)
|
||||||
flags = S_ATTR_DEBUG;
|
flags = S_REGULAR | S_ATTR_DEBUG;
|
||||||
else
|
else
|
||||||
flags = SHT_PROGBITS;
|
flags = SHT_PROGBITS;
|
||||||
}
|
}
|
||||||
|
@ -552,10 +556,7 @@ static if (1)
|
||||||
debug_abbrev = Section("__debug_abbrev");
|
debug_abbrev = Section("__debug_abbrev");
|
||||||
debug_info = Section("__debug_info");
|
debug_info = Section("__debug_info");
|
||||||
debug_str = Section("__debug_str");
|
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 = Section("__debug_line");
|
||||||
debug_line.flags = S_REGULAR;
|
|
||||||
}
|
}
|
||||||
void elfDebugSectionsInit()
|
void elfDebugSectionsInit()
|
||||||
{
|
{
|
||||||
|
|
|
@ -94,6 +94,12 @@ enum
|
||||||
LC_SYMTAB = 2,
|
LC_SYMTAB = 2,
|
||||||
LC_DYSYMTAB = 11,
|
LC_DYSYMTAB = 11,
|
||||||
LC_SEGMENT_64 = 0x19,
|
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
|
struct load_command
|
||||||
|
@ -407,3 +413,62 @@ struct scattered_relocation_info
|
||||||
|
|
||||||
int r_value;
|
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 }
|
* { sections }
|
||||||
* symtab_command
|
* symtab_command
|
||||||
* dysymtab_command
|
* dysymtab_command
|
||||||
|
* build_version_command/version_min_command
|
||||||
* { segment contents }
|
* { segment contents }
|
||||||
* { relocations }
|
* { relocations }
|
||||||
* symbol table
|
* symbol table
|
||||||
|
@ -632,6 +633,7 @@ void MachObj_term(const(char)* objfilename)
|
||||||
* indirect symbol table
|
* indirect symbol table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
auto version_command = VersionCommand(operatingSystemVersion);
|
||||||
uint foffset;
|
uint foffset;
|
||||||
uint headersize;
|
uint headersize;
|
||||||
uint sizeofcmds;
|
uint sizeofcmds;
|
||||||
|
@ -645,9 +647,10 @@ void MachObj_term(const(char)* objfilename)
|
||||||
header.cputype = CPU_TYPE_X86_64;
|
header.cputype = CPU_TYPE_X86_64;
|
||||||
header.cpusubtype = CPU_SUBTYPE_I386_ALL;
|
header.cpusubtype = CPU_SUBTYPE_I386_ALL;
|
||||||
header.filetype = MH_OBJECT;
|
header.filetype = MH_OBJECT;
|
||||||
header.ncmds = 3;
|
header.ncmds = 4;
|
||||||
header.sizeofcmds = cast(uint)(segment_command_64.sizeof +
|
header.sizeofcmds = cast(uint)(segment_command_64.sizeof +
|
||||||
(section_cnt - 1) * section_64.sizeof +
|
(section_cnt - 1) * section_64.sizeof +
|
||||||
|
version_command.size +
|
||||||
symtab_command.sizeof +
|
symtab_command.sizeof +
|
||||||
dysymtab_command.sizeof);
|
dysymtab_command.sizeof);
|
||||||
header.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
|
header.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
|
||||||
|
@ -669,9 +672,10 @@ void MachObj_term(const(char)* objfilename)
|
||||||
header.cputype = CPU_TYPE_I386;
|
header.cputype = CPU_TYPE_I386;
|
||||||
header.cpusubtype = CPU_SUBTYPE_I386_ALL;
|
header.cpusubtype = CPU_SUBTYPE_I386_ALL;
|
||||||
header.filetype = MH_OBJECT;
|
header.filetype = MH_OBJECT;
|
||||||
header.ncmds = 3;
|
header.ncmds = 4;
|
||||||
header.sizeofcmds = cast(uint)(segment_command.sizeof +
|
header.sizeofcmds = cast(uint)(segment_command.sizeof +
|
||||||
(section_cnt - 1) * section.sizeof +
|
(section_cnt - 1) * section.sizeof +
|
||||||
|
version_command.size +
|
||||||
symtab_command.sizeof +
|
symtab_command.sizeof +
|
||||||
dysymtab_command.sizeof);
|
dysymtab_command.sizeof);
|
||||||
header.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
|
header.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
|
||||||
|
@ -864,6 +868,8 @@ void MachObj_term(const(char)* objfilename)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put out relocation data
|
// 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();
|
mach_numbersyms();
|
||||||
for (int seg = 1; seg < SegData.length; seg++)
|
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;
|
rel.r_type = X86_64_RELOC_SIGNED;
|
||||||
else if ((s.Sfl == FLfunc || s.Sfl == FLextern || s.Sclass == SC.global ||
|
else if ((s.Sfl == FLfunc || s.Sfl == FLextern || s.Sclass == SC.global ||
|
||||||
s.Sclass == SC.comdat || s.Sclass == SC.comdef) && r.rtype == RELaddr)
|
s.Sclass == SC.comdat || s.Sclass == SC.comdef) && r.rtype == RELaddr)
|
||||||
{
|
rel.r_type = X86_64_RELOC_GOT;
|
||||||
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_address = cast(int)r.offset;
|
||||||
rel.r_symbolnum = s.Sxtrnnum;
|
rel.r_symbolnum = s.Sxtrnnum;
|
||||||
rel.r_pcrel = 1;
|
rel.r_pcrel = 1;
|
||||||
|
@ -1352,6 +1354,7 @@ void MachObj_term(const(char)* objfilename)
|
||||||
sym32.n_sect = sym.n_sect;
|
sym32.n_sect = sym.n_sect;
|
||||||
fobjbuf.write(&sym32, sym32.sizeof);
|
fobjbuf.write(&sym32, sym32.sizeof);
|
||||||
}
|
}
|
||||||
|
dysymtab_cmd.nundefsym++;
|
||||||
symtab_cmd.nsyms++;
|
symtab_cmd.nsyms++;
|
||||||
}
|
}
|
||||||
foffset += symtab_cmd.nsyms * (I64 ? nlist_64.sizeof : nlist.sizeof);
|
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(&segment_cmd, segment_cmd.sizeof);
|
||||||
fobjbuf.write(SECbuf.buf + section.sizeof, cast(uint)((section_cnt - 1) * section.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(&symtab_cmd, symtab_cmd.sizeof);
|
||||||
fobjbuf.write(&dysymtab_cmd, dysymtab_cmd.sizeof);
|
fobjbuf.write(&dysymtab_cmd, dysymtab_cmd.sizeof);
|
||||||
fobjbuf.position(foffset, 0);
|
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;
|
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 `...`");
|
error("function identifier-list cannot end with `...`");
|
||||||
ft.parameterList.varargs = AST.VarArg.KRvariadic; // but C11 allows extra arguments
|
ft.parameterList.varargs = AST.VarArg.KRvariadic; // but C11 allows extra arguments
|
||||||
auto plLength = pl.length;
|
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);
|
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[]
|
/* 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))
|
if (p.type || !(p.storageClass & STC.parameter))
|
||||||
error("storage class and type are not allowed in identifier-list");
|
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
|
foreach (s; (*symbols)[]) // yes, quadratic
|
||||||
{
|
{
|
||||||
auto ad = s.isAttribDeclaration();
|
auto ad = s.isAttribDeclaration();
|
||||||
|
|
|
@ -3787,7 +3787,7 @@ public:
|
||||||
if (v is v2 || !v.isOverlappedWith(v2))
|
if (v is v2 || !v.isOverlappedWith(v2))
|
||||||
continue;
|
continue;
|
||||||
auto e = (*sle.elements)[i];
|
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();
|
(*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 SourceEncoding { utf16, utf32}
|
||||||
enum Endian { little, big}
|
enum Endian { little, big}
|
||||||
|
immutable loc = mod.getLoc();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert a buffer from UTF32 to UTF8
|
* Convert a buffer from UTF32 to UTF8
|
||||||
|
@ -1413,7 +1414,7 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
||||||
|
|
||||||
if (buf.length & 3)
|
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);
|
mod.kind, mod.toPrettyChars, cast(ulong) buf.length);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1430,7 +1431,7 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
||||||
{
|
{
|
||||||
if (u > 0x10FFFF)
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
dbuf.writeUTF8(u);
|
dbuf.writeUTF8(u);
|
||||||
|
@ -1460,7 +1461,7 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
||||||
|
|
||||||
if (buf.length & 1)
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1480,13 +1481,13 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
||||||
i++;
|
i++;
|
||||||
if (i >= eBuf.length)
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
const u2 = readNext(&eBuf[i]);
|
const u2 = readNext(&eBuf[i]);
|
||||||
if (u2 < 0xDC00 || 0xE000 <= u2)
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
u = (u - 0xD7C0) << 10;
|
u = (u - 0xD7C0) << 10;
|
||||||
|
@ -1494,12 +1495,12 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
||||||
}
|
}
|
||||||
else if (u >= 0xDC00 && u <= 0xDFFF)
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
else if (u == 0xFFFE || u == 0xFFFF)
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
dbuf.writeUTF8(u);
|
dbuf.writeUTF8(u);
|
||||||
|
@ -1558,7 +1559,6 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
|
||||||
// It's UTF-8
|
// It's UTF-8
|
||||||
if (buf[0] >= 0x80)
|
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]);
|
.error(loc, "%s `%s` source file must start with BOM or ASCII character, not \\x%02X", mod.kind, mod.toPrettyChars, buf[0]);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12357,8 +12357,16 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||||
return result;
|
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())
|
if (auto ce = e.isCatExp())
|
||||||
{
|
{
|
||||||
Expression lowering = ce.lowering;
|
Expression lowering = ce.lowering;
|
||||||
|
@ -12388,8 +12396,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||||
arguments.push(new StringExp(exp.loc, funcname.toDString()));
|
arguments.push(new StringExp(exp.loc, funcname.toDString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCatArgument(arguments, exp.e1);
|
handleCatArgument(arguments, exp.e1, exp.type.toBasetype(), false);
|
||||||
handleCatArgument(arguments, exp.e2);
|
handleCatArgument(arguments, exp.e2, exp.type.toBasetype(), true);
|
||||||
|
|
||||||
Expression id = new IdentifierExp(exp.loc, Id.empty);
|
Expression id = new IdentifierExp(exp.loc, Id.empty);
|
||||||
id = new DotIdExp(exp.loc, id, Id.object);
|
id = new DotIdExp(exp.loc, id, Id.object);
|
||||||
|
|
|
@ -338,7 +338,7 @@ struct Segments
|
||||||
immutable(char*) sectionName;
|
immutable(char*) sectionName;
|
||||||
immutable(char*) segmentName;
|
immutable(char*) segmentName;
|
||||||
immutable int flags;
|
immutable int flags;
|
||||||
immutable int alignment;
|
immutable int p2align;
|
||||||
|
|
||||||
this(typeof(this.tupleof) tuple) @safe
|
this(typeof(this.tupleof) tuple) @safe
|
||||||
{
|
{
|
||||||
|
@ -388,7 +388,7 @@ struct Segments
|
||||||
return segments[id] = Obj.getsegment(
|
return segments[id] = Obj.getsegment(
|
||||||
seg.sectionName,
|
seg.sectionName,
|
||||||
seg.segmentName,
|
seg.segmentName,
|
||||||
seg.alignment,
|
seg.p2align,
|
||||||
seg.flags
|
seg.flags
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1159,7 +1159,7 @@ private:
|
||||||
const symbolName = prefix ~ classDeclaration.objc.identifier.toString();
|
const symbolName = prefix ~ classDeclaration.objc.identifier.toString();
|
||||||
auto symbol = Symbols.getStatic(symbolName);
|
auto symbol = Symbols.getStatic(symbolName);
|
||||||
symbol.Sseg = Segments[Segments.Id.const_];
|
symbol.Sseg = Segments[Segments.Id.const_];
|
||||||
symbol.Salignment = 3;
|
symbol.Salignment = 8;
|
||||||
symbol.Sdt = dtb.finish();
|
symbol.Sdt = dtb.finish();
|
||||||
|
|
||||||
return symbol;
|
return symbol;
|
||||||
|
@ -1311,7 +1311,7 @@ struct ProtocolDeclaration
|
||||||
symbol.Sseg = Segments[Segments.Id.protolist];
|
symbol.Sseg = Segments[Segments.Id.protolist];
|
||||||
symbol.Sclass = SC.comdat;
|
symbol.Sclass = SC.comdat;
|
||||||
symbol.Sflags |= SFLhidden;
|
symbol.Sflags |= SFLhidden;
|
||||||
symbol.Salignment = 3;
|
symbol.Salignment = 8;
|
||||||
|
|
||||||
auto dtb = DtBuilder(0);
|
auto dtb = DtBuilder(0);
|
||||||
dtb.xoff(protocol, 0);
|
dtb.xoff(protocol, 0);
|
||||||
|
@ -1326,7 +1326,7 @@ struct ProtocolDeclaration
|
||||||
symbol.Sseg = Segments[Segments.Id.data];
|
symbol.Sseg = Segments[Segments.Id.data];
|
||||||
symbol.Sclass = SC.comdat;
|
symbol.Sclass = SC.comdat;
|
||||||
symbol.Sflags |= SFLhidden;
|
symbol.Sflags |= SFLhidden;
|
||||||
symbol.Salignment = 3;
|
symbol.Salignment = 8;
|
||||||
|
|
||||||
auto dtb = DtBuilder(0);
|
auto dtb = DtBuilder(0);
|
||||||
toDt(dtb);
|
toDt(dtb);
|
||||||
|
@ -1478,7 +1478,7 @@ private:
|
||||||
|
|
||||||
symbol.Sdt = dtb.finish();
|
symbol.Sdt = dtb.finish();
|
||||||
symbol.Sseg = Segments[Segments.Id.const_];
|
symbol.Sseg = Segments[Segments.Id.const_];
|
||||||
symbol.Salignment = 3;
|
symbol.Salignment = 8;
|
||||||
|
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
@ -1512,7 +1512,7 @@ private:
|
||||||
|
|
||||||
symbol.Sdt = dtb.finish();
|
symbol.Sdt = dtb.finish();
|
||||||
symbol.Sseg = Segments[Segments.Id.const_];
|
symbol.Sseg = Segments[Segments.Id.const_];
|
||||||
symbol.Salignment = 3;
|
symbol.Salignment = 8;
|
||||||
|
|
||||||
outdata(symbol);
|
outdata(symbol);
|
||||||
|
|
||||||
|
@ -1546,7 +1546,7 @@ private:
|
||||||
|
|
||||||
symbol.Sdt = dtb.finish();
|
symbol.Sdt = dtb.finish();
|
||||||
symbol.Sseg = Segments[Segments.Id.const_];
|
symbol.Sseg = Segments[Segments.Id.const_];
|
||||||
symbol.Salignment = 3;
|
symbol.Salignment = 8;
|
||||||
|
|
||||||
outdata(symbol);
|
outdata(symbol);
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,11 @@ void Initializer_toDt(Initializer init, ref DtBuilder dtb, bool isCfile)
|
||||||
if (tb.ty == Tvector)
|
if (tb.ty == Tvector)
|
||||||
tb = (cast(TypeVector)tb).basetype;
|
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();
|
Type tn = tb.nextOf().toBasetype();
|
||||||
|
|
||||||
//printf("\tdim = %d\n", ai.dim);
|
//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
|
// 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;
|
import core.vararg;
|
||||||
|
|
||||||
extern(C++) class C1
|
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");
|
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.
|
* Thrown on a range error.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,7 +20,7 @@ ifeq ($(OS)-$(BUILD),dragonflybsd-debug)
|
||||||
LINE_TRACE_DFLAGS:=-L--export-dynamic
|
LINE_TRACE_DFLAGS:=-L--export-dynamic
|
||||||
endif
|
endif
|
||||||
ifeq ($(OS)-$(BUILD),osx-debug)
|
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:=
|
LINE_TRACE_DFLAGS:=
|
||||||
endif
|
endif
|
||||||
ifeq ($(OS)-$(BUILD),windows-debug)
|
ifeq ($(OS)-$(BUILD),windows-debug)
|
||||||
|
@ -42,7 +42,7 @@ $(ROOT)/line_trace.done: $(ROOT)/line_trace$(DOTEXE)
|
||||||
@echo Testing line_trace
|
@echo Testing line_trace
|
||||||
$(QUIET)$(TIMELIMIT)$(ROOT)/line_trace $(RUN_ARGS) > $(ROOT)/line_trace.output
|
$(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
|
# 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
|
@rm -f $(ROOT)/line_trace.output
|
||||||
@touch $@
|
@touch $@
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ $(ROOT)/line_trace_21656.done: $(ROOT)/line_trace$(DOTEXE)
|
||||||
@mkdir -p $(ROOT)/line_trace_21656
|
@mkdir -p $(ROOT)/line_trace_21656
|
||||||
@touch $(ROOT)/line_trace_21656/line_trace
|
@touch $(ROOT)/line_trace_21656/line_trace
|
||||||
$(QUIET)cd $(ROOT)/line_trace_21656 && PATH="..:$$PATH" $(TIMELIMIT)line_trace $(RUN_ARGS) > line_trace.output
|
$(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
|
@rm -rf $(ROOT)/line_trace_21656
|
||||||
@touch $@
|
@touch $@
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ $(ROOT)/long_backtrace_trunc.done: $(ROOT)/long_backtrace_trunc$(DOTEXE)
|
||||||
@echo Testing long_backtrace_trunc
|
@echo Testing long_backtrace_trunc
|
||||||
$(QUIET)$(TIMELIMIT)$(ROOT)/long_backtrace_trunc $(RUN_ARGS) > $(ROOT)/long_backtrace_trunc.output
|
$(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
|
# 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
|
@rm -f $(ROOT)/long_backtrace_trunc.output
|
||||||
@touch $@
|
@touch $@
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue