Skip to content

Commit

Permalink
Rebase stable6 (#16967)
Browse files Browse the repository at this point in the history
* Document template instance duplication status as part of its field documentation. (#16643)

* Fix Bugzilla 24599 - Wrongly elided TypeInfo emission (#15868)

Reverting #14844, which caused such missing TypeInfos, *and* making
sure the special TypeInfo members are fully analyzed and ready for
codegen (otherwise hitting an assertion for the real-world project).

* Reorganize backend build files to match target and make more similar per line (#16672)

* Remove redundant suggestions on linker errors (#16711)

* Fix bugzilla 24337 - Segfault when printing an int[] cast from a string (#16729)

* Add BitFieldStyle.Gcc_Clang_ARM

Required for 32-bit ARM, and non-Apple 64-bit ARM targets.

The only difference to `Gcc_Clang` is that anonymous and 0-length
bit-fields do contribute to the aggregate alignment.

Caught by existing proper C interop tests in
runnable_cxx/testbitfields.d on such targets. The hardcoded bad tests
in runnable/{bitfieldsposix64.c,dbitfieldsposix64.d} however now fail
after the fix, on such targets again.

* [refactor to `TargetC.contributesToAggregateAlignment(BitFieldDeclaration)` hook]

* Fix Bugzilla Issue 24687 - [REG2.110] Cannot cast string-imports to select overload anymore

* Also make deprecationSupplemental adhere to error limit (#16779)

Co-authored-by: Dennis Korpel <[email protected]>

* Fix bugzilla 24699 - [REG2.108] No short-circuit evaluation of mixing template bool argument

* Fix bugzilla 24731 - IFTI cannot handle integer expressions (#16822)

* Fix Bugzilla Issue 24760 - ICE on variadic after default argument

* Fix bugzilla 24790 - -vcg-ast ICE on lowered assign exp (#16914)

Co-authored-by: Dennis Korpel <[email protected]>

* Fix bugzilla 24764 - ICE when -vcg-ast prints imported invariant (#16917)

Co-authored-by: Dennis Korpel <[email protected]>

* Fix bugzilla 24431 - dmd -vcg-ast crashes printing failed template in… (#16916)

---------

Co-authored-by: Richard (Rikki) Andrew Cattermole <[email protected]>
Co-authored-by: Martin Kinkelin <[email protected]>
Co-authored-by: Dennis <[email protected]>
Co-authored-by: Martin Kinkelin <[email protected]>
Co-authored-by: Martin Kinkelin <[email protected]>
Co-authored-by: RazvanN7 <[email protected]>
Co-authored-by: Dennis Korpel <[email protected]>
Co-authored-by: Dennis Korpel <[email protected]>
  • Loading branch information
9 people authored Oct 7, 2024
1 parent 4c02e46 commit 57c5b07
Show file tree
Hide file tree
Showing 35 changed files with 359 additions and 146 deletions.
27 changes: 16 additions & 11 deletions compiler/src/build.d
Original file line number Diff line number Diff line change
Expand Up @@ -1581,10 +1581,12 @@ auto sourceFiles()
cparse.d
"),
backendHeaders: fileArray(env["C"], "
cc.d cdef.d cgcv.d code.d cv4.d dt.d el.d global.d
obj.d oper.d rtlsym.d x86/code_x86.d iasm.d codebuilder.d
ty.d type.d mach.d mscoff.d dwarf.d dwarf2.d x86/xmm.d
dlist.d melf.d
cc.d cdef.d cgcv.d code.d dt.d el.d global.d
obj.d oper.d rtlsym.d iasm.d codebuilder.d
ty.d type.d dlist.d
dwarf.d dwarf2.d cv4.d
melf.d mscoff.d mach.d
x86/code_x86.d x86/xmm.d
"),
};
foreach (member; __traits(allMembers, DmdSources))
Expand Down Expand Up @@ -1620,13 +1622,16 @@ auto sourceFiles()
"),
backend: fileArray(env["C"], "
bcomplex.d evalu8.d divcoeff.d dvec.d go.d gsroa.d glocal.d gdag.d gother.d gflow.d
dout.d inliner.d
gloop.d cgelem.d cgcs.d ee.d x86/cod4.d x86/cod5.d eh.d x86/nteh.d blockopt.d mem.d cg.d x86/cgreg.d
dtype.d debugprint.d fp.d symbol.d symtab.d elem.d dcode.d cgsched.d x86/cg87.d x86/cgxmm.d x86/cgcod.d x86/cod1.d x86/cod2.d
x86/cod3.d cv8.d dcgcv.d pdata.d util2.d var.d backconfig.d drtlsym.d dwarfeh.d ptrntab.d
dvarstats.d dwarfdbginf.d cgen.d goh.d barray.d cgcse.d elpicpie.d
machobj.d elfobj.d mscoffobj.d filespec.d aarray.d x86/disasm86.d arm/disasmarm.d arm/instr.d
arm/cod1.d arm/cod2.d arm/cod3.d arm/cod4.d
dout.d inliner.d eh.d filespec.d aarray.d
gloop.d cgelem.d cgcs.d ee.d blockopt.d mem.d cg.d
dtype.d debugprint.d fp.d symbol.d symtab.d elem.d dcode.d cgsched.d
pdata.d util2.d var.d backconfig.d drtlsym.d ptrntab.d
dvarstats.d cgen.d goh.d barray.d cgcse.d elpicpie.d
dwarfeh.d dwarfdbginf.d cv8.d dcgcv.d
machobj.d elfobj.d mscoffobj.d
x86/nteh.d x86/cgreg.d x86/cg87.d x86/cgxmm.d x86/disasm86.d
x86/cgcod.d x86/cod1.d x86/cod2.d x86/cod3.d x86/cod4.d x86/cod5.d
arm/disasmarm.d arm/instr.d arm/cod1.d arm/cod2.d arm/cod3.d arm/cod4.d
"
),
};
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dmd/dcast.d
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ MATCH implicitConvTo(Expression e, Type t)
return MATCH.nomatch;
m = MATCH.constant;
}
if (e.hexString && tn.isIntegral && (tn.size == e.sz || (!e.committed && (e.len % tn.size) == 0)))
if (e.type != t && e.hexString && tn.isIntegral && (tn.size == e.sz || (!e.committed && (e.len % tn.size) == 0)))
{
m = MATCH.convert;
return m;
Expand Down
80 changes: 34 additions & 46 deletions compiler/src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -1832,7 +1832,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
//printf("MixinDeclaration::compileIt(loc = %d) %s\n", cd.loc.linnum, cd.exp.toChars());
OutBuffer buf;
if (expressionsToString(buf, sc, cd.exps))
if (expressionsToString(buf, sc, cd.exps, cd.loc, null, true))
return null;

const errors = global.errors;
Expand Down Expand Up @@ -7113,12 +7113,19 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
error(bfd.loc, "bit field width %d is larger than type", bfd.fieldWidth);

const style = target.c.bitFieldStyle;
if (style != TargetC.BitFieldStyle.MS && style != TargetC.BitFieldStyle.Gcc_Clang)
assert(0, "unsupported bit-field style");

const isMicrosoftStyle = style == TargetC.BitFieldStyle.MS;
const contributesToAggregateAlignment = target.c.contributesToAggregateAlignment(bfd);

void startNewField()
{
if (log) printf("startNewField()\n");
uint alignsize;
if (style == TargetC.BitFieldStyle.Gcc_Clang)
if (isMicrosoftStyle)
alignsize = memsize; // not memalignsize
else
{
if (bfd.fieldWidth > 32)
alignsize = memalignsize;
Expand All @@ -7129,15 +7136,13 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
else
alignsize = 1;
}
else
alignsize = memsize; // not memalignsize

uint dummy;
bfd.offset = placeField(bfd.loc,
fieldState.offset,
memsize, alignsize, bfd.alignment,
ad.structsize,
(anon && style == TargetC.BitFieldStyle.Gcc_Clang) ? dummy : ad.alignsize,
contributesToAggregateAlignment ? ad.alignsize : dummy,
isunion);

fieldState.inFlight = true;
Expand All @@ -7146,53 +7151,38 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
fieldState.fieldSize = memsize;
}

if (style == TargetC.BitFieldStyle.Gcc_Clang)
if (ad.alignsize == 0)
ad.alignsize = 1;
if (!isMicrosoftStyle && contributesToAggregateAlignment && ad.alignsize < memalignsize)
ad.alignsize = memalignsize;

if (bfd.fieldWidth == 0)
{
if (bfd.fieldWidth == 0)
if (!isMicrosoftStyle && !isunion)
{
if (!isunion)
{
// Use type of zero width field to align to next field
fieldState.offset = (fieldState.offset + memalignsize - 1) & ~(memalignsize - 1);
ad.structsize = fieldState.offset;
}

fieldState.inFlight = false;
return;
// Use type of zero width field to align to next field
fieldState.offset = (fieldState.offset + memalignsize - 1) & ~(memalignsize - 1);
ad.structsize = fieldState.offset;
}

if (ad.alignsize == 0)
ad.alignsize = 1;
if (!anon &&
ad.alignsize < memalignsize)
ad.alignsize = memalignsize;
}
else if (style == TargetC.BitFieldStyle.MS)
{
if (ad.alignsize == 0)
ad.alignsize = 1;
if (bfd.fieldWidth == 0)
else if (isMicrosoftStyle && fieldState.inFlight && !isunion)
{
if (fieldState.inFlight && !isunion)
{
// documentation says align to next int
//const alsz = cast(uint)Type.tint32.size();
const alsz = memsize; // but it really does this
fieldState.offset = (fieldState.offset + alsz - 1) & ~(alsz - 1);
ad.structsize = fieldState.offset;
}

fieldState.inFlight = false;
return;
// documentation says align to next int
//const alsz = cast(uint)Type.tint32.size();
const alsz = memsize; // but it really does this
fieldState.offset = (fieldState.offset + alsz - 1) & ~(alsz - 1);
ad.structsize = fieldState.offset;
}

fieldState.inFlight = false;
return;
}

if (!fieldState.inFlight)
{
//printf("not in flight\n");
startNewField();
}
else if (style == TargetC.BitFieldStyle.Gcc_Clang)
else if (!isMicrosoftStyle)
{
// If the bit-field spans more units of alignment than its type
// and is at the alignment boundary, start a new field at the
Expand All @@ -7217,7 +7207,7 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
}
}
}
else if (style == TargetC.BitFieldStyle.MS)
else
{
if (memsize != fieldState.fieldSize ||
fieldState.bitOffset + bfd.fieldWidth > fieldState.fieldSize * 8)
Expand All @@ -7226,14 +7216,14 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
startNewField();
}
}
else
assert(0);

bfd.offset = fieldState.fieldOffset;
bfd.bitOffset = fieldState.bitOffset;

const pastField = bfd.bitOffset + bfd.fieldWidth;
if (style == TargetC.BitFieldStyle.Gcc_Clang)
if (isMicrosoftStyle)
fieldState.fieldSize = memsize;
else
{
auto size = (pastField + 7) / 8;
fieldState.fieldSize = size;
Expand All @@ -7247,8 +7237,6 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
else
ad.structsize = bfd.offset + size;
}
else
fieldState.fieldSize = memsize;
//printf("at end: ad.structsize = %d\n", cast(int)ad.structsize);
//print(fieldState);

Expand Down
35 changes: 32 additions & 3 deletions compiler/src/dmd/dtemplate.d
Original file line number Diff line number Diff line change
Expand Up @@ -1695,7 +1695,9 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, ref TemplateParameters pa
edim = s ? getValue(s) : getValue(e);
}
}
if (tp && tp.matchArg(sc, t.dim, i, &parameters, dedtypes, null) || edim && edim.toInteger() == t.dim.toInteger())
if ((tp && tp.matchArg(sc, t.dim, i, &parameters, dedtypes, null)) ||
(edim && edim.isIntegerExp() && edim.toInteger() == t.dim.toInteger())
)
{
result = deduceType(t.next, sc, tparam.nextOf(), parameters, dedtypes, wm);
return;
Expand Down Expand Up @@ -3653,7 +3655,22 @@ extern (C++) class TemplateInstance : ScopeDsymbol
Dsymbol tempdecl; // referenced by foo.bar.abc
Dsymbol enclosing; // if referencing local symbols, this is the context
Dsymbol aliasdecl; // !=null if instance is an alias for its sole member
TemplateInstance inst; // refer to existing instance

/**
If this is not null and it has a value that is not the current object,
then this field points to an existing template instance
and that object has been duplicated into us.

If this object is a duplicate,
the ``memberOf`` field will be set to a root module (passed on CLI).

This information is useful to deduplicate analysis that may occur
after semantic 3 has completed.

See_Also: memberOf
*/
TemplateInstance inst;

ScopeDsymbol argsym; // argument symbol table
size_t hash; // cached result of toHash()

Expand All @@ -3665,7 +3682,15 @@ extern (C++) class TemplateInstance : ScopeDsymbol

TemplateInstances* deferred;

Module memberOf; // if !null, then this TemplateInstance appears in memberOf.members[]
/**
If this is not null then this template instance appears in a root module's members.

Note: This is not useful for determining duplication status of this template instance.
Use the field ``inst`` for determining if a template instance has been duplicated into this object.

See_Also: inst
*/
Module memberOf;

// Used to determine the instance needs code generation.
// Note that these are inaccurate until semantic analysis phase completed.
Expand Down Expand Up @@ -4482,9 +4507,13 @@ extern (C++) class TemplateInstance : ScopeDsymbol

// The arguments are not treated as part of a default argument,
// because they are evaluated at compile time.
const inCondition = sc.condition;
sc = sc.push();
sc.inDefaultArg = false;

// https://issues.dlang.org/show_bug.cgi?id=24699
sc.condition = inCondition;

for (size_t j = 0; j < tiargs.length; j++)
{
RootObject o = (*tiargs)[j];
Expand Down
7 changes: 5 additions & 2 deletions compiler/src/dmd/errors.d
Original file line number Diff line number Diff line change
Expand Up @@ -570,8 +570,11 @@ extern (C++) void verrorReportSupplemental(const ref Loc loc, const(char)* forma
goto case ErrorKind.error;
else if (global.params.useDeprecated == DiagnosticReporting.inform && !global.gag)
{
info.headerColor = Classification.deprecation;
verrorPrint(format, ap, info);
if (global.params.v.errorLimit == 0 || global.deprecations <= global.params.v.errorLimit)
{
info.headerColor = Classification.deprecation;
verrorPrint(format, ap, info);
}
}
break;

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dmd/expression.d
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ extern (C++) abstract class Expression : ASTNode
dinteger_t toInteger()
{
//printf("Expression %s\n", EXPtoString(op).ptr);
if (!type.isTypeError())
if (!type || !type.isTypeError())
error(loc, "integer constant expression expected instead of `%s`", toChars());
return 0;
}
Expand Down
48 changes: 26 additions & 22 deletions compiler/src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,26 @@ private bool isNeedThisScope(Scope* sc, Declaration d)
* buf = append generated string to buffer
* sc = context
* exps = array of Expressions
* loc = location of the pragma / mixin where this conversion was requested, for supplemental error
* fmt = format string for supplemental error. May contain 1 `%s` which prints the faulty expression
* expandTuples = whether tuples should be expanded rather than printed as tuple syntax
* Returns:
* true on error
*/
bool expressionsToString(ref OutBuffer buf, Scope* sc, Expressions* exps)
bool expressionsToString(ref OutBuffer buf, Scope* sc, Expressions* exps,
Loc loc, const(char)* fmt, bool expandTuples)
{
if (!exps)
return false;

foreach (ex; *exps)
{
bool error()
{
if (loc != Loc.initial && fmt)
errorSupplemental(loc, fmt, ex.toChars());
return true;
}
if (!ex)
continue;
auto sc2 = sc.startCTFE();
Expand All @@ -162,15 +172,16 @@ bool expressionsToString(ref OutBuffer buf, Scope* sc, Expressions* exps)
// allowed to contain types as well as expressions
auto e4 = ctfeInterpretForPragmaMsg(e3);
if (!e4 || e4.op == EXP.error)
return true;
return error();

// expand tuple
if (auto te = e4.isTupleExp())
{
if (expressionsToString(buf, sc, te.exps))
return true;
continue;
}
if (expandTuples)
if (auto te = e4.isTupleExp())
{
if (expressionsToString(buf, sc, te.exps, loc, fmt, true))
return error();
continue;
}
// char literals exp `.toStringExp` return `null` but we cant override it
// because in most contexts we don't want the conversion to succeed.
IntegerExp ie = e4.isIntegerExp();
Expand All @@ -181,9 +192,11 @@ bool expressionsToString(ref OutBuffer buf, Scope* sc, Expressions* exps)
e4 = new ArrayLiteralExp(ex.loc, tsa, ie);
}

if (StringExp se = e4.toStringExp())
StringExp se = e4.toStringExp();

if (se && se.type.nextOf().ty.isSomeChar)
buf.writestring(se.toUTF8(sc).peekString());
else
else if (!(se && se.len == 0)) // don't print empty array literal `[]`
buf.writestring(e4.toString());
}
return false;
Expand Down Expand Up @@ -336,6 +349,7 @@ StringExp toUTF8(StringExp se, Scope* sc)
Expression e = castTo(se, sc, Type.tchar.arrayOf());
e = e.optimize(WANTvalue);
auto result = e.isStringExp();
assert(result);
assert(result.sz == 1);
return result;
}
Expand Down Expand Up @@ -7194,17 +7208,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// Handle this in the glue layer
Expression e = new TypeidExp(exp.loc, ta);

bool genObjCode = true;

// https://issues.dlang.org/show_bug.cgi?id=23650
// We generate object code for typeinfo, required
// by typeid, only if in non-speculative context
if (sc.traitsCompiles)
{
genObjCode = false;
}

e.type = getTypeInfoType(exp.loc, ta, sc, genObjCode);
e.type = getTypeInfoType(exp.loc, ta, sc);
semanticTypeInfo(sc, ta);

if (ea)
Expand Down Expand Up @@ -7704,7 +7708,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
private Expression compileIt(MixinExp exp, Scope *sc)
{
OutBuffer buf;
if (expressionsToString(buf, sc, exp.exps))
if (expressionsToString(buf, sc, exp.exps, exp.loc, null, true))
return null;

uint errors = global.errors;
Expand Down
Loading

0 comments on commit 57c5b07

Please sign in to comment.