aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2021-01-25 13:50:55 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2021-01-26 09:54:57 +0100
commit5a36cae275ad84cc7e623f2f5829bdad767e3f6a (patch)
treece6b996b6cfcb1b1aa73bcc7786c07ef8df504b1 /gcc
parenteb77a934eec8fe52e4c5612f5264127290bc517d (diff)
downloadgcc-5a36cae275ad84cc7e623f2f5829bdad767e3f6a.zip
gcc-5a36cae275ad84cc7e623f2f5829bdad767e3f6a.tar.gz
gcc-5a36cae275ad84cc7e623f2f5829bdad767e3f6a.tar.bz2
d: Merge upstream dmd 609c3ce2d, phobos 3dd5df686
D front-end changes: - Contracts for pre- and postconditions are now implicitly "this" const, so that state can no longer be altered in these functions. - Inside a constructor scope, assigning to aggregate declaration members is done by considering the first assignment as initialization and subsequent assignments as modifications of the constructed object. For const/immutable fields the initialization is accepted in the constructor but subsequent modifications are not. However this rule did not apply when inside a constructor scope there is a call to a different constructor. This been changed so it is now an error when there's a double initialization of immutable fields inside a constructor. Phobos changes: - Don't run unit-tests for unsupported clocks in std.datetime. The phobos and phobos_shared tests now add -fversion=Linux_Pre_2639 if required. - Deprecate public extern(C) bindings for getline and getdelim in std.stdio. The correct module for bindings is core.sys.posix.stdio. Reviewed-on: https://github.com/dlang/dmd/pull/12153 https://github.com/dlang/phobos/pull/7768 gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 609c3ce2d. * d-compiler.cc (Compiler::loadModule): Rename to ... (Compiler::onParseModule): ... this. (Compiler::onImport): New function. * d-lang.cc (d_parse_file): Remove call to Compiler::loadModule. libphobos/ChangeLog: * src/MERGE: Merge upstream phobos 3dd5df686. * testsuite/libphobos.phobos/phobos.exp: Add compiler flag -fversion=Linux_Pre_2639 if target is linux_pre_2639. * testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/d/d-compiler.cc12
-rw-r--r--gcc/d/d-lang.cc1
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/compiler.h7
-rw-r--r--gcc/d/dmd/declaration.c14
-rw-r--r--gcc/d/dmd/dmodule.c12
-rw-r--r--gcc/d/dmd/expressionsem.c7
-rw-r--r--gcc/d/dmd/func.c2
-rw-r--r--gcc/d/dmd/root/array.h4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail18143.d43
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail18719.d41
11 files changed, 135 insertions, 10 deletions
diff --git a/gcc/d/d-compiler.cc b/gcc/d/d-compiler.cc
index 881d482..3907d01 100644
--- a/gcc/d/d-compiler.cc
+++ b/gcc/d/d-compiler.cc
@@ -157,7 +157,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
- core.stdc.*: For all gcc library builtins. */
void
-Compiler::loadModule (Module *m)
+Compiler::onParseModule (Module *m)
{
ModuleDeclaration *md = m->md;
@@ -180,3 +180,13 @@ Compiler::loadModule (Module *m)
d_add_builtin_module (m);
}
}
+
+/* A callback function that is called once an imported module is parsed.
+ If the callback returns true, then it tells the front-end that the
+ driver intends on compiling the import. */
+
+bool
+Compiler::onImport (Module *)
+{
+ return false;
+}
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index 72dcb71..0fd207d 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -980,7 +980,6 @@ d_parse_file (void)
m->importedFrom = m;
m->parse ();
- Compiler::loadModule (m);
if (m->isDocFile)
{
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 1f907b8..228eed8 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-3a7ebef73cc01d4a877a95cf95cd3776c9e3ee66
+609c3ce2d5d5d8a3dc4ba12c5e6e1100873f9ed1
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/compiler.h b/gcc/d/dmd/compiler.h
index 124829b..7f9006c 100644
--- a/gcc/d/dmd/compiler.h
+++ b/gcc/d/dmd/compiler.h
@@ -27,12 +27,17 @@ extern Module *entrypoint;
// Module in which the D main is
extern Module *rootHasMain;
+extern bool includeImports;
+// array of module patterns used to include/exclude imported modules
+extern Array<const char*> includeModulePatterns;
+extern Array<Module *> compiledImports;
+
struct Compiler
{
// CTFE support for cross-compilation.
static Expression *paintAsType(UnionExp *, Expression *, Type *);
// Backend
- static void loadModule(Module *);
static void genCmain(Scope *);
static bool onImport(Module *);
+ static void onParseModule(Module *);
};
diff --git a/gcc/d/dmd/declaration.c b/gcc/d/dmd/declaration.c
index 72a07d9b8..d20f663 100644
--- a/gcc/d/dmd/declaration.c
+++ b/gcc/d/dmd/declaration.c
@@ -145,6 +145,20 @@ int Declaration::checkModify(Loc loc, Scope *sc, Type *, Expression *e1, int fla
}
}
+ if (e1 && e1->op == TOKthis && isField())
+ {
+ VarDeclaration *vthis = e1->isThisExp()->var;
+ for (Scope *scx = sc; scx; scx = scx->enclosing)
+ {
+ if (scx->func == vthis->parent && (scx->flags & SCOPEcontract))
+ {
+ if (!flag)
+ error(loc, "cannot modify parameter `this` in contract");
+ return 2; // do not report type related errors
+ }
+ }
+ }
+
if (v && (isCtorinit() || isField()))
{
// It's only modifiable if inside the right constructor
diff --git a/gcc/d/dmd/dmodule.c b/gcc/d/dmd/dmodule.c
index 305b133..95c263f 100644
--- a/gcc/d/dmd/dmodule.c
+++ b/gcc/d/dmd/dmodule.c
@@ -375,8 +375,15 @@ Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
m = m->parse();
- Compiler::loadModule(m);
-
+ // Call onImport here because if the module is going to be compiled then we
+ // need to determine it early because it affects semantic analysis. This is
+ // being done after parsing the module so the full module name can be taken
+ // from whatever was declared in the file.
+ if (!m->isRoot() && Compiler::onImport(m))
+ {
+ m->importedFrom = m;
+ assert(m->isRoot());
+ }
return m;
}
@@ -736,6 +743,7 @@ Module *Module::parse()
// Add to global array of all modules
amodules.push(this);
}
+ Compiler::onParseModule(this);
return this;
}
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index a4ff0b4..7cebd9a 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -3344,6 +3344,13 @@ public:
return setError();
}
+ // https://issues.dlang.org/show_bug.cgi?id=18719
+ // If `exp` is a call expression to another constructor
+ // then it means that all struct/class fields will be
+ // initialized after this call.
+ for (size_t i = 0; i < sc->fieldinit_dim; i++)
+ sc->fieldinit[i] |= CSXthis_ctor;
+
if (!sc->intypeof && !(sc->callSuper & CSXhalt))
{
if (sc->noctor || sc->callSuper & CSXlabel)
diff --git a/gcc/d/dmd/func.c b/gcc/d/dmd/func.c
index f8f43dc..2f1d648 100644
--- a/gcc/d/dmd/func.c
+++ b/gcc/d/dmd/func.c
@@ -2181,7 +2181,6 @@ void FuncDeclaration::semantic3(Scope *sc)
sc2->flags = (sc2->flags & ~SCOPEcontract) | SCOPErequire;
// BUG: need to error if accessing out parameters
- // BUG: need to treat parameters as const
// BUG: need to disallow returns and throws
// BUG: verify that all in and ref parameters are read
freq = ::semantic(freq, sc2);
@@ -2213,7 +2212,6 @@ void FuncDeclaration::semantic3(Scope *sc)
sc2 = scout; //push
sc2->flags = (sc2->flags & ~SCOPEcontract) | SCOPEensure;
- // BUG: need to treat parameters as const
// BUG: need to disallow returns and throws
if (fensure && f->next->ty != Tvoid)
buildResultVar(scout, f->next);
diff --git a/gcc/d/dmd/root/array.h b/gcc/d/dmd/root/array.h
index d4eccd8..633414b 100644
--- a/gcc/d/dmd/root/array.h
+++ b/gcc/d/dmd/root/array.h
@@ -28,9 +28,9 @@ struct Array
public:
Array()
{
- data.ptr = SMALLARRAYCAP ? &smallarray[0] : NULL;
+ data.ptr = NULL;
length = 0;
- data.length = SMALLARRAYCAP;
+ data.length = 0;
}
~Array()
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail18143.d b/gcc/testsuite/gdc.test/fail_compilation/fail18143.d
new file mode 100644
index 0000000..28df93a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail18143.d
@@ -0,0 +1,43 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail18143.d(20): Error: variable `fail18143.S.a` cannot modify parameter `this` in contract
+fail_compilation/fail18143.d(21): Error: variable `fail18143.S.a` cannot modify parameter `this` in contract
+fail_compilation/fail18143.d(25): Error: variable `fail18143.S.a` cannot modify parameter `this` in contract
+fail_compilation/fail18143.d(26): Error: variable `fail18143.S.a` cannot modify parameter `this` in contract
+fail_compilation/fail18143.d(35): Error: variable `fail18143.C.a` cannot modify parameter `this` in contract
+fail_compilation/fail18143.d(36): Error: variable `fail18143.C.a` cannot modify parameter `this` in contract
+fail_compilation/fail18143.d(40): Error: variable `fail18143.C.a` cannot modify parameter `this` in contract
+fail_compilation/fail18143.d(41): Error: variable `fail18143.C.a` cannot modify parameter `this` in contract
+---
+*/
+
+struct S
+{
+ int a;
+
+ this(int n)
+ in { a = n; } // error, modifying this.a in contract
+ out { a = n; } // error, modifying this.a in contract
+ do { }
+
+ void foo(int n)
+ in { a = n; } // error, modifying this.a in contract
+ out { a = n; } // error, modifying this.a in contract
+ do { }
+}
+
+class C
+{
+ int a;
+
+ this(int n)
+ in { a = n; } // error, modifying this.a in contract
+ out { a = n; } // error, modifying this.a in contract
+ do { }
+
+ void foo(int n)
+ in { a = n; } // error, modifying this.a in contract
+ out { a = n; } // error, modifying this.a in contract
+ do { }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail18719.d b/gcc/testsuite/gdc.test/fail_compilation/fail18719.d
new file mode 100644
index 0000000..7d993d1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail18719.d
@@ -0,0 +1,41 @@
+// https://issues.dlang.org/show_bug.cgi?id=18719
+
+// REQUIRED_ARGS:
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail18719.d(30): Error: immutable field `x` initialized multiple times
+ Previous initialization is here.
+---
+*/
+
+struct S
+{
+ int x = -1;
+ this(int y) immutable
+ {
+ x = y;
+ import std.stdio;
+ writeln("Ctor called with ", y);
+ }
+ void opAssign(int) immutable;
+}
+
+class C
+{
+ S x;
+ this() immutable
+ {
+ this(42); /* Initializes x. */
+ x = 13; /* Breaking immutable, or ok? */
+ }
+ this(int x) immutable
+ {
+ this.x = x;
+ }
+}
+
+void main()
+{
+ new immutable C;
+}