aboutsummaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2023-08-15 16:29:08 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2023-08-20 11:20:00 +0200
commitd77c280454cfba48ef38357145cecdabc8c1b05c (patch)
tree49e02afce6ab03a3405752c963b6ffb225012a40 /gcc/d
parentce33bbfcbc7dd3afc6c96fb48a19ed00f0c598ce (diff)
downloadgcc-d77c280454cfba48ef38357145cecdabc8c1b05c.zip
gcc-d77c280454cfba48ef38357145cecdabc8c1b05c.tar.gz
gcc-d77c280454cfba48ef38357145cecdabc8c1b05c.tar.bz2
d: Merge upstream dmd, druntime 26f049fb26, phobos 330d6a4fd.
D front-end changes: - Import dmd v2.105.0-beta.1. - Added predefined version identifier VisionOS (ignored by GDC). - Functions can no longer have `enum` storage class. - The deprecation of the `body` keyword has been reverted, it is now an obsolete feature. - The error for `scope class` has been reverted, it is now an obsolete feature. D runtime changes: - Import druntime v2.105.0-beta.1. Phobos changes: - Import phobos v2.105.0-beta.1. - AliasSeq has been removed from std.math. - extern(C) getdelim and getline have been removed from std.stdio. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 26f049fb26. * dmd/VERSION: Bump version to v2.105.0-beta.1. * d-codegen.cc (get_frameinfo): Check useGC in condition. * d-lang.cc (d_handle_option): Set obsolete parameter when compiling with -Wall. (d_post_options): Set useGC to false when compiling with -fno-druntime. Propagate obsolete flag to compileEnv. * expr.cc (ExprVisitor::visit (CatExp *)): Check useGC in condition. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 26f049fb26. * src/MERGE: Merge upstream phobos 330d6a4fd.
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/d-codegen.cc2
-rw-r--r--gcc/d/d-lang.cc3
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/VERSION2
-rw-r--r--gcc/d/dmd/clone.d2
-rw-r--r--gcc/d/dmd/common/string.d2
-rw-r--r--gcc/d/dmd/cond.d1
-rw-r--r--gcc/d/dmd/cparse.d10
-rw-r--r--gcc/d/dmd/dsymbolsem.d194
-rw-r--r--gcc/d/dmd/errors.d34
-rw-r--r--gcc/d/dmd/expression.d24
-rw-r--r--gcc/d/dmd/expression.h6
-rw-r--r--gcc/d/dmd/expressionsem.d4
-rw-r--r--gcc/d/dmd/func.d18
-rw-r--r--gcc/d/dmd/globals.d10
-rw-r--r--gcc/d/dmd/globals.h11
-rw-r--r--gcc/d/dmd/initsem.d25
-rw-r--r--gcc/d/dmd/lexer.d1
-rw-r--r--gcc/d/dmd/nogc.d2
-rw-r--r--gcc/d/dmd/parse.d86
-rw-r--r--gcc/d/dmd/semantic3.d3
-rw-r--r--gcc/d/dmd/target.d4
-rw-r--r--gcc/d/dmd/target.h2
-rw-r--r--gcc/d/dmd/traits.d23
-rw-r--r--gcc/d/expr.cc2
25 files changed, 281 insertions, 192 deletions
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 2738958..155f5d0 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -2850,7 +2850,7 @@ get_frameinfo (FuncDeclaration *fd)
/* This can shift due to templates being expanded that access alias
symbols, give it a decent error for now. */
if (requiresClosure != fd->requiresClosure
- && (fd->nrvo_var || global.params.betterC))
+ && (fd->nrvo_var || !global.params.useGC))
fd->checkClosure ();
/* Set-up a closure frame, this will be allocated on the heap. */
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index 7cb86bf..10b9000 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -779,6 +779,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
case OPT_Wall:
if (value)
global.params.warnings = DIAGNOSTICinform;
+ global.params.obsolete = value;
break;
case OPT_Wdeprecated:
@@ -894,6 +895,7 @@ d_post_options (const char ** fn)
flag_exceptions = false;
}
+ global.params.useGC = false;
global.params.checkAction = CHECKACTION_C;
}
@@ -939,6 +941,7 @@ d_post_options (const char ** fn)
global.compileEnv.previewIn = global.params.previewIn;
global.compileEnv.ddocOutput = global.params.ddoc.doOutput;
global.compileEnv.shortenedMethods = global.params.shortenedMethods;
+ global.compileEnv.obsolete = global.params.obsolete;
/* Add in versions given on the command line. */
if (global.params.versionids)
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");
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 8fb1eea..7038655 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -695,7 +695,7 @@ public:
{
/* This error is only emitted during the code generation pass because
concatentation is allowed in CTFE. */
- if (global.params.betterC)
+ if (!global.params.useGC)
{
error_at (make_location_t (e->loc),
"array concatenation of expression %qs requires the GC and "