Merge remote-tracking branch 'upstream/stable' into merge_stable

This commit is contained in:
Iain Buclaw 2024-03-01 23:11:59 +00:00
commit 53cd4b7c30
24 changed files with 431 additions and 109 deletions

View file

@ -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

View file

@ -1 +1 @@
v2.107.1-rc.1 v2.107.1

View file

@ -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:

View file

@ -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()
{ {

View file

@ -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
}

View file

@ -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_LOAD;
if (seg == eh_frame_seg ||
seg == except_table_seg)
rel.r_type = X86_64_RELOC_GOT; 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_;
}

View file

@ -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();

View file

@ -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();
} }
} }

View file

@ -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;
} }

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -0,0 +1,9 @@
// REQUIRED_ARGS: -main
// LINK:
template rt_options()
{
__gshared string[] rt_options = [];
string[] rt_options_tls = [];
}
alias _ = rt_options!();

View 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();

View file

@ -0,0 +1,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail24422.c(7): Error: type-specifier missing for declaration of `a`
---
*/
void f24422(a) a; { }

View file

@ -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);
}

View 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);
}

View 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; }
}

View file

@ -0,0 +1,6 @@
// PERMUTE_ARGS:
// https://issues.dlang.org/show_bug.cgi?id=24401
int main()
{
return (() @trusted => 0)();
}

View 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}}

View 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"]);
}

View file

@ -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

View file

@ -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.
*/ */

View file

@ -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 $@