diff options
Diffstat (limited to 'gcc/d/dmd')
-rw-r--r-- | gcc/d/dmd/MERGE | 2 | ||||
-rw-r--r-- | gcc/d/dmd/VERSION | 2 | ||||
-rw-r--r-- | gcc/d/dmd/clone.d | 2 | ||||
-rw-r--r-- | gcc/d/dmd/common/string.d | 2 | ||||
-rw-r--r-- | gcc/d/dmd/cond.d | 1 | ||||
-rw-r--r-- | gcc/d/dmd/cparse.d | 10 | ||||
-rw-r--r-- | gcc/d/dmd/dsymbolsem.d | 194 | ||||
-rw-r--r-- | gcc/d/dmd/errors.d | 34 | ||||
-rw-r--r-- | gcc/d/dmd/expression.d | 24 | ||||
-rw-r--r-- | gcc/d/dmd/expression.h | 6 | ||||
-rw-r--r-- | gcc/d/dmd/expressionsem.d | 4 | ||||
-rw-r--r-- | gcc/d/dmd/func.d | 18 | ||||
-rw-r--r-- | gcc/d/dmd/globals.d | 10 | ||||
-rw-r--r-- | gcc/d/dmd/globals.h | 11 | ||||
-rw-r--r-- | gcc/d/dmd/initsem.d | 25 | ||||
-rw-r--r-- | gcc/d/dmd/lexer.d | 1 | ||||
-rw-r--r-- | gcc/d/dmd/nogc.d | 2 | ||||
-rw-r--r-- | gcc/d/dmd/parse.d | 86 | ||||
-rw-r--r-- | gcc/d/dmd/semantic3.d | 3 | ||||
-rw-r--r-- | gcc/d/dmd/target.d | 4 | ||||
-rw-r--r-- | gcc/d/dmd/target.h | 2 | ||||
-rw-r--r-- | gcc/d/dmd/traits.d | 23 |
22 files changed, 276 insertions, 190 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 308d51b..a02a8cb 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -a88e1335f7ea767ef438c34998f5d1f26008c586 +26f049fb26e755096dea3f1474decea7c0fef187 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index 9c46eea..6faa8d8 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.104.1 +v2.105.0-beta.1 diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d index 3586f20..4cff1ec 100644 --- a/gcc/d/dmd/clone.d +++ b/gcc/d/dmd/clone.d @@ -1263,7 +1263,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) // block to destroy any prior successfully postblitted fields should // this field's postblit fail. // Don't generate it for betterC code since it cannot throw exceptions. - if (fieldsToDestroy.length > 0 && !(cast(TypeFunction)sdv.postblit.type).isnothrow && !global.params.betterC) + if (fieldsToDestroy.length > 0 && !(cast(TypeFunction)sdv.postblit.type).isnothrow && global.params.useExceptions) { // create a list of destructors that need to be called Expression[] dtorCalls; diff --git a/gcc/d/dmd/common/string.d b/gcc/d/dmd/common/string.d index a1614fd..6de921e 100644 --- a/gcc/d/dmd/common/string.d +++ b/gcc/d/dmd/common/string.d @@ -48,7 +48,7 @@ struct SmallBuffer(Element) } else { - assert(len < sizeof.max / Element.sizeof); + assert(len < sizeof.max / (2 * Element.sizeof)); _extent = (cast(typeof(_extent.ptr)) malloc(len * Element.sizeof))[0 .. len]; _extent.ptr || assert(0, "Out of memory."); needsFree = true; diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d index fcb50e0..467f9f1 100644 --- a/gcc/d/dmd/cond.d +++ b/gcc/d/dmd/cond.d @@ -733,6 +733,7 @@ extern (C++) final class VersionCondition : DVCondition case "SysV4": case "TVOS": case "unittest": + case "VisionOS": case "WASI": case "WatchOS": case "WebAssembly": diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index 1b6b2bb..03383d1 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -1911,14 +1911,12 @@ final class CParser(AST) : Parser!AST if (tt.id || tt.tok == TOK.enum_) { if (!tt.id && id) + /* This applies for enums declared as + * typedef enum {A} E; + */ tt.id = id; Specifier spec; - auto stag = declareTag(tt, spec); - if (tt.tok == TOK.enum_) - { - isalias = false; - s = new AST.AliasDeclaration(token.loc, id, stag); - } + declareTag(tt, spec); } } if (isalias) diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index 622e286..7a800bd 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -1459,9 +1459,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (sym) { import dmd.access : symbolIsVisible; - if (!symbolIsVisible(sc, sym)) + if (!symbolIsVisible(sc, sym) && !sym.errors) + { imp.mod.error(imp.loc, "member `%s` is not visible from module `%s`", imp.names[i].toChars(), sc._module.toChars()); + sym.errors = true; + } ad.dsymbolSemantic(sc); // If the import declaration is in non-root module, // analysis of the aliased symbol is deferred. @@ -2231,11 +2234,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (!(sc.flags & SCOPE.Cfile)) // C enum remains incomplete until members are done ed.semanticRun = PASS.semanticdone; - // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint - // Deprecated in 2.100 - // Make an error in 2.110 - if (sc.stc & STC.scope_) - deprecation(ed.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site."); + version (none) + { + // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint + // Deprecated in 2.100 + // Make an error in 2.110 + if (sc.stc & STC.scope_) + deprecation(ed.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site."); + } Scope* sce; if (ed.isAnonymous()) @@ -3176,6 +3182,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor funcdecl.skipCodegen = true; funcdecl._linkage = sc.linkage; + if (sc.flags & SCOPE.Cfile && funcdecl.isFuncLiteralDeclaration()) + funcdecl._linkage = LINK.d; // so they are uniquely mangled + if (auto fld = funcdecl.isFuncLiteralDeclaration()) { if (fld.treq) @@ -3460,77 +3469,10 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (funcdecl.isAbstract() && funcdecl.isFinalFunc()) funcdecl.error("cannot be both `final` and `abstract`"); - version (none) - { - if (funcdecl.isAbstract() && funcdecl.fbody) - funcdecl.error("`abstract` functions cannot have bodies"); - } - - version (none) - { - if (funcdecl.isStaticConstructor() || funcdecl.isStaticDestructor()) - { - if (!funcdecl.isStatic() || funcdecl.type.nextOf().ty != Tvoid) - funcdecl.error("static constructors / destructors must be `static void`"); - if (f.arguments && f.arguments.length) - funcdecl.error("static constructors / destructors must have empty parameter list"); - // BUG: check for invalid storage classes - } - } if (funcdecl.printf || funcdecl.scanf) { - /* printf/scanf-like functions must be of the form: - * extern (C/C++) T printf([parameters...], const(char)* format, ...); - * or: - * extern (C/C++) T vprintf([parameters...], const(char)* format, va_list); - */ - - static bool isPointerToChar(Parameter p) - { - if (auto tptr = p.type.isTypePointer()) - { - return tptr.next.ty == Tchar; - } - return false; - } - - bool isVa_list(Parameter p) - { - return p.type.equals(target.va_listType(funcdecl.loc, sc)); - } - - const nparams = f.parameterList.length; - if ((f.linkage == LINK.c || f.linkage == LINK.cpp) && - - (f.parameterList.varargs == VarArg.variadic && - nparams >= 1 && - isPointerToChar(f.parameterList[nparams - 1]) || - - f.parameterList.varargs == VarArg.none && - nparams >= 2 && - isPointerToChar(f.parameterList[nparams - 2]) && - isVa_list(f.parameterList[nparams - 1]) - ) - ) - { - // the signature is valid for printf/scanf, no error - } - else - { - const p = (funcdecl.printf ? Id.printf : Id.scanf).toChars(); - if (f.parameterList.varargs == VarArg.variadic) - { - funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, ...)`" - ~ " not `%s`", - p, f.next.toChars(), funcdecl.toChars(), funcdecl.type.toChars()); - } - else - { - funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, va_list)`", - p, f.next.toChars(), funcdecl.toChars()); - } - } + checkPrintfScanfSignature(funcdecl, f, sc); } if (auto id = parent.isInterfaceDeclaration()) @@ -4869,11 +4811,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor sd.deferred.semantic3(sc); } - // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint - // Deprecated in 2.100 - // Make an error in 2.110 - if (sd.storage_class & STC.scope_) - deprecation(sd.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site."); + version (none) + { + // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint + // Deprecated in 2.100 + // Make an error in 2.110 + if (sd.storage_class & STC.scope_) + deprecation(sd.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site."); + } //printf("-StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", sd, sd.toPrettyChars(), sd.sizeok); } @@ -5538,12 +5483,15 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } //printf("-ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); - // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint - // Deprecated in 2.100 - // Make an error in 2.110 - // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036 - if (cldec.storage_class & STC.scope_) - deprecation(cldec.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site."); + version (none) + { + // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint + // Deprecated in 2.100 + // Make an error in 2.110 + // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036 + if (cldec.storage_class & STC.scope_) + deprecation(cldec.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site."); + } } override void visit(InterfaceDeclaration idec) @@ -5844,12 +5792,15 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } assert(idec.type.ty != Tclass || (cast(TypeClass)idec.type).sym == idec); - // @@@DEPRECATED_2.120@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint - // Deprecated in 2.087 - // Made an error in 2.100, but removal depends on `scope class` being removed too - // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036 - if (idec.storage_class & STC.scope_) - error(idec.loc, "`scope` as a type constraint is obsolete. Use `scope` at the usage site."); + version (none) + { + // @@@DEPRECATED_2.120@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint + // Deprecated in 2.087 + // Made an error in 2.100, but removal depends on `scope class` being removed too + // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036 + if (idec.storage_class & STC.scope_) + error(idec.loc, "`scope` as a type constraint is obsolete. Use `scope` at the usage site."); + } } } @@ -7386,3 +7337,64 @@ private void writeMixin(const(char)[] s, ref const Loc loc, ref int lines, ref O buf.writenl(); ++lines; } + +/** + * Check signature of `pragma(printf)` function, print error if invalid. + * + * printf/scanf-like functions must be of the form: + * extern (C/C++) T printf([parameters...], const(char)* format, ...); + * or: + * extern (C/C++) T vprintf([parameters...], const(char)* format, va_list); + * + * Params: + * funcdecl = function to check + * f = function type + * sc = scope + */ +void checkPrintfScanfSignature(FuncDeclaration funcdecl, TypeFunction f, Scope* sc) +{ + static bool isPointerToChar(Parameter p) + { + if (auto tptr = p.type.isTypePointer()) + { + return tptr.next.ty == Tchar; + } + return false; + } + + bool isVa_list(Parameter p) + { + return p.type.equals(target.va_listType(funcdecl.loc, sc)); + } + + const nparams = f.parameterList.length; + const p = (funcdecl.printf ? Id.printf : Id.scanf).toChars(); + if (!(f.linkage == LINK.c || f.linkage == LINK.cpp)) + { + .error(funcdecl.loc, "`pragma(%s)` function `%s` must have `extern(C)` or `extern(C++)` linkage," + ~" not `extern(%s)`", + p, funcdecl.toChars(), f.linkage.linkageToChars()); + } + if (f.parameterList.varargs == VarArg.variadic) + { + if (!(nparams >= 1 && isPointerToChar(f.parameterList[nparams - 1]))) + { + .error(funcdecl.loc, "`pragma(%s)` function `%s` must have" + ~ " signature `%s %s([parameters...], const(char)*, ...)` not `%s`", + p, funcdecl.toChars(), f.next.toChars(), funcdecl.toChars(), funcdecl.type.toChars()); + } + } + else if (f.parameterList.varargs == VarArg.none) + { + if(!(nparams >= 2 && isPointerToChar(f.parameterList[nparams - 2]) && + isVa_list(f.parameterList[nparams - 1]))) + .error(funcdecl.loc, "`pragma(%s)` function `%s` must have"~ + " signature `%s %s([parameters...], const(char)*, va_list)`", + p, funcdecl.toChars(), f.next.toChars(), funcdecl.toChars()); + } + else + { + .error(funcdecl.loc, "`pragma(%s)` function `%s` must have C-style variadic `...` or `va_list` parameter", + p, funcdecl.toChars()); + } +} diff --git a/gcc/d/dmd/errors.d b/gcc/d/dmd/errors.d index 287dc49..1f7a78e 100644 --- a/gcc/d/dmd/errors.d +++ b/gcc/d/dmd/errors.d @@ -119,22 +119,32 @@ else package auto previewErrorFunc(bool isDeprecated, FeatureState featureState) @safe @nogc pure nothrow { - if (featureState == FeatureState.enabled) - return &error; - else if (featureState == FeatureState.disabled || isDeprecated) - return &noop; - else - return &deprecation; + with (FeatureState) final switch (featureState) + { + case enabled: + return &error; + + case disabled: + return &noop; + + case default_: + return isDeprecated ? &noop : &deprecation; + } } package auto previewSupplementalFunc(bool isDeprecated, FeatureState featureState) @safe @nogc pure nothrow { - if (featureState == FeatureState.enabled) - return &errorSupplemental; - else if (featureState == FeatureState.disabled || isDeprecated) - return &noop; - else - return &deprecationSupplemental; + with (FeatureState) final switch (featureState) + { + case enabled: + return &errorSupplemental; + + case disabled: + return &noop; + + case default_: + return isDeprecated ? &noop : &deprecationSupplemental; + } } diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 35f11af..9477867 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -2468,19 +2468,13 @@ extern (C++) class ThisExp : Expression return typeof(return)(true); } - override final bool isLvalue() + override bool isLvalue() { - // Class `this` should be an rvalue; struct `this` should be an lvalue. - return type.toBasetype().ty != Tclass; + return true; } - override final Expression toLvalue(Scope* sc, Expression e) + override Expression toLvalue(Scope* sc, Expression e) { - if (type.toBasetype().ty == Tclass) - { - // Class `this` is an rvalue; struct `this` is an lvalue. - return Expression.toLvalue(sc, e); - } return this; } @@ -2500,6 +2494,18 @@ extern (C++) final class SuperExp : ThisExp super(loc, EXP.super_); } + override bool isLvalue() + { + // Class `super` should be an rvalue + return false; + } + + override Expression toLvalue(Scope* sc, Expression e) + { + // Class `super` is an rvalue + return Expression.toLvalue(sc, e); + } + override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index 770c3e7..8c6393f 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -348,8 +348,8 @@ public: ThisExp *syntaxCopy() override; Optional<bool> toBool() override; - bool isLvalue() override final; - Expression *toLvalue(Scope *sc, Expression *e) override final; + bool isLvalue() override; + Expression *toLvalue(Scope *sc, Expression *e) override; void accept(Visitor *v) override { v->visit(this); } }; @@ -357,6 +357,8 @@ public: class SuperExp final : public ThisExp { public: + bool isLvalue() override; + Expression* toLvalue(Scope* sc, Expression* e) final override; void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index be597df..25f755b 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -3556,7 +3556,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor */ private void tryLowerToNewItem(NewExp ne) { - if (global.params.betterC || !sc.needsCodegen()) + if (!global.params.useGC || !sc.needsCodegen()) return; auto hook = global.params.tracegc ? Id._d_newitemTTrace : Id._d_newitemT; @@ -11069,7 +11069,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor /* `_d_arraycatnTX` canot be used with `-betterC`, but `CatExp`s may be * used with `-betterC`, but only during CTFE. */ - if (global.params.betterC || !sc.needsCodegen()) + if (!global.params.useGC || !sc.needsCodegen()) return; if (auto ce = exp.isCatExp()) diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index a714d2d..6045735 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -2019,7 +2019,8 @@ extern (C++) class FuncDeclaration : Declaration overloadApply(cast() this, (Dsymbol s) { auto f = s.isFuncDeclaration(); - if (!f) + auto td = s.isTemplateDeclaration(); + if (!f && !td) return 0; if (result) { @@ -2243,7 +2244,7 @@ extern (C++) class FuncDeclaration : Declaration if (global.gag) // need not report supplemental errors return true; } - else if (global.params.betterC) + else if (!global.params.useGC) { error("is `-betterC` yet allocates closure for `%s()` with the GC", toChars()); if (global.gag) // need not report supplemental errors @@ -4605,16 +4606,15 @@ bool setUnsafe(Scope* sc, bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)* msg, RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null) { - if (fs == FeatureState.disabled) + with (FeatureState) final switch (fs) { + case disabled: return false; - } - else if (fs == FeatureState.enabled) - { + + case enabled: return sc.setUnsafe(gag, loc, msg, arg0, arg1, arg2); - } - else - { + + case default_: if (!sc.func) return false; if (sc.func.isSafeBypassingInference()) diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d index 0ac6042..9071e6a 100644 --- a/gcc/d/dmd/globals.d +++ b/gcc/d/dmd/globals.d @@ -81,11 +81,11 @@ enum CppStdRevision : uint } /// Trivalent boolean to represent the state of a `revert`able change -enum FeatureState : byte +enum FeatureState : ubyte { - default_ = -1, /// Not specified by the user - disabled = 0, /// Specified as `-revert=` - enabled = 1 /// Specified as `-preview=` + default_ = 0, /// Not specified by the user + disabled = 1, /// Specified as `-revert=` + enabled = 2, /// Specified as `-preview=` } extern(C++) struct Output @@ -124,6 +124,7 @@ extern (C++) struct Param bool release; // build release version bool preservePaths; // true means don't strip path from source file DiagnosticReporting warnings = DiagnosticReporting.off; // how compiler warnings are handled + bool obsolete; // enable warnings about use of obsolete messages bool color; // use ANSI colors in console output bool cov; // generate code coverage data ubyte covPercent; // 0..100 code coverage percentage required @@ -132,6 +133,7 @@ extern (C++) struct Param bool useModuleInfo = true; // generate runtime module information bool useTypeInfo = true; // generate runtime type information bool useExceptions = true; // support exception handling + bool useGC = true; // support features that require the GC bool betterC; // be a "better C" compiler; no dependency on D runtime bool addMain; // add a default main() function bool allInst; // generate code for all template instantiations diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index 66345ac..0dad5dd 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -75,11 +75,11 @@ enum CppStdRevision }; /// Trivalent boolean to represent the state of a `revert`able change -enum class FeatureState : signed char +enum class FeatureState : unsigned char { - default_ = -1, /// Not specified by the user - disabled = 0, /// Specified as `-revert=` - enabled = 1 /// Specified as `-preview=` + default_ = 0, /// Not specified by the user + disabled = 1, /// Specified as `-revert=` + enabled = 2, /// Specified as `-preview=` }; struct Output @@ -119,6 +119,7 @@ struct Param d_bool release; // build release version d_bool preservePaths; // true means don't strip path from source file Diagnostic warnings; + d_bool obsolete; // warn about use of obsolete features d_bool color; // use ANSI colors in console output d_bool cov; // generate code coverage data unsigned char covPercent; // 0..100 code coverage percentage required @@ -127,6 +128,7 @@ struct Param d_bool useModuleInfo; // generate runtime module information d_bool useTypeInfo; // generate runtime type information d_bool useExceptions; // support exception handling + d_bool useGC; // support features that require the GC d_bool betterC; // be a "better C" compiler; no dependency on D runtime d_bool addMain; // add a default main() function d_bool allInst; // generate code for all template instantiations @@ -263,6 +265,7 @@ struct CompileEnv bool previewIn; bool ddocOutput; bool shortenedMethods; + bool obsolete; }; struct Global diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d index ee288d1..c60b431 100644 --- a/gcc/d/dmd/initsem.d +++ b/gcc/d/dmd/initsem.d @@ -772,10 +772,13 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ const nfields = sd.fields.length; size_t fieldi = 0; + Loop1: for (size_t index = 0; index < ci.initializerList.length; ) { - auto di = ci.initializerList[index]; - auto dlist = di.designatorList; + CInitializer cprev; + L1: + DesigInit di = ci.initializerList[index]; + Designators* dlist = di.designatorList; if (dlist) { const length = (*dlist).length; @@ -798,9 +801,19 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ si.addInit(id, di.initializer); ++fieldi; ++index; - break; + continue Loop1; } } + if (cprev) + { + /* The peeling didn't work, so unpeel it + */ + ci = cprev; + di = ci.initializerList[index]; + goto L2; + } + error(ci.loc, "`.%s` is not a field of `%s`\n", id.toChars(), sd.toChars()); + return err(); } else { @@ -808,10 +821,14 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ break; if (index == 0 && ci.initializerList.length == 1 && di.initializer.isCInitializer()) { + /* Try peeling off this set of { } and see if it works + */ + cprev = ci; ci = di.initializer.isCInitializer(); - continue; + goto L1; } + L2: VarDeclaration field; while (1) // skip field if it overlaps with previously seen fields { diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index add1ce6..9cce7c5 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -51,6 +51,7 @@ struct CompileEnv bool previewIn; /// `in` means `[ref] scope const`, accepts rvalues bool ddocOutput; /// collect embedded documentation comments bool shortenedMethods = true; /// allow => in normal function declarations + bool obsolete; /// warn on use of legacy code } /*********************************************************** diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d index 9a8f242..d7a2820 100644 --- a/gcc/d/dmd/nogc.d +++ b/gcc/d/dmd/nogc.d @@ -219,7 +219,7 @@ Expression checkGC(Scope* sc, Expression e) * Just don't generate code for it. * Detect non-CTFE use of the GC in betterC code. */ - const betterC = global.params.betterC; + const betterC = !global.params.useGC; FuncDeclaration f = sc.func; if (e && e.op != EXP.error && f && sc.intypeof != 1 && (!(sc.flags & SCOPE.ctfe) || betterC) && diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index eeaef8d..d15e448 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -718,13 +718,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer tk.value == TOK.out_ || tk.value == TOK.do_ || tk.value == TOK.goesTo || tk.value == TOK.identifier && tk.ident == Id._body)) { - // @@@DEPRECATED_2.117@@@ - // https://github.com/dlang/DIPs/blob/1f5959abe482b1f9094f6484a7d0a3ade77fc2fc/DIPs/accepted/DIP1003.md - // Deprecated in 2.097 - Can be removed from 2.117 - // The deprecation period is longer than usual as `body` - // was quite widely used. if (tk.value == TOK.identifier && tk.ident == Id._body) - deprecation("usage of the `body` keyword is deprecated. Use `do` instead."); + usageOfBodyKeyword(); a = parseDeclarations(true, pAttrs, pAttrs.comment); if (a && a.length) @@ -1163,7 +1158,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer a = parseDeclDefs(0, pLastDecl); if (token.value != TOK.rightCurly) { - /* { */ + /* left curly brace */ error("matching `}` expected, not `%s`", token.toChars()); eSink.errorSupplemental(lcLoc, "unmatched `{`"); } @@ -1505,7 +1500,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer if (token.value != TOK.leftCurly) { - error("`{` expected after template parameter list, not `%s`", token.toChars()); + error("`{` expected after template parameter list, not `%s`", token.toChars()); /* } */ goto Lerr; } decldefs = parseBlock(null); @@ -2724,7 +2719,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer nextToken(); - const(char)* begPtr = token.ptr + 1; // skip '{' + const(char)* begPtr = token.ptr + 1; // skip left curly brace const(char)* endPtr = null; AST.Statement sbody = parseStatement(ParseStatementFlags.curly, &endPtr); @@ -3041,6 +3036,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } e = new AST.EnumDeclaration(loc, id, memtype); + // opaque type if (token.value == TOK.semicolon && id) nextToken(); else if (token.value == TOK.leftCurly) @@ -3073,7 +3069,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer && token.value != TOK.comma && token.value != TOK.assign) { - switch(token.value) + switch (token.value) { case TOK.at: if (StorageClass _stc = parseAttribute(udas)) @@ -3109,12 +3105,23 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } else { - goto default; + if (isAnonymousEnum) + goto default; // maybe `Type identifier` + + prevTOK = token.value; + nextToken(); + error("expected `,` or `=` after identifier, not `%s`", token.toChars()); } break; default: if (isAnonymousEnum) { + if (type) + { + error("expected identifier after type, not `%s`", token.toChars()); + type = null; + break; + } type = parseType(&ident, null); if (type == AST.Type.terror) { @@ -3125,6 +3132,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer else { prevTOK = TOK.identifier; + const tv = token.value; + if (ident && tv != TOK.assign && tv != TOK.comma && tv != TOK.rightCurly) + { + error("expected `,` or `=` after identifier, not `%s`", token.toChars()); + } } } else @@ -3166,7 +3178,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { value = null; if (type && type != AST.Type.terror && isAnonymousEnum) - error("if type, there must be an initializer"); + error("initializer required after `%s` when type is specified", ident.toChars()); } AST.DeprecatedDeclaration dd; @@ -3471,6 +3483,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer return decldefs; } + /* Parse a type and optional identifier + * Params: + * pident = set to Identifier if there is one, null if not + * ptpl = if !null, then set to TemplateParameterList + */ AST.Type parseType(Identifier* pident = null, AST.TemplateParameters** ptpl = null) { /* Take care of the storage class prefixes that @@ -4450,13 +4467,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer (tk.value == TOK.leftParenthesis || tk.value == TOK.leftCurly || tk.value == TOK.in_ || tk.value == TOK.out_ || tk.value == TOK.goesTo || tk.value == TOK.do_ || tk.value == TOK.identifier && tk.ident == Id._body)) { - // @@@DEPRECATED_2.117@@@ - // https://github.com/dlang/DIPs/blob/1f5959abe482b1f9094f6484a7d0a3ade77fc2fc/DIPs/accepted/DIP1003.md - // Deprecated in 2.097 - Can be removed from 2.117 - // The deprecation period is longer than usual as `body` - // was quite widely used. if (tk.value == TOK.identifier && tk.ident == Id._body) - deprecation("usage of the `body` keyword is deprecated. Use `do` instead."); + usageOfBodyKeyword(); ts = null; } @@ -4569,6 +4581,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } else if (t.ty == Tfunction) { + if (storage_class & STC.manifest) + error("function cannot have enum storage class"); + AST.Expression constraint = null; //printf("%s funcdecl t = %s, storage_class = x%lx\n", loc.toChars(), t.toChars(), storage_class); auto f = new AST.FuncDeclaration(loc, Loc.initial, ident, storage_class | (disable ? STC.disable : 0), t); @@ -5193,12 +5208,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer case TOK.identifier: if (token.ident == Id._body) { - // @@@DEPRECATED_2.117@@@ - // https://github.com/dlang/DIPs/blob/1f5959abe482b1f9094f6484a7d0a3ade77fc2fc/DIPs/accepted/DIP1003.md - // Deprecated in 2.097 - Can be removed from 2.117 - // The deprecation period is longer than usual as `body` - // was quite widely used. - deprecation("usage of the `body` keyword is deprecated. Use `do` instead."); + usageOfBodyKeyword(); goto case TOK.do_; } goto default; @@ -6027,7 +6037,7 @@ LagainStc: auto statements = new AST.Statements(); while (token.value != TOK.rightCurly && token.value != TOK.endOfFile) { - statements.push(parseStatement(ParseStatementFlags.curlyScope)); + statements.push(parseStatement(ParseStatementFlags.curlyScope | ParseStatementFlags.semiOk)); } if (endPtr) *endPtr = token.ptr; @@ -7572,12 +7582,7 @@ LagainStc: case TOK.identifier: if (t.ident == Id._body) { - // @@@DEPRECATED_2.117@@@ - // https://github.com/dlang/DIPs/blob/1f5959abe482b1f9094f6484a7d0a3ade77fc2fc/DIPs/accepted/DIP1003.md - // Deprecated in 2.097 - Can be removed from 2.117 - // The deprecation period is longer than usual as `body` - // was quite widely used. - deprecation("usage of the `body` keyword is deprecated. Use `do` instead."); + usageOfBodyKeyword(); goto case TOK.do_; } goto default; @@ -8806,6 +8811,7 @@ LagainStc: { // (type) una_exp nextToken(); + // Note: `t` may be an expression that looks like a type auto t = parseType(); check(TOK.rightParenthesis); @@ -8823,6 +8829,16 @@ LagainStc: te.parens = true; e = parsePostExp(te); } + else if (token.value == TOK.leftParenthesis || + token.value == TOK.plusPlus || token.value == TOK.minusMinus) + { + // (type)(expr) + // (callable)(args) + // (expr)++ + auto te = new AST.TypeExp(loc, t); + te.parens = true; + e = parsePostExp(te); + } else { e = parseUnaryExp(); @@ -9526,6 +9542,14 @@ LagainStc: STC.live | /*STC.future |*/ // probably should be included STC.disable; + + void usageOfBodyKeyword() + { + if (compileEnv.obsolete) + { + eSink.warning(token.loc, "usage of identifer `body` as a keyword is obsolete. Use `do` instead."); + } + } } enum PREC : int diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index e4ca22a..c7d1219 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -1422,7 +1422,8 @@ private extern(C++) final class Semantic3Visitor : Visitor * https://issues.dlang.org/show_bug.cgi?id=14246 */ AggregateDeclaration ad = ctor.isMemberDecl(); - if (!ctor.fbody || !ad || !ad.fieldDtor || !global.params.dtorFields || !global.params.useExceptions || ctor.type.toTypeFunction.isnothrow) + if (!ctor.fbody || !ad || !ad.fieldDtor || + global.params.dtorFields == FeatureState.disabled || !global.params.useExceptions || ctor.type.toTypeFunction.isnothrow) return visit(cast(FuncDeclaration)ctor); /* Generate: diff --git a/gcc/d/dmd/target.d b/gcc/d/dmd/target.d index fddfd54..81ff84f 100644 --- a/gcc/d/dmd/target.d +++ b/gcc/d/dmd/target.d @@ -25,7 +25,7 @@ module dmd.target; -import dmd.globals : Param; +import dmd.globals : Param, CHECKENABLE; enum CPU : ubyte { @@ -111,7 +111,7 @@ extern (C++) struct Target /// Architecture name const(char)[] architectureName; CPU cpu = CPU.baseline; // CPU instruction set to target - bool is64bit; // generate 64 bit code for x86_64; true by default for 64 bit dmd + bool isX86_64; // generate 64 bit code for x86_64; true by default for 64 bit dmd bool isLP64; // pointers are 64 bits // Environmental diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h index 561afa1..ca0e09c 100644 --- a/gcc/d/dmd/target.h +++ b/gcc/d/dmd/target.h @@ -156,7 +156,7 @@ struct Target DString architectureName; // name of the platform architecture (e.g. X86_64) CPU cpu; // CPU instruction set to target - d_bool is64bit; // generate 64 bit code for x86_64; true by default for 64 bit dmd + d_bool isX86_64; // generate 64 bit code for x86_64; true by default for 64 bit dmd d_bool isLP64; // pointers are 64 bits // Environmental diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index caebf1c..0d9c95f 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -947,15 +947,24 @@ Expression semanticTraits(TraitsExp e, Scope* sc) */ Dsymbol sym = getDsymbol(o); + + if (sym && e.ident == Id.hasMember) + { + if (auto sm = sym.search(e.loc, id)) + return True(); + + // https://issues.dlang.org/show_bug.cgi?id=23951 + if (auto decl = sym.isDeclaration()) + { + ex = typeDotIdExp(e.loc, decl.type, id); + goto doSemantic; + } + } + if (auto t = isType(o)) ex = typeDotIdExp(e.loc, t, id); else if (sym) { - if (e.ident == Id.hasMember) - { - if (auto sm = sym.search(e.loc, id)) - return True(); - } ex = new DsymbolExp(e.loc, sym); ex = new DotIdExp(e.loc, ex, id); } @@ -966,7 +975,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) e.error("invalid first argument"); return ErrorExp.get(); } - + doSemantic: // ignore symbol visibility and disable access checks for these traits Scope* scx = sc.push(); scx.flags |= SCOPE.ignoresymbolvisibility | SCOPE.noaccesscheck; @@ -1223,7 +1232,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) // @@@DEPRECATION 2.100.2 if (auto td = s.isTemplateDeclaration()) { - if (td.overnext || td.funcroot) + if (td.overnext || td.overroot) { deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not the overload set `%s`", td.ident.toChars()); deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from"); |