From 6a8ce7c32a5dddc28d155cc171442c4ba2f15416 Mon Sep 17 00:00:00 2001 From: "Richard (Rikki) Andrew Cattermole" Date: Tue, 2 Jul 2024 12:34:27 +1200 Subject: [PATCH 01/23] Document template instance duplication status as part of its field documentation. (#16643) --- compiler/src/dmd/dtemplate.d | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/compiler/src/dmd/dtemplate.d b/compiler/src/dmd/dtemplate.d index 8fcbbad2f7..0881acf18d 100644 --- a/compiler/src/dmd/dtemplate.d +++ b/compiler/src/dmd/dtemplate.d @@ -3699,7 +3699,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() @@ -3711,7 +3726,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. From 7ab98b931aa1fe40ae3bae73ab3a64a44bb1c696 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Tue, 2 Jul 2024 19:31:34 +0200 Subject: [PATCH 02/23] 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). --- compiler/src/dmd/expressionsem.d | 12 +----------- compiler/src/dmd/frontend.h | 2 +- compiler/src/dmd/todt.d | 7 +++++++ compiler/src/dmd/typinf.d | 5 ++--- compiler/src/dmd/typinf.h | 2 +- compiler/src/tests/cxxfrontend.cc | 2 +- compiler/test/runnable/test23650.d | 13 ------------- compiler/test/runnable/test24599.d | 24 ++++++++++++++++++++++++ 8 files changed, 37 insertions(+), 30 deletions(-) delete mode 100644 compiler/test/runnable/test23650.d create mode 100644 compiler/test/runnable/test24599.d diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index a69b64d6b7..126db177d2 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -7091,17 +7091,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // Handle this in the glue layer 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.flags & SCOPE.compile) - { - genObjCode = false; - } - - e.type = getTypeInfoType(exp.loc, ta, sc, genObjCode); + e.type = getTypeInfoType(exp.loc, ta, sc); semanticTypeInfo(sc, ta); if (ea) diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index 355913ce0f..b3baffb830 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -7628,7 +7628,7 @@ public: extern Target target; -extern Type* getTypeInfoType(const Loc& loc, Type* t, Scope* sc, bool genObjCode = true); +extern Type* getTypeInfoType(const Loc& loc, Type* t, Scope* sc); class SemanticTimeTransitiveVisitor : public SemanticTimePermissiveVisitor { diff --git a/compiler/src/dmd/todt.d b/compiler/src/dmd/todt.d index a79c261416..06bbc314b9 100644 --- a/compiler/src/dmd/todt.d +++ b/compiler/src/dmd/todt.d @@ -1443,6 +1443,13 @@ private extern (C++) class TypeInfoDtVisitor : Visitor /* ti.toObjFile() won't get called. So, store these * member functions into object file in here. */ + + if (sd.semanticRun < PASS.semantic3done) + { + import dmd.semantic3 : semanticTypeInfoMembers; + semanticTypeInfoMembers(sd); + } + if (sd.xeq && sd.xeq != StructDeclaration.xerreq) toObjFile(sd.xeq, global.params.multiobj); if (sd.xcmp && sd.xcmp != StructDeclaration.xerrcmp) diff --git a/compiler/src/dmd/typinf.d b/compiler/src/dmd/typinf.d index 3314e2f004..6a265ecd3d 100644 --- a/compiler/src/dmd/typinf.d +++ b/compiler/src/dmd/typinf.d @@ -100,14 +100,13 @@ bool genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc) * loc = the location for reporting line nunbers in errors * t = the type to get the type of the `TypeInfo` object for * sc = the scope - * genObjCode = if true, object code will be generated for the obtained TypeInfo * Returns: * The type of the `TypeInfo` object associated with `t` */ -extern (C++) Type getTypeInfoType(const ref Loc loc, Type t, Scope* sc, bool genObjCode = true) +extern (C++) Type getTypeInfoType(const ref Loc loc, Type t, Scope* sc) { assert(t.ty != Terror); - if (genTypeInfo(null, loc, t, sc) && genObjCode) + if (genTypeInfo(null, loc, t, sc)) { // Find module that will go all the way to an object file Module m = sc._module.importedFrom; diff --git a/compiler/src/dmd/typinf.h b/compiler/src/dmd/typinf.h index dd9572aab4..6414ecdd36 100644 --- a/compiler/src/dmd/typinf.h +++ b/compiler/src/dmd/typinf.h @@ -22,4 +22,4 @@ namespace dmd bool isSpeculativeType(Type *t); bool builtinTypeInfo(Type *t); } -Type *getTypeInfoType(const Loc &loc, Type *t, Scope *sc, bool genObjCode = true); +Type *getTypeInfoType(const Loc &loc, Type *t, Scope *sc); diff --git a/compiler/src/tests/cxxfrontend.cc b/compiler/src/tests/cxxfrontend.cc index be9d269b8e..bc0c305c8e 100644 --- a/compiler/src/tests/cxxfrontend.cc +++ b/compiler/src/tests/cxxfrontend.cc @@ -1865,7 +1865,7 @@ void template_h(TemplateParameter *tp, Scope *sc, TemplateParameters *tps, void typinf_h(Expression *e, const Loc &loc, Type *t, Scope *sc) { dmd::genTypeInfo(e, loc, t, sc); - ::getTypeInfoType(loc, t, sc, false); + ::getTypeInfoType(loc, t, sc); dmd::isSpeculativeType(t); dmd::builtinTypeInfo(t); } diff --git a/compiler/test/runnable/test23650.d b/compiler/test/runnable/test23650.d deleted file mode 100644 index 3ce8f5f075..0000000000 --- a/compiler/test/runnable/test23650.d +++ /dev/null @@ -1,13 +0,0 @@ -// https://issues.dlang.org/show_bug.cgi?id=23650 - -__gshared int x; - -void main() -{ - - static assert(__traits(compiles, - { - struct S { int *p = &x; } - auto t = typeid(S); - })); -} diff --git a/compiler/test/runnable/test24599.d b/compiler/test/runnable/test24599.d new file mode 100644 index 0000000000..257773846e --- /dev/null +++ b/compiler/test/runnable/test24599.d @@ -0,0 +1,24 @@ +module mod; + +struct Variable +{ + size_t toHash() const { return 0; } +} + +enum hasInoutConstruction(T) = __traits(compiles, { struct S { T a; } }); + +struct Algebraic(T) +{ + static if (hasInoutConstruction!T) + { + } +} + +Algebraic!Variable foo(); + +struct S +{ + Variable[] symbols; +} + +void main() {} From 48a88837b8abf6426b3cbc7a2dce81eea77c4abe Mon Sep 17 00:00:00 2001 From: "Richard (Rikki) Andrew Cattermole" Date: Mon, 8 Jul 2024 14:00:50 +1200 Subject: [PATCH 03/23] Reorganize backend build files to match target and make more similar per line (#16672) --- compiler/src/build.d | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/compiler/src/build.d b/compiler/src/build.d index e4f5a5eb26..2e022e85b9 100755 --- a/compiler/src/build.d +++ b/compiler/src/build.d @@ -1578,10 +1578,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)) @@ -1617,12 +1619,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 compress.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 cgobj.d aarray.d x86/disasm86.d arm/disasmarm.d + dout.d inliner.d eh.d filespec.d cgobj.d aarray.d + gloop.d compress.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 " ), }; From 463687203362ab15fd5dffd3faf3a2217e549e85 Mon Sep 17 00:00:00 2001 From: Dennis Date: Tue, 16 Jul 2024 13:22:02 +0200 Subject: [PATCH 04/23] Remove redundant suggestions on linker errors (#16711) --- compiler/src/dmd/link.d | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/src/dmd/link.d b/compiler/src/dmd/link.d index 7ac403ba94..0be1461236 100644 --- a/compiler/src/dmd/link.d +++ b/compiler/src/dmd/link.d @@ -1426,8 +1426,8 @@ void parseLinkerOutput(const(char)[] linkerOutput, ErrorSink eSink) return s; } - bool missingSymbols = false; - bool missingDfunction = false; + bool missingCSymbols = false; + bool missingDsymbols = false; bool missingMain = false; void missingSymbol(const(char)[] name, const(char)[] referencedFrom) @@ -1437,11 +1437,12 @@ void parseLinkerOutput(const(char)[] linkerOutput, ErrorSink eSink) name = name[1 .. $]; // MS LINK prepends underscore to the existing one auto sym = demangle(name); - missingSymbols = true; if (sym == "main") missingMain = true; - if (sym != name) - missingDfunction = true; + else if (sym != name) + missingDsymbols = true; + else + missingCSymbols = true; eSink.error(Loc.initial, "undefined reference to `%.*s`", cast(int) sym.length, sym.ptr); if (referencedFrom.length > 0) @@ -1513,10 +1514,9 @@ void parseLinkerOutput(const(char)[] linkerOutput, ErrorSink eSink) if (missingMain) eSink.errorSupplemental(Loc.initial, "perhaps define a `void main() {}` function or use the `-main` switch"); - - if (missingDfunction) + else if (missingDsymbols) eSink.errorSupplemental(Loc.initial, "perhaps `.d` files need to be added on the command line, or use `-i` to compile imports"); - else if (missingSymbols) + else if (missingCSymbols) eSink.errorSupplemental(Loc.initial, "perhaps a library needs to be added with the `-L` flag or `pragma(lib, ...)`"); } From cf618a659c92a0a6fcbc9079af29c72a8af27b76 Mon Sep 17 00:00:00 2001 From: Dennis Date: Mon, 22 Jul 2024 10:00:31 +0200 Subject: [PATCH 05/23] Fix bugzilla 24337 - Segfault when printing an int[] cast from a string (#16729) --- compiler/src/dmd/dsymbolsem.d | 2 +- compiler/src/dmd/expressionsem.d | 36 ++++++++++++++++-------- compiler/src/dmd/pragmasem.d | 29 ++++++------------- compiler/src/dmd/statementsem.d | 2 +- compiler/src/dmd/typesem.d | 2 +- compiler/test/compilable/staticforeach.d | 4 +-- compiler/test/compilable/test24337.d | 11 ++++++++ compiler/test/runnable/test13613.d | 2 +- 8 files changed, 50 insertions(+), 38 deletions(-) create mode 100644 compiler/test/compilable/test24337.d diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index e32f5fa221..f9c524fd85 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -1788,7 +1788,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; diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 126db177d2..5cf0cbb4cb 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -137,16 +137,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(); @@ -159,15 +169,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(); @@ -178,9 +189,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; @@ -333,6 +346,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; } @@ -7598,7 +7612,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; diff --git a/compiler/src/dmd/pragmasem.d b/compiler/src/dmd/pragmasem.d index 4dceb595e5..3a455fb3d1 100644 --- a/compiler/src/dmd/pragmasem.d +++ b/compiler/src/dmd/pragmasem.d @@ -557,32 +557,19 @@ private uint setMangleOverride(Dsymbol s, const(char)[] sym) private bool pragmaMsgSemantic(Loc loc, Scope* sc, Expressions* args) { import dmd.tokens; + import dmd.common.outbuffer; if (!args) return true; - foreach (arg; *args) - { - sc = sc.startCTFE(); - auto e = arg.expressionSemantic(sc); - e = resolveProperties(sc, e); - sc = sc.endCTFE(); - // pragma(msg) is allowed to contain types as well as expressions - e = ctfeInterpretForPragmaMsg(e); - if (e.op == EXP.error) - { - errorSupplemental(loc, "while evaluating `pragma(msg, %s)`", arg.toChars()); - return false; - } - if (auto se = e.toStringExp()) - { - const slice = se.toUTF8(sc).peekString(); - fprintf(stderr, "%.*s", cast(int)slice.length, slice.ptr); - } - else - fprintf(stderr, "%s", e.toChars()); + OutBuffer buf; + if (expressionsToString(buf, sc, args, loc, "while evaluating `pragma(msg, %s)`", false)) + return false; + else + { + buf.writestring("\n"); + fprintf(stderr, buf.extractChars); } - fprintf(stderr, "\n"); return true; } diff --git a/compiler/src/dmd/statementsem.d b/compiler/src/dmd/statementsem.d index c5c8a12593..0390892efe 100644 --- a/compiler/src/dmd/statementsem.d +++ b/compiler/src/dmd/statementsem.d @@ -4803,7 +4803,7 @@ private Statements* flatten(Statement statement, Scope* sc) OutBuffer buf; - if (expressionsToString(buf, sc, cs.exps)) + if (expressionsToString(buf, sc, cs.exps, cs.loc, null, true)) return errorStatements(); const errors = global.errors; diff --git a/compiler/src/dmd/typesem.d b/compiler/src/dmd/typesem.d index 33d825a2b8..a909fcf14c 100644 --- a/compiler/src/dmd/typesem.d +++ b/compiler/src/dmd/typesem.d @@ -7449,7 +7449,7 @@ Expression getMaxMinValue(EnumDeclaration ed, const ref Loc loc, Identifier id) RootObject compileTypeMixin(TypeMixin tm, ref const Loc loc, Scope* sc) { OutBuffer buf; - if (expressionsToString(buf, sc, tm.exps)) + if (expressionsToString(buf, sc, tm.exps, tm.loc, null, true)) return null; const errors = global.errors; diff --git a/compiler/test/compilable/staticforeach.d b/compiler/test/compilable/staticforeach.d index ce9eb74a1e..5b23446f89 100644 --- a/compiler/test/compilable/staticforeach.d +++ b/compiler/test/compilable/staticforeach.d @@ -117,8 +117,8 @@ foo2 T2 TestStaticForeach2 issue22007 -1 2 '3' -2 3 '4' +1 2 3 +2 3 4 0 1 1 2 2 3 diff --git a/compiler/test/compilable/test24337.d b/compiler/test/compilable/test24337.d new file mode 100644 index 0000000000..a31f665f35 --- /dev/null +++ b/compiler/test/compilable/test24337.d @@ -0,0 +1,11 @@ +/* +TEST_OUTPUT: +--- +"ab"w x"11223344556677" +--- +*/ +// https://issues.dlang.org/show_bug.cgi?id=24337 + +immutable ushort[] y = cast(immutable ushort[]) "ab"w; +immutable ulong[] z = x"00 11 22 33 44 55 66 77"; +pragma(msg, y, " ", z); diff --git a/compiler/test/runnable/test13613.d b/compiler/test/runnable/test13613.d index ea57df4e91..1382f00a17 100644 --- a/compiler/test/runnable/test13613.d +++ b/compiler/test/runnable/test13613.d @@ -4,9 +4,9 @@ /* TEST_OUTPUT: --- -CT x.offsetof = < CT y.offsetof = < 0 > y +CT x.offsetof = < 0 > x --- */ From 76a48f3dac4cfa714f00689ee097a670fc878100 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Sun, 21 Jul 2024 16:33:56 +0200 Subject: [PATCH 06/23] 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. --- compiler/src/dmd/dsymbolsem.d | 86 ++++++++++++++++------------------- compiler/src/dmd/frontend.h | 1 + compiler/src/dmd/target.d | 3 ++ compiler/src/dmd/target.h | 3 ++ compiler/src/dmd/todt.d | 1 + 5 files changed, 47 insertions(+), 47 deletions(-) diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index f9c524fd85..2e8240bbb8 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -7186,12 +7186,23 @@ 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 && + style != TargetC.BitFieldStyle.Gcc_Clang_ARM) + { + assert(0, "unsupported bit-field style"); + } + + const isMicrosoftStyle = style == TargetC.BitFieldStyle.MS; + const contributesToAggregateAlignment = !anon || style != TargetC.BitFieldStyle.Gcc_Clang; 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; @@ -7202,15 +7213,13 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor else alignsize = 1; } - else - alignsize = memsize; // not memalignsize uint dummy; bfd.offset = placeField( 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; @@ -7219,45 +7228,30 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor fieldState.fieldSize = memsize; } - if (style == TargetC.BitFieldStyle.Gcc_Clang) - { - if (bfd.fieldWidth == 0) - { - 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; - } + if (ad.alignsize == 0) + ad.alignsize = 1; + if (!isMicrosoftStyle && contributesToAggregateAlignment && ad.alignsize < memalignsize) + ad.alignsize = memalignsize; - fieldState.inFlight = false; - return; + if (bfd.fieldWidth == 0) + { + if (!isMicrosoftStyle && !isunion) + { + // Use type of zero width field to align to next field + fieldState.offset = (fieldState.offset + memalignsize - 1) & ~(memalignsize - 1); + ad.structsize = fieldState.offset; + } + else if (isMicrosoftStyle && 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; } - 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) - { - 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; - } + fieldState.inFlight = false; + return; } if (!fieldState.inFlight) @@ -7265,7 +7259,7 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor //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, // start a new field at the next alignment boundary. @@ -7288,7 +7282,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) @@ -7297,14 +7291,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; @@ -7318,8 +7312,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); diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index b3baffb830..b91fb1ffd9 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -5938,6 +5938,7 @@ struct TargetC final Unspecified = 0u, MS = 1u, Gcc_Clang = 2u, + Gcc_Clang_ARM = 3u, }; bool crtDestructorsSupported; diff --git a/compiler/src/dmd/target.d b/compiler/src/dmd/target.d index 797ff5bead..41843a3145 100644 --- a/compiler/src/dmd/target.d +++ b/compiler/src/dmd/target.d @@ -1379,6 +1379,9 @@ struct TargetC /// https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160 /// https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160 Gcc_Clang, /// gcc and clang + Gcc_Clang_ARM, /// Like `Gcc_Clang`, except that anonymous and 0-length bit fields contribute + /// to the aggregate alignment. Used for 32 & 64 bit ARM targets, except for + /// Apple ARM64. } bool crtDestructorsSupported = true; /// Not all platforms support crt_destructor ubyte boolsize; /// size of a C `_Bool` type diff --git a/compiler/src/dmd/target.h b/compiler/src/dmd/target.h index a380bb8bbe..4f57b6fa3f 100644 --- a/compiler/src/dmd/target.h +++ b/compiler/src/dmd/target.h @@ -65,6 +65,9 @@ struct TargetC // https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160 // https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160 Gcc_Clang, // gcc and clang + Gcc_Clang_ARM, // Like `Gcc_Clang`, except that anonymous and 0-length bit fields contribute + // to the aggregate alignment. Used for 32 & 64 bit ARM targets, except for + // Apple ARM64. }; uint8_t crtDestructorsSupported; // Not all platforms support crt_destructor diff --git a/compiler/src/dmd/todt.d b/compiler/src/dmd/todt.d index 06bbc314b9..6a3634c4a3 100644 --- a/compiler/src/dmd/todt.d +++ b/compiler/src/dmd/todt.d @@ -958,6 +958,7 @@ private void membersToDt(AggregateDeclaration ad, ref DtBuilder dtb, switch (target.c.bitFieldStyle) { case TargetC.BitFieldStyle.Gcc_Clang: + case TargetC.BitFieldStyle.Gcc_Clang_ARM: bitFieldSize = (bf.bitOffset + bf.fieldWidth + 7) / 8; break; From 5ca459303e00a46b37adcb5b6fbea0e3dbdb19fb Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Mon, 22 Jul 2024 17:09:41 +0200 Subject: [PATCH 07/23] [refactor to `TargetC.contributesToAggregateAlignment(BitFieldDeclaration)` hook] --- compiler/src/dmd/dsymbolsem.d | 8 ++------ compiler/src/dmd/frontend.h | 2 +- compiler/src/dmd/target.d | 23 ++++++++++++++++++++--- compiler/src/dmd/target.h | 6 +++--- compiler/src/dmd/todt.d | 1 - 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index 2e8240bbb8..77e03c3bc8 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -7186,15 +7186,11 @@ 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 && - style != TargetC.BitFieldStyle.Gcc_Clang_ARM) - { + if (style != TargetC.BitFieldStyle.MS && style != TargetC.BitFieldStyle.Gcc_Clang) assert(0, "unsupported bit-field style"); - } const isMicrosoftStyle = style == TargetC.BitFieldStyle.MS; - const contributesToAggregateAlignment = !anon || style != TargetC.BitFieldStyle.Gcc_Clang; + const contributesToAggregateAlignment = target.c.contributesToAggregateAlignment(bfd); void startNewField() { diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index b91fb1ffd9..845e4889e9 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -5938,7 +5938,6 @@ struct TargetC final Unspecified = 0u, MS = 1u, Gcc_Clang = 2u, - Gcc_Clang_ARM = 3u, }; bool crtDestructorsSupported; @@ -5951,6 +5950,7 @@ struct TargetC final uint8_t wchar_tsize; Runtime runtime; BitFieldStyle bitFieldStyle; + bool contributesToAggregateAlignment(BitFieldDeclaration* bfd); TargetC() : crtDestructorsSupported(true), boolsize(), diff --git a/compiler/src/dmd/target.d b/compiler/src/dmd/target.d index 41843a3145..cb90d7133e 100644 --- a/compiler/src/dmd/target.d +++ b/compiler/src/dmd/target.d @@ -1360,6 +1360,8 @@ extern (C++) struct Target */ struct TargetC { + import dmd.declaration : BitFieldDeclaration; + enum Runtime : ubyte { Unspecified, @@ -1379,9 +1381,6 @@ struct TargetC /// https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160 /// https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160 Gcc_Clang, /// gcc and clang - Gcc_Clang_ARM, /// Like `Gcc_Clang`, except that anonymous and 0-length bit fields contribute - /// to the aggregate alignment. Used for 32 & 64 bit ARM targets, except for - /// Apple ARM64. } bool crtDestructorsSupported = true; /// Not all platforms support crt_destructor ubyte boolsize; /// size of a C `_Bool` type @@ -1452,6 +1451,24 @@ struct TargetC crtDestructorsSupported = false; } } + + /** + * Indicates whether the specified bit-field contributes to the alignment + * of the containing aggregate. + * E.g., (not all) ARM ABIs do NOT ignore anonymous (incl. 0-length) + * bit-fields. + */ + extern (C++) bool contributesToAggregateAlignment(BitFieldDeclaration bfd) + { + if (bitFieldStyle == BitFieldStyle.MS) + return true; + if (bitFieldStyle == BitFieldStyle.Gcc_Clang) + { + // sufficient for DMD's currently supported architectures + return !bfd.isAnonymous(); + } + assert(0); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/compiler/src/dmd/target.h b/compiler/src/dmd/target.h index 4f57b6fa3f..4ef76d7596 100644 --- a/compiler/src/dmd/target.h +++ b/compiler/src/dmd/target.h @@ -16,6 +16,7 @@ #include "globals.h" #include "tokens.h" +class BitFieldDeclaration; class ClassDeclaration; class Dsymbol; class Expression; @@ -65,9 +66,6 @@ struct TargetC // https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160 // https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160 Gcc_Clang, // gcc and clang - Gcc_Clang_ARM, // Like `Gcc_Clang`, except that anonymous and 0-length bit fields contribute - // to the aggregate alignment. Used for 32 & 64 bit ARM targets, except for - // Apple ARM64. }; uint8_t crtDestructorsSupported; // Not all platforms support crt_destructor @@ -80,6 +78,8 @@ struct TargetC uint8_t wchar_tsize; // size of a C 'wchar_t' type Runtime runtime; BitFieldStyle bitFieldStyle; // different C compilers do it differently + + bool contributesToAggregateAlignment(BitFieldDeclaration *bfd); }; struct TargetCPP diff --git a/compiler/src/dmd/todt.d b/compiler/src/dmd/todt.d index 6a3634c4a3..06bbc314b9 100644 --- a/compiler/src/dmd/todt.d +++ b/compiler/src/dmd/todt.d @@ -958,7 +958,6 @@ private void membersToDt(AggregateDeclaration ad, ref DtBuilder dtb, switch (target.c.bitFieldStyle) { case TargetC.BitFieldStyle.Gcc_Clang: - case TargetC.BitFieldStyle.Gcc_Clang_ARM: bitFieldSize = (bf.bitOffset + bf.fieldWidth + 7) / 8; break; From 29a34181da51bff45a78f51cf5889349499d0dca Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Mon, 5 Aug 2024 18:46:57 +0300 Subject: [PATCH 08/23] Fix Bugzilla Issue 24687 - [REG2.110] Cannot cast string-imports to select overload anymore --- compiler/src/dmd/dcast.d | 2 +- compiler/test/compilable/import_exp.d | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/src/dmd/dcast.d b/compiler/src/dmd/dcast.d index 29059678fc..b682c75429 100644 --- a/compiler/src/dmd/dcast.d +++ b/compiler/src/dmd/dcast.d @@ -704,7 +704,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; diff --git a/compiler/test/compilable/import_exp.d b/compiler/test/compilable/import_exp.d index 014d0f65f6..d29fc67ed6 100644 --- a/compiler/test/compilable/import_exp.d +++ b/compiler/test/compilable/import_exp.d @@ -34,3 +34,11 @@ enum expectedStart = "module imports.imp16088;"; immutable ubyte[] s0 = import("imp16088.d"); static assert(s0[0 .. expectedStart.length] == "module imports.imp16088;"); + +// https://issues.dlang.org/show_bug.cgi?id=24687 + +void foo(string path); +void foo(const(ubyte[]) data); + +void bar1() { foo(import("imp16088.d")); } // matches both +void bar2() { foo(cast(const(ubyte[])) import("imp16088.d")); } // matches both! From e643a07ebc37ef6e525bdc9de56c0ca1142a3317 Mon Sep 17 00:00:00 2001 From: Dennis Date: Tue, 13 Aug 2024 23:23:09 +0200 Subject: [PATCH 09/23] Also make deprecationSupplemental adhere to error limit (#16779) Co-authored-by: Dennis Korpel --- compiler/src/dmd/errors.d | 7 +++++-- compiler/test/compilable/deprecationlimit.d | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/src/dmd/errors.d b/compiler/src/dmd/errors.d index c7f647de9b..3b81248207 100644 --- a/compiler/src/dmd/errors.d +++ b/compiler/src/dmd/errors.d @@ -567,8 +567,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; diff --git a/compiler/test/compilable/deprecationlimit.d b/compiler/test/compilable/deprecationlimit.d index dcdc9e118c..8ee7ab650f 100644 --- a/compiler/test/compilable/deprecationlimit.d +++ b/compiler/test/compilable/deprecationlimit.d @@ -18,5 +18,5 @@ void main() f(); f(); f(); - f(); + static assert("1"); // also surpress deprecationSupplemental } From 636f4d3ba280cff50ced4d553cd34869fd69ba16 Mon Sep 17 00:00:00 2001 From: Dennis Korpel Date: Tue, 13 Aug 2024 22:29:43 +0200 Subject: [PATCH 10/23] Fix bugzilla 24699 - [REG2.108] No short-circuit evaluation of mixing template bool argument --- compiler/src/dmd/dtemplate.d | 6 ++++++ compiler/test/compilable/compile1.d | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/compiler/src/dmd/dtemplate.d b/compiler/src/dmd/dtemplate.d index 0881acf18d..19de63db66 100644 --- a/compiler/src/dmd/dtemplate.d +++ b/compiler/src/dmd/dtemplate.d @@ -4556,9 +4556,15 @@ 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.flags & SCOPE.condition); + // For master branch: const inCondition = sc.condition; sc = sc.push(); sc.inDefaultArg = false; + // https://issues.dlang.org/show_bug.cgi?id=24699 + sc.flags |= SCOPE.condition * inCondition; + // For master branch: sc.condition = inCondition; + for (size_t j = 0; j < tiargs.length; j++) { RootObject o = (*tiargs)[j]; diff --git a/compiler/test/compilable/compile1.d b/compiler/test/compilable/compile1.d index 4678eb5338..676108f68c 100644 --- a/compiler/test/compilable/compile1.d +++ b/compiler/test/compilable/compile1.d @@ -623,6 +623,11 @@ static assert (__traits(compiles, false && error) == false); int f11042a3()() if (__traits(compiles, true || error) == false) { return 0; } enum x11042a3 = f11042a3(); int f11042b3()() if (__traits(compiles, false && error) == false) { return 0; } enum x11042b3 = f11042b3(); +// https://issues.dlang.org/show_bug.cgi?id=24699 +enum T24699(bool cond) = cond; +enum b24699a = T24699!(true || error); +enum b24699b = T24699!(false && error); + /***************************************************/ // https://issues.dlang.org/show_bug.cgi?id=11554 From 96d630c6445b352fb3671c25db584cd292864072 Mon Sep 17 00:00:00 2001 From: Dennis Date: Sat, 31 Aug 2024 15:20:35 +0200 Subject: [PATCH 11/23] Fix bugzilla 24731 - IFTI cannot handle integer expressions (#16822) --- compiler/src/dmd/dtemplate.d | 4 +++- compiler/src/dmd/expression.d | 2 +- compiler/test/runnable/ifti.d | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/compiler/src/dmd/dtemplate.d b/compiler/src/dmd/dtemplate.d index 19de63db66..dfb18a8ed5 100644 --- a/compiler/src/dmd/dtemplate.d +++ b/compiler/src/dmd/dtemplate.d @@ -1698,7 +1698,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, ¶meters, dedtypes, null) || edim && edim.toInteger() == t.dim.toInteger()) + if ((tp && tp.matchArg(sc, t.dim, i, ¶meters, dedtypes, null)) || + (edim && edim.isIntegerExp() && edim.toInteger() == t.dim.toInteger()) + ) { result = deduceType(t.next, sc, tparam.nextOf(), parameters, dedtypes, wm); return; diff --git a/compiler/src/dmd/expression.d b/compiler/src/dmd/expression.d index b5fb0e2b9b..018a73d70a 100644 --- a/compiler/src/dmd/expression.d +++ b/compiler/src/dmd/expression.d @@ -474,7 +474,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; } diff --git a/compiler/test/runnable/ifti.d b/compiler/test/runnable/ifti.d index 0c94946c8b..293b8198d7 100644 --- a/compiler/test/runnable/ifti.d +++ b/compiler/test/runnable/ifti.d @@ -72,6 +72,20 @@ class Tst(TST, int v = 2) { class Y : Tst!(float) {} +// https://issues.dlang.org/show_bug.cgi?id=24731 +void test24731() +{ + static int solve(size_t N)(ref double[N+1][N]) + { + return N; + } + + double[3][2] m; + assert(solve(m) == 2); + assert(solve!2(m) == 2); +} + + void main() { Tst!(int) t = new Tst!(int); Y u = new Y; @@ -113,4 +127,5 @@ void main() { printf("%g\n", i); } + test24731(); } From 219b4f07e47f9a0b4c4304b6b02620335bc2a172 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Wed, 11 Sep 2024 16:04:08 +0300 Subject: [PATCH 12/23] Fix Bugzilla Issue 24760 - ICE on variadic after default argument --- compiler/src/dmd/typesem.d | 4 +++- compiler/test/compilable/test24760.d | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 compiler/test/compilable/test24760.d diff --git a/compiler/src/dmd/typesem.d b/compiler/src/dmd/typesem.d index a909fcf14c..3933d7dfdd 100644 --- a/compiler/src/dmd/typesem.d +++ b/compiler/src/dmd/typesem.d @@ -835,7 +835,9 @@ extern (D) MATCH callMatch(TypeFunction tf, Type tthis, ArgumentList argumentLis L1: if (parameterList.varargs == VarArg.typesafe && u + 1 == nparams) // if last varargs param { - auto trailingArgs = args[u .. $]; + Expression[] trailingArgs; + if (args.length >= u) + trailingArgs = args[u .. $]; if (auto vmatch = matchTypeSafeVarArgs(tf, p, trailingArgs, pMessage)) return vmatch < match ? vmatch : match; // Error message was already generated in `matchTypeSafeVarArgs` diff --git a/compiler/test/compilable/test24760.d b/compiler/test/compilable/test24760.d new file mode 100644 index 0000000000..7c84848a6f --- /dev/null +++ b/compiler/test/compilable/test24760.d @@ -0,0 +1,4 @@ +// https://issues.dlang.org/show_bug.cgi?id=24760 + +long f(int e = 0, uint[] optional...) => optional.length; +long f0() => f(); // compiler segfaults From f420f988ab1f53e604851c73e9f883dab4328f65 Mon Sep 17 00:00:00 2001 From: Dennis Date: Thu, 3 Oct 2024 13:46:41 +0200 Subject: [PATCH 13/23] Fix bugzilla 24790 - -vcg-ast ICE on lowered assign exp (#16914) Co-authored-by: Dennis Korpel --- compiler/src/dmd/parse.d | 1 + compiler/test/compilable/vcg-ast-arraylength.d | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/compiler/src/dmd/parse.d b/compiler/src/dmd/parse.d index a7a930335a..757aefb26b 100644 --- a/compiler/src/dmd/parse.d +++ b/compiler/src/dmd/parse.d @@ -9749,6 +9749,7 @@ immutable PREC[EXP.max + 1] precedence = EXP.assign : PREC.assign, EXP.construct : PREC.assign, EXP.blit : PREC.assign, + EXP.loweredAssignExp : PREC.assign, EXP.addAssign : PREC.assign, EXP.minAssign : PREC.assign, EXP.concatenateAssign : PREC.assign, diff --git a/compiler/test/compilable/vcg-ast-arraylength.d b/compiler/test/compilable/vcg-ast-arraylength.d index 8fdd7808f7..8c44421c61 100644 --- a/compiler/test/compilable/vcg-ast-arraylength.d +++ b/compiler/test/compilable/vcg-ast-arraylength.d @@ -23,4 +23,9 @@ void main() static assert(is(typeof(a.length = 0) == size_t)); static assert(is(typeof(a.length = f.length = 0) == size_t)); + + // https://issues.dlang.org/show_bug.cgi?id=24790 + struct S { int[] payload; } + S s; + s.payload.length += 3; } From e0259d92e7fada37ae5c8e784704056f8a5aefd0 Mon Sep 17 00:00:00 2001 From: Dennis Date: Thu, 3 Oct 2024 13:47:19 +0200 Subject: [PATCH 14/23] Fix bugzilla 24764 - ICE when -vcg-ast prints imported invariant (#16917) Co-authored-by: Dennis Korpel --- compiler/src/dmd/hdrgen.d | 4 ++-- .../test/compilable/extra-files/vcg-ast.d.cg | 22 ++++++++++++++++++- .../test/compilable/imports/vcg_ast_import.d | 4 ++++ compiler/test/compilable/vcg-ast.d | 12 ++++++++++ 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 compiler/test/compilable/imports/vcg_ast_import.d diff --git a/compiler/src/dmd/hdrgen.d b/compiler/src/dmd/hdrgen.d index a44fb2877a..f3c6bbb56b 100644 --- a/compiler/src/dmd/hdrgen.d +++ b/compiler/src/dmd/hdrgen.d @@ -1858,9 +1858,9 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs) if (stcToBuffer(buf, d.storage_class)) buf.writeByte(' '); buf.writestring("invariant"); - if(auto es = d.fbody.isExpStatement()) + auto es = d.fbody.isExpStatement(); + if (es && es.exp && es.exp.op == EXP.assert_) { - assert(es.exp && es.exp.op == EXP.assert_); buf.writestring(" ("); (cast(AssertExp)es.exp).e1.expressionToBuffer(buf, hgs); buf.writestring(");"); diff --git a/compiler/test/compilable/extra-files/vcg-ast.d.cg b/compiler/test/compilable/extra-files/vcg-ast.d.cg index 640cba43ed..e6a9ca384f 100644 --- a/compiler/test/compilable/extra-files/vcg-ast.d.cg +++ b/compiler/test/compilable/extra-files/vcg-ast.d.cg @@ -100,6 +100,12 @@ void main() values(); return 0; } +import imports.vcg_ast_import; +template imported() +{ + import imported = imports.vcg_ast_import; +} +alias myImport = vcg_ast_import; R!int { struct _R @@ -126,6 +132,21 @@ mixin _d_cmain!(); } } } +imported!() +{ + import object; + struct O + { + invariant + { + } + invariant + { + __invariant0(); + } + } + +} RTInfo!(C) { enum immutable(void)* RTInfo = null; @@ -150,4 +171,3 @@ RTInfo!(_R) enum immutable(void)* RTInfo = null; } - diff --git a/compiler/test/compilable/imports/vcg_ast_import.d b/compiler/test/compilable/imports/vcg_ast_import.d new file mode 100644 index 0000000000..a2064c0d17 --- /dev/null +++ b/compiler/test/compilable/imports/vcg_ast_import.d @@ -0,0 +1,4 @@ +struct O +{ + invariant() {} +} diff --git a/compiler/test/compilable/vcg-ast.d b/compiler/test/compilable/vcg-ast.d index 4a7b8bc33c..9197441aff 100644 --- a/compiler/test/compilable/vcg-ast.d +++ b/compiler/test/compilable/vcg-ast.d @@ -2,6 +2,7 @@ REQUIRED_ARGS: -vcg-ast -o- PERMUTE_ARGS: OUTPUT_FILES: compilable/vcg-ast.d.cg +EXTRA_FILES: imports/vcg_ast_import.d TEST_OUTPUT_FILE: extra-files/vcg-ast.d.cg */ @@ -63,3 +64,14 @@ void main() { values!wchar_t; } + +// https://issues.dlang.org/show_bug.cgi?id=24764 + +import imports.vcg_ast_import; + +template imported() +{ + import imported = imports.vcg_ast_import; +} + +alias myImport = imported!(); From 3f48f53e2784c4bab812469f428eb65653035fcf Mon Sep 17 00:00:00 2001 From: Dennis Date: Fri, 4 Oct 2024 01:47:09 +0200 Subject: [PATCH 15/23] =?UTF-8?q?Fix=20bugzilla=2024431=20-=20dmd=20-vcg-a?= =?UTF-8?q?st=20crashes=20printing=20failed=20template=20in=E2=80=A6=20(#1?= =?UTF-8?q?6916)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/src/dmd/hdrgen.d | 4 +- compiler/test/compilable/vcg_ast_compilable.d | 69 +++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 compiler/test/compilable/vcg_ast_compilable.d diff --git a/compiler/src/dmd/hdrgen.d b/compiler/src/dmd/hdrgen.d index f3c6bbb56b..013a081534 100644 --- a/compiler/src/dmd/hdrgen.d +++ b/compiler/src/dmd/hdrgen.d @@ -1720,10 +1720,10 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs) //printf("FuncDeclaration::toCBuffer() '%s'\n", f.toChars()); if (stcToBuffer(buf, f.storage_class)) buf.writeByte(' '); + typeToBuffer(f.type, f.ident, buf, hgs); auto tf = f.type.isTypeFunction(); - typeToBuffer(tf, f.ident, buf, hgs); - if (hgs.hdrgen) + if (hgs.hdrgen && tf) { // if the return type is missing (e.g. ref functions or auto) // https://issues.dlang.org/show_bug.cgi?id=20090 diff --git a/compiler/test/compilable/vcg_ast_compilable.d b/compiler/test/compilable/vcg_ast_compilable.d new file mode 100644 index 0000000000..e84846dfbe --- /dev/null +++ b/compiler/test/compilable/vcg_ast_compilable.d @@ -0,0 +1,69 @@ +/* +REQUIRED_ARGS: -vcg-ast -o- +OUTPUT_FILES: compilable/vcg_ast_compilable.d.cg +TEST_OUTPUT: +--- +=== compilable/vcg_ast_compilable.d.cg +import object; +auto binaryFun(E)(E b) +{ + return 'a' == b; +} +void find(Element)(Element needle) if (is(typeof(binaryFun(needle)))) +{ +} +void find()(string needle) +{ +} +void splitter() +{ + find(3); + find(""); +} +binaryFun!int +{ + auto pure nothrow @nogc @safe bool binaryFun(int b) + { + return 97 == b; + } + +} +find!int +{ + pure nothrow @nogc @safe void find(int needle) + { + } + +} +binaryFun!string +{ + auto _error_ binaryFun + { + __error__ + } + +} +find!() +{ + pure nothrow @nogc @safe void find(string needle) + { + } + +} +--- +*/ + +// https://issues.dlang.org/show_bug.cgi?id=24431 +auto binaryFun(E)(E b) +{ + return 'a' == b; +} + +void find(Element)(Element needle) if (is(typeof(binaryFun(needle)))) { } +void find()(string needle) { } + +void splitter() +{ + find!int(3); + find!()(""); +} From e093a6f8be353e6b75d460ca7ff2888a5d192575 Mon Sep 17 00:00:00 2001 From: Nicholas Wilson Date: Mon, 7 Oct 2024 13:08:42 +0800 Subject: [PATCH 16/23] [importc.h] #define __typeof__ typeof --- druntime/src/importc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/druntime/src/importc.h b/druntime/src/importc.h index 858e502b99..b7b82dbe6b 100644 --- a/druntime/src/importc.h +++ b/druntime/src/importc.h @@ -41,6 +41,7 @@ #define __alignof _Alignof #define __vector_size__ vector_size #define __typeof typeof +#define __typeof__ typeof /******************** * Clang nullability extension used by macOS headers. From b97828fef45b55541eaefe098e5508f45c27f837 Mon Sep 17 00:00:00 2001 From: Nicholas Wilson Date: Mon, 14 Oct 2024 19:03:17 +0800 Subject: [PATCH 17/23] Fix bugzilla issue 24812 - Incorrect highlighting when diagnosing an empty enum declaration (#17004) --- compiler/src/dmd/enumsem.d | 2 +- compiler/test/fail_compilation/diag24812.d | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 compiler/test/fail_compilation/diag24812.d diff --git a/compiler/src/dmd/enumsem.d b/compiler/src/dmd/enumsem.d index c67ac618ec..0aa26cf47b 100644 --- a/compiler/src/dmd/enumsem.d +++ b/compiler/src/dmd/enumsem.d @@ -186,7 +186,7 @@ void enumSemantic(Scope* sc, EnumDeclaration ed) if (ed.members.length == 0) { - .error(ed.loc, "%s `%s enum `%s` must have at least one member", ed.kind, ed.toPrettyChars, ed.toChars()); + .error(ed.loc, "%s `%s` enum `%s` must have at least one member", ed.kind, ed.toPrettyChars, ed.toChars()); ed.errors = true; ed.semanticRun = PASS.semanticdone; return; diff --git a/compiler/test/fail_compilation/diag24812.d b/compiler/test/fail_compilation/diag24812.d new file mode 100644 index 0000000000..626f47ebf0 --- /dev/null +++ b/compiler/test/fail_compilation/diag24812.d @@ -0,0 +1,7 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/diag24812.d(7): Error: enum `diag24812.Foo` enum `Foo` must have at least one member +--- +*/ +enum Foo {} From d0eb6bb659fc2d348a7e6beaad2d32e1cf909f02 Mon Sep 17 00:00:00 2001 From: Dennis Date: Thu, 24 Oct 2024 19:45:57 +0200 Subject: [PATCH 18/23] Fix bugzilla 24832 - Segfault in hex string (#17024) * Fix bugzilla 24832 - Segfault in hex string * Fix lack of camelcasing on stable branch --- compiler/src/dmd/dcast.d | 2 +- compiler/src/dmd/dinterpret.d | 2 +- compiler/test/fail_compilation/hexstring.d | 10 +++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/src/dmd/dcast.d b/compiler/src/dmd/dcast.d index b682c75429..ce51c28f6e 100644 --- a/compiler/src/dmd/dcast.d +++ b/compiler/src/dmd/dcast.d @@ -2336,7 +2336,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) Type tb = t.toBasetype(); Type typeb = e.type.toBasetype(); - if (e.hexString && !e.committed) + if (e.hexString && !e.committed && tb.nextOf().isintegral) { const szx = cast(ubyte) tb.nextOf().size(); if (szx != se.sz && (e.len % szx) == 0) diff --git a/compiler/src/dmd/dinterpret.d b/compiler/src/dmd/dinterpret.d index 52520be01d..967e83106f 100644 --- a/compiler/src/dmd/dinterpret.d +++ b/compiler/src/dmd/dinterpret.d @@ -6107,7 +6107,7 @@ public: { auto se = e1.isStringExp(); // Allow casting a hex string literal to short[], int[] or long[] - if (se && se.hexString && se.postfix == StringExp.NoPostfix) + if (se && se.hexString && se.postfix == StringExp.NoPostfix && e.to.nextOf().isintegral) { const sz = cast(size_t) e.to.nextOf().size; if ((se.len % sz) != 0) diff --git a/compiler/test/fail_compilation/hexstring.d b/compiler/test/fail_compilation/hexstring.d index 0f23f44438..edbb4e67bc 100644 --- a/compiler/test/fail_compilation/hexstring.d +++ b/compiler/test/fail_compilation/hexstring.d @@ -14,6 +14,7 @@ fail_compilation/hexstring.d(39): perhaps remove postfix `c` from hex str fail_compilation/hexstring.d(40): Error: hex string with `dstring` type needs to be multiple of 4 bytes, not 5 fail_compilation/hexstring.d(41): Error: cannot implicitly convert expression `x"11223344"d` of type `dstring` to `immutable(float[])` fail_compilation/hexstring.d(42): Error: cannot implicitly convert expression `x"1122"w` of type `wstring` to `immutable(ubyte[])` +fail_compilation/hexstring.d(50): Error: array cast from `string` to `S[]` is not supported at compile time fail_compilation/hexstring.d(28): Error: cannot implicitly convert expression `x"123F"` of type `string` to `ubyte[]` --- */ @@ -21,7 +22,6 @@ immutable ubyte[] s0 = x"123F"; static assert(s0[0] == 0x12); static assert(s0[1] == 0x3F); immutable byte[] s1 = x"123F"; - enum E(X) = cast(X[]) x"AABBCCDD"; static assert(E!int[0] == 0xAABBCCDD); @@ -40,3 +40,11 @@ immutable uint[] f11 = cast(immutable uint[]) x"AABBCCDD"c; immutable uint[] f12 = x"1122334455"d; immutable float[] f13 = x"11223344"d; immutable ubyte[] f14 = x"1122"w; + +// https://issues.dlang.org/show_bug.cgi?id=24832 +struct S +{ + ushort l0, l1, l2, l3, l4, l5; +} + +immutable S[] returnValues = cast(S[]) x"FFFFFFFFFFFFFFFFFFFFFFFF"; From 735193cc36db6b2fa2c50270fae3414316323d9b Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Thu, 24 Oct 2024 04:01:19 -0700 Subject: [PATCH 19/23] fix bugzilla Issue 24819 - Optimizer changes result of float calculations on 32-bit (#17023) (cherry picked from commit 88d1e8fc37428b873f59d87f8dff1f40fbd3e7a3) --- compiler/src/dmd/backend/cgelem.d | 4 ++++ compiler/src/dmd/backend/debugprint.d | 2 +- compiler/src/dmd/backend/dout.d | 2 +- compiler/test/runnable/test24819.d | 18 ++++++++++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 compiler/test/runnable/test24819.d diff --git a/compiler/src/dmd/backend/cgelem.d b/compiler/src/dmd/backend/cgelem.d index 6d4324cd4d..31f53adf3d 100644 --- a/compiler/src/dmd/backend/cgelem.d +++ b/compiler/src/dmd/backend/cgelem.d @@ -3888,6 +3888,10 @@ static if (0) // If floating point, replace (x = -y) with (x = y ^ signbit) if (op2 == OPneg && (tyreal(e2.Ety) || tyimaginary(e2.Ety)) && (e2.E1.Eoper == OPvar || e2.E1.Eoper == OPind) && + /* Turned off for x87 because of https://issues.dlang.org/show_bug.cgi?id=24819 + * and this is unnecessary anyway because of the FCHS x87 instruction + */ + !config.inline8087 && /* Turned off for XMM registers because they don't play well with * int registers. */ diff --git a/compiler/src/dmd/backend/debugprint.d b/compiler/src/dmd/backend/debugprint.d index 1a7334ce55..b36e5ccb87 100644 --- a/compiler/src/dmd/backend/debugprint.d +++ b/compiler/src/dmd/backend/debugprint.d @@ -510,7 +510,7 @@ void numberBlocks(block *startblock) @trusted void WRfunc(const char* msg, Symbol* sfunc, block* startblock) { - printf("............%s...%s().............\n", msg, sfunc.Sident.ptr); + printf("............%s...%s()\n", msg, sfunc.Sident.ptr); numberBlocks(startblock); for (block *b = startblock; b; b = b.Bnext) WRblock(b); diff --git a/compiler/src/dmd/backend/dout.d b/compiler/src/dmd/backend/dout.d index 09003df4d6..031cbe105c 100644 --- a/compiler/src/dmd/backend/dout.d +++ b/compiler/src/dmd/backend/dout.d @@ -861,7 +861,7 @@ private void writefunc2(Symbol *sfunc) { func_t *f = sfunc.Sfunc; - //printf("writefunc(%s)\n",sfunc.Sident.ptr); + debugb && printf("=========== writefunc %s ==================\n",sfunc.Sident.ptr); //symbol_print(sfunc); debug debugy && printf("writefunc(%s)\n",sfunc.Sident.ptr); diff --git a/compiler/test/runnable/test24819.d b/compiler/test/runnable/test24819.d new file mode 100644 index 0000000000..3ba374bed3 --- /dev/null +++ b/compiler/test/runnable/test24819.d @@ -0,0 +1,18 @@ +import core.stdc.stdio; + +pragma(inline, true) +double sqrt(double x) +{ + static import core.math; + return core.math.sqrt(x); +} + +int main() +{ + double q = -5.0; + double r = q + 1.0; + double result = sqrt(-r); + //printf("%f\n", result); + assert(result == 2); + return 0; +} From 2a63416b43cdf876e8818501f56a4ec441f053bf Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 14 Aug 2024 11:21:18 +0200 Subject: [PATCH 20/23] Bugzilla 24700 - Don't search for mscoff .dp$B section over and over (#16780) (cherry picked from commit 67227f03e04368654d40ff707be7ee424b490e3b) --- compiler/src/dmd/backend/mscoffobj.d | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/compiler/src/dmd/backend/mscoffobj.d b/compiler/src/dmd/backend/mscoffobj.d index e0490ba353..0be34ce7f7 100644 --- a/compiler/src/dmd/backend/mscoffobj.d +++ b/compiler/src/dmd/backend/mscoffobj.d @@ -2456,15 +2456,21 @@ void MsCoffObj_write_pointerRef(Symbol* s, uint soff) * Params: * s = symbol that contains the pointer * soff = offset of the pointer inside the Symbol's memory + * segments = lazy indices into tls / data pointer sections */ @trusted -extern (D) private void objflush_pointerRef(Symbol* s, uint soff) +extern (D) private void objflush_pointerRef(Symbol* s, uint soff, ref segidx_t[2] segments) { bool isTls = (s.Sfl == FLtlsdata); - const(char)* segname = isTls ? ".tp$B" : ".dp$B"; - int attr = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ; - int seg = MsCoffObj_getsegment(segname, attr); + if (segments[isTls] == UNKNOWN) + { + const(char)* segname = isTls ? ".tp$B" : ".dp$B"; + int attr = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ; + segments[isTls] = MsCoffObj_getsegment(segname, attr); + } + + const seg = segments[isTls]; targ_size_t offset = SegData[seg].SDoffset; MsCoffObj_addrel(seg, offset, s, cast(uint)offset, RELaddr32, 0); OutBuffer* buf = SegData[seg].SDbuf; @@ -2485,13 +2491,14 @@ extern (D) private void objflush_pointerRefs() ubyte *p = ptrref_buf.buf; ubyte *end = ptrref_buf.buf + ptrref_buf.length(); + segidx_t[2] segments = UNKNOWN; while (p < end) { Symbol* s = *cast(Symbol**)p; p += s.sizeof; uint soff = *cast(uint*)p; p += soff.sizeof; - objflush_pointerRef(s, soff); + objflush_pointerRef(s, soff, segments); } ptrref_buf.reset(); } From b11b3f3bfa8d8fd1dd9413bb97d044855aef7613 Mon Sep 17 00:00:00 2001 From: "Richard (Rikki) Andrew Cattermole" Date: Sat, 2 Nov 2024 19:54:47 +1300 Subject: [PATCH 21/23] Fix bugzilla issue 24841 - UTF-16 surrogates when used as an escape of a string should hint on error --- compiler/src/dmd/lexer.d | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/compiler/src/dmd/lexer.d b/compiler/src/dmd/lexer.d index 26a56c2b1f..487076ea5f 100644 --- a/compiler/src/dmd/lexer.d +++ b/compiler/src/dmd/lexer.d @@ -1556,6 +1556,8 @@ class Lexer if (ndigits != 2 && !utf_isValidDchar(v)) { error(loc, "invalid UTF character \\U%08x", v); + if (v >= 0xD800 && v <= 0xDFFF) + errorSupplemental("The code unit is a UTF-16 surrogate, is the escape UTF-16 not a Unicode code point?"); v = '?'; // recover with valid UTF character } } @@ -3169,6 +3171,11 @@ class Lexer eSink.error(loc, format, args); } + void errorSupplemental(T...)(const(char)* format, T args) + { + eSink.errorSupplemental(token.loc, format, args); + } + void deprecation(T...)(const ref Loc loc, const(char)* format, T args) { eSink.deprecation(loc, format, args); @@ -3672,6 +3679,7 @@ unittest import core.stdc.stdarg; string expected; + string expectedSupplemental; bool gotError; void error(const ref Loc loc, const(char)* format, ...) @@ -3684,13 +3692,25 @@ unittest va_end(ap); assert(expected == actual); } + + void errorSupplemental(const ref Loc loc, const(char)* format, ...) + { + gotError = true; + char[128] buffer = void; + va_list ap; + va_start(ap, format); + auto actual = buffer[0 .. vsnprintf(buffer.ptr, buffer.length, format, ap)]; + va_end(ap); + assert(expectedSupplemental == actual); + } } ErrorSinkTest errorSink = new ErrorSinkTest; - void test(string sequence, string expectedError, dchar expectedReturnValue, uint expectedScanLength, bool Ccompile = false) + void test2(string sequence, string[2] expectedError, dchar expectedReturnValue, uint expectedScanLength, bool Ccompile = false) { - errorSink.expected = expectedError; + errorSink.expected = expectedError[0]; + errorSink.expectedSupplemental = expectedError[1]; errorSink.gotError = false; auto p = cast(const(char)*)sequence.ptr; Lexer lexer = new Lexer(errorSink); @@ -3703,6 +3723,11 @@ unittest assert(expectedScanLength == actualScanLength); } + void test(string sequence, string expectedError, dchar expectedReturnValue, uint expectedScanLength, bool Ccompile = false) + { + test2(sequence, [expectedError, null], expectedReturnValue, expectedScanLength, Ccompile); + } + test("c", `undefined escape sequence \c`, 'c', 1); test("!", `undefined escape sequence \!`, '!', 1); test(""", `undefined escape sequence \&`, '&', 1, true); @@ -3721,8 +3746,6 @@ unittest test("U0001f6" , `escape hex sequence has 6 hex digits instead of 8`, 0x0001f6, 7); test("U0001f60", `escape hex sequence has 7 hex digits instead of 8`, 0x0001f60, 8); - test("ud800" , `invalid UTF character \U0000d800`, '?', 5); - test("udfff" , `invalid UTF character \U0000dfff`, '?', 5); test("U00110000", `invalid UTF character \U00110000`, '?', 9); test("xg0" , `undefined escape hex sequence \xg`, 'g', 2); @@ -3734,6 +3757,9 @@ unittest test(""", `unterminated named entity "`, '?', 5); test("400", `escape octal sequence \400 is larger than \377`, 0x100, 3); + + test2("uD800", [`invalid UTF character \U0000d800`, `The code unit is a UTF-16 surrogate, is the escape UTF-16 not a Unicode code point?`], '?', 5); + test2("uDFFF", [`invalid UTF character \U0000dfff`, `The code unit is a UTF-16 surrogate, is the escape UTF-16 not a Unicode code point?`], '?', 5); } unittest From a7c85ec3be036e87a6fd76e0d4cd0fba36dd1e07 Mon Sep 17 00:00:00 2001 From: "Richard (Rikki) Andrew Cattermole" Date: Thu, 7 Nov 2024 23:58:50 +1300 Subject: [PATCH 22/23] Fix bugzilla issue 24846 - atomicLoad does not work for class arguments with -preview=nosharedaccess --- compiler/src/dmd/expressionsem.d | 21 +++++++++++++++++++ compiler/src/dmd/frontend.h | 1 + compiler/src/dmd/id.d | 1 + ...es.d => atomic_loadstore_shared_classes.d} | 5 +++++ 4 files changed, 28 insertions(+) rename compiler/test/compilable/{atomic_store_2_shared_classes.d => atomic_loadstore_shared_classes.d} (60%) diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 5cf0cbb4cb..07b1347938 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -15136,6 +15136,27 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false) { return false; } + else if (sc._module.ident == Id.atomic && sc._module.parent !is null) + { + // Allow core.internal.atomic, it is an compiler implementation for a given platform module. + // It is then exposed by other modules such as core.atomic and core.stdc.atomic. + // This is available as long as druntime is on the import path and the platform supports that operation. + + // https://issues.dlang.org/show_bug.cgi?id=24846 + + Package parent = sc._module.parent.isPackage(); + if (parent !is null) + { + // This can be easily converted over to apply to core.atomic and core.internal.atomic + if (parent.ident == Id.internal) + { + parent = parent.parent.isPackage(); + + if (parent !is null && parent.ident == Id.core && parent.parent is null) + return false; + } + } + } //printf("checkSharedAccess() `%s` returnRef: %d\n", e.toChars(), returnRef); diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index 845e4889e9..46b0efd8d1 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -8606,6 +8606,7 @@ struct Id final static Identifier* va_start; static Identifier* std; static Identifier* core; + static Identifier* internal; static Identifier* config; static Identifier* c_complex_float; static Identifier* c_complex_double; diff --git a/compiler/src/dmd/id.d b/compiler/src/dmd/id.d index f676361d95..f5d9340e86 100644 --- a/compiler/src/dmd/id.d +++ b/compiler/src/dmd/id.d @@ -389,6 +389,7 @@ immutable Msgtable[] msgtable = // Builtin functions { "std" }, { "core" }, + { "internal" }, { "config" }, { "c_complex_float" }, { "c_complex_double" }, diff --git a/compiler/test/compilable/atomic_store_2_shared_classes.d b/compiler/test/compilable/atomic_loadstore_shared_classes.d similarity index 60% rename from compiler/test/compilable/atomic_store_2_shared_classes.d rename to compiler/test/compilable/atomic_loadstore_shared_classes.d index 0d8cd74893..f719aa829f 100644 --- a/compiler/test/compilable/atomic_store_2_shared_classes.d +++ b/compiler/test/compilable/atomic_loadstore_shared_classes.d @@ -5,9 +5,14 @@ class Foo { } +shared Foo toLoad; + void oops() { auto f0 = new shared Foo; auto f1 = new shared Foo; atomicStore(f0, f1); + + // https://issues.dlang.org/show_bug.cgi?id=24846 + shared(Foo) f2 = atomicLoad(toLoad); } From 3aaf7bf2224aa5f82e5c9ef0e9b24e42dad2ee99 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Thu, 14 Nov 2024 03:46:12 +0100 Subject: [PATCH 23/23] GitHub Actions: Bump macos-12 jobs to macos-13 (#17063) As the macos-12 image will be 'fully unsupported' starting with December 3rd: https://github.com/actions/runner-images/issues/10721 --- .github/workflows/main.yml | 14 ++++++------- .github/workflows/runnable_cxx.yml | 32 +++++++++++++++++------------- ci/README.md | 12 +++++------ 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b3fcb82b07..69d289f317 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -58,8 +58,9 @@ jobs: # os: macos-13 # host_dmd: dmd # coverage: true - - job_name: macOS 12 x64, DMD (bootstrap) - os: macos-12 + - job_name: macOS 13 x64, DMD (bootstrap) + os: macos-13 + xcode: '14.3.1' # work around 'ld: multiple errors: symbol count from symbol table and dynamic symbol table differ' with old bootstrap compiler # de-facto bootstrap version on OSX # See: https://github.com/dlang/dmd/pull/13890 host_dmd: dmd-2.099.1 @@ -100,12 +101,9 @@ jobs: if: runner.os != 'Windows' run: ${{ runner.os == 'macOS' && 'ci/cirrusci.sh' || 'sudo -E ci/cirrusci.sh' }} - # 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: 'macOS: Switch Xcode version if required' + if: runner.os == 'macOS' && matrix.xcode + run: sudo xcode-select -switch /Applications/Xcode_${{ matrix.xcode }}.app - name: 'Posix: Install host compiler' if: runner.os != 'Windows' diff --git a/.github/workflows/runnable_cxx.yml b/.github/workflows/runnable_cxx.yml index dc701907cd..224ae6fd85 100644 --- a/.github/workflows/runnable_cxx.yml +++ b/.github/workflows/runnable_cxx.yml @@ -57,10 +57,10 @@ jobs: # very few PRs actually benefit from this. fail-fast: false matrix: - os: [ macOS-12, ubuntu-20.04, windows-2019 ] + os: [ macos-13, ubuntu-20.04, windows-2019 ] target: [ - # Versions of clang earlier than 11 are not available on 20.04, but are on macOS-12 + # Versions of clang earlier than 11 are not available on 20.04, but are on macOS 13 clang-13.0.0, clang-12.0.0, clang-11.0.0, clang-10.0.0, clang-9.0.0, clang-8.0.0, # For g++, we test the oldest compiler on Ubuntu 20.04, which is GCC-9 g++-11, g++-10, g++-9, @@ -81,13 +81,13 @@ jobs: - { os: ubuntu-20.04, target: msvc-2015 } - { os: ubuntu-20.04, target: msvc-2013 } # OSX only supports clang - - { os: macOS-12, target: g++-11 } - - { os: macOS-12, target: g++-10 } - - { os: macOS-12, target: g++-9 } - - { os: macOS-12, target: msvc-2019 } - - { os: macOS-12, target: msvc-2017 } - - { os: macOS-12, target: msvc-2015 } - - { os: macOS-12, target: msvc-2013 } + - { os: macos-13, target: g++-11 } + - { os: macos-13, target: g++-10 } + - { os: macos-13, target: g++-9 } + - { os: macos-13, target: msvc-2019 } + - { os: macos-13, target: msvc-2017 } + - { os: macos-13, target: msvc-2015 } + - { os: macos-13, target: msvc-2013 } # We don't test g++ on Windows as DMD only mangles for MSVC - { os: windows-2019, target: g++-11 } - { os: windows-2019, target: g++-10 } @@ -126,13 +126,13 @@ jobs: - { target: g++-9, compiler: g++, cxx-version: 9.4.0, major: 9 } # Platform boilerplate - { os: ubuntu-20.04, arch: x86_64-linux-gnu-ubuntu-20.04 } - - { os: macOS-12, arch: x86_64-apple-darwin } + - { os: macos-13, arch: x86_64-apple-darwin } # Clang 9.0.0 have a different arch for OSX - - { os: macOS-12, target: clang-9.0.0, arch: x86_64-darwin-apple } + - { os: macos-13, target: clang-9.0.0, arch: x86_64-darwin-apple } # Those targets will generate artifacts that can be used by other testers - { storeArtifacts: false } - { os: ubuntu-20.04, target: g++-9, storeArtifacts: true } - - { os: macOS-12, target: clang-9.0.0, storeArtifacts: true } + - { os: macos-13, target: clang-9.0.0, storeArtifacts: true } #- { os: windows-2019, target: msvc-2019, storeArtifacts: true } # We're using the latest available images at the time of this commit. @@ -209,7 +209,7 @@ jobs: # On OSX, the system header are installed via `xcode-select` and not distributed with clang # Since some part of the testsuite rely on CC and CXX being only a binary (not a command), # and config files where only introduced from 6.0.0, use a wrapper script. - if [ "${{ matrix.os }}" == "macOS-12" ]; then + if [ "${{ matrix.os }}" == "macos-13" ]; then # Note: heredoc shouldn't be indented cat << 'EOF' > ${TMP_CC}-wrapper #!/bin/bash @@ -227,11 +227,15 @@ jobs: chmod +x ${TMP_CC}-wrapper ${TMP_CC}++-wrapper fi + - name: 'macOS 13: Switch to Xcode v14.3.1' # to work around '-macosx_version_min has been renamed to -macos_version_min' with some clang versions + if: matrix.os == 'macos-13' + run: sudo xcode-select -switch /Applications/Xcode_14.3.1.app + - name: '[Posix] Setup environment variables' if: matrix.compiler == 'clang' && runner.os != 'Windows' run: | TMP_CC='${{ github.workspace }}/clang+llvm-${{ matrix.cxx-version }}-${{ matrix.arch }}/bin/clang' - if [ "${{ matrix.os }}" == "macOS-12" ]; then + if [ "${{ matrix.os }}" == "macos-13" ]; then echo "CC=${TMP_CC}-wrapper" >> $GITHUB_ENV echo "CXX=${TMP_CC}++-wrapper" >> $GITHUB_ENV echo "SDKROOT=$(xcrun --show-sdk-path)" >> $GITHUB_ENV diff --git a/ci/README.md b/ci/README.md index ec1c6bf5ba..d9f989dc11 100644 --- a/ci/README.md +++ b/ci/README.md @@ -112,12 +112,12 @@ The auto tester tests DMD on various Posix platforms. **Config**: [azure-pipelines.yml](https://github.com/dlang/dmd/blob/master/.github/workflows/runnable_cxx.yml) **Checks**: -- C++ interop tests / Run (macOS-12, clang-13.0.0) -- C++ interop tests / Run (macOS-12, clang-12.0.0) -- C++ interop tests / Run (macOS-12, clang-11.0.0) -- C++ interop tests / Run (macOS-12, clang-10.0.0) -- C++ interop tests / Run (macOS-12, clang-9.0.0) -- C++ interop tests / Run (macOS-12, clang-8.0.0) +- C++ interop tests / Run (macos-13, clang-13.0.0) +- C++ interop tests / Run (macos-13, clang-12.0.0) +- C++ interop tests / Run (macos-13, clang-11.0.0) +- C++ interop tests / Run (macos-13, clang-10.0.0) +- C++ interop tests / Run (macos-13, clang-9.0.0) +- C++ interop tests / Run (macos-13, clang-8.0.0) - C++ interop tests / Run (ubuntu-20.04, clang-13.0.0) - C++ interop tests / Run (ubuntu-20.04, clang-12.0.0) - C++ interop tests / Run (ubuntu-20.04, clang-11.0.0)