From 8f5439bea30bd2370638261ec7613628c8918d7d Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Thu, 7 Mar 2019 16:57:23 +0000 Subject: [PATCH] d/dmd: Merge upstream dmd d517c0e6a Fixes https://gcc.gnu.org/PR89016 Reviewed-on: https://github.com/dlang/dmd/pull/9427 From-SVN: r269465 --- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/attrib.c | 108 ++++++------------ gcc/d/dmd/dimport.c | 4 + gcc/d/dmd/dmodule.c | 12 +- gcc/d/dmd/expression.c | 37 ++++++ gcc/d/dmd/expressionsem.c | 50 ++------ gcc/d/dmd/statement.c | 52 ++++----- .../gdc.test/compilable/imports/test19609a.d | 1 + .../gdc.test/compilable/imports/test19609b.d | 1 + .../gdc.test/compilable/imports/test19609c.d | 1 + .../fail12567.d => compilable/test12567e.d} | 1 - gcc/testsuite/gdc.test/compilable/test19609.d | 12 ++ .../gdc.test/fail_compilation/fail19609.d | 18 +++ .../fail_compilation/imports/fail19609a.d | 1 + .../fail_compilation/imports/fail19609b.d | 1 + .../fail_compilation/imports/fail19609c.d | 1 + 16 files changed, 151 insertions(+), 151 deletions(-) create mode 100644 gcc/testsuite/gdc.test/compilable/imports/test19609a.d create mode 100644 gcc/testsuite/gdc.test/compilable/imports/test19609b.d create mode 100644 gcc/testsuite/gdc.test/compilable/imports/test19609c.d rename gcc/testsuite/gdc.test/{fail_compilation/fail12567.d => compilable/test12567e.d} (54%) create mode 100644 gcc/testsuite/gdc.test/compilable/test19609.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail19609.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/fail19609a.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/fail19609b.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/fail19609c.d diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 97aa40d1ace..3f416dbfb7b 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -ed71446aaa2bd0e548c3bf2154a638826dfe3db0 +d517c0e6a10b548f44d82b71b3c079663cb94f8e 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/attrib.c b/gcc/d/dmd/attrib.c index e4ad5739e73..a6686381485 100644 --- a/gcc/d/dmd/attrib.c +++ b/gcc/d/dmd/attrib.c @@ -30,6 +30,7 @@ bool definitelyValueParameter(Expression *e); Expression *semantic(Expression *e, Scope *sc); +StringExp *semanticString(Scope *sc, Expression *exp, const char *s); /********************************* AttribDeclaration ****************************/ @@ -977,41 +978,29 @@ void PragmaDeclaration::semantic(Scope *sc) error("string expected for library name"); else { - Expression *e = (*args)[0]; - - sc = sc->startCTFE(); - e = ::semantic(e, sc); - e = resolveProperties(sc, e); - sc = sc->endCTFE(); - - e = e->ctfeInterpret(); - (*args)[0] = e; - if (e->op == TOKerror) - goto Lnodecl; - StringExp *se = e->toStringExp(); + StringExp *se = semanticString(sc, (*args)[0], "library name"); if (!se) - error("string expected for library name, not '%s'", e->toChars()); - else + goto Lnodecl; + (*args)[0] = se; + + char *name = (char *)mem.xmalloc(se->len + 1); + memcpy(name, se->string, se->len); + name[se->len] = 0; + if (global.params.verbose) + message("library %s", name); + if (global.params.moduleDeps && !global.params.moduleDepsFile) { - char *name = (char *)mem.xmalloc(se->len + 1); - memcpy(name, se->string, se->len); - name[se->len] = 0; - if (global.params.verbose) - message("library %s", name); - if (global.params.moduleDeps && !global.params.moduleDepsFile) - { - OutBuffer *ob = global.params.moduleDeps; - Module *imod = sc->instantiatingModule(); - ob->writestring("depsLib "); - ob->writestring(imod->toPrettyChars()); - ob->writestring(" ("); - escapePath(ob, imod->srcfile->toChars()); - ob->writestring(") : "); - ob->writestring((char *) name); - ob->writenl(); - } - mem.xfree(name); + OutBuffer *ob = global.params.moduleDeps; + Module *imod = sc->instantiatingModule(); + ob->writestring("depsLib "); + ob->writestring(imod->toPrettyChars()); + ob->writestring(" ("); + escapePath(ob, imod->srcfile->toChars()); + ob->writestring(") : "); + ob->writestring((char *) name); + ob->writenl(); } + mem.xfree(name); } goto Lnodecl; } @@ -1053,19 +1042,11 @@ void PragmaDeclaration::semantic(Scope *sc) goto Ldecl; } - Expression *e = (*args)[0]; - e = ::semantic(e, sc); - e = e->ctfeInterpret(); - (*args)[0] = e; - if (e->op == TOKerror) - goto Ldecl; - - StringExp *se = e->toStringExp(); + StringExp *se = semanticString(sc, (*args)[0], "mangled name"); if (!se) - { - error("string expected for mangled name, not '%s'", e->toChars()); goto Ldecl; - } + (*args)[0] = se; // Will be used for later + if (!se->len) { error("zero-length string not allowed for mangled name"); @@ -1418,35 +1399,22 @@ void CompileDeclaration::setScope(Scope *sc) void CompileDeclaration::compileIt(Scope *sc) { //printf("CompileDeclaration::compileIt(loc = %d) %s\n", loc.linnum, exp->toChars()); - sc = sc->startCTFE(); - exp = ::semantic(exp, sc); - exp = resolveProperties(sc, exp); - sc = sc->endCTFE(); + StringExp *se = semanticString(sc, exp, "argument to mixin"); + if (!se) + return; + se = se->toUTF8(sc); + + unsigned errors = global.errors; + Parser p(loc, sc->_module, (utf8_t *)se->string, se->len, 0); + p.nextToken(); - if (exp->op != TOKerror) + decl = p.parseDeclDefs(0); + if (p.token.value != TOKeof) + exp->error("incomplete mixin declaration (%s)", se->toChars()); + if (p.errors) { - Expression *e = exp->ctfeInterpret(); - if (e->op == TOKerror) // Bugzilla 15974 - return; - StringExp *se = e->toStringExp(); - if (!se) - exp->error("argument to mixin must be a string, not (%s) of type %s", exp->toChars(), exp->type->toChars()); - else - { - se = se->toUTF8(sc); - unsigned errors = global.errors; - Parser p(loc, sc->_module, (utf8_t *)se->string, se->len, 0); - p.nextToken(); - - decl = p.parseDeclDefs(0); - if (p.token.value != TOKeof) - exp->error("incomplete mixin declaration (%s)", se->toChars()); - if (p.errors) - { - assert(global.errors != errors); - decl = NULL; - } - } + assert(global.errors != errors); + decl = NULL; } } diff --git a/gcc/d/dmd/dimport.c b/gcc/d/dmd/dimport.c index ad1e2d0463c..cd2c5b22a74 100644 --- a/gcc/d/dmd/dimport.c +++ b/gcc/d/dmd/dimport.c @@ -23,6 +23,8 @@ #include "attrib.h" #include "hdrgen.h" +StringExp *semanticString(Scope *sc, Expression *exp, const char *s); + /********************************* Import ****************************/ Import::Import(Loc loc, Identifiers *packages, Identifier *id, Identifier *aliasId, @@ -176,6 +178,8 @@ void Import::importAll(Scope *sc) if (mod->md && mod->md->isdeprecated) { Expression *msg = mod->md->msg; + if (msg) + msg = semanticString(sc, msg, "deprecation message"); if (StringExp *se = msg ? msg->toStringExp() : NULL) mod->deprecation(loc, "is deprecated - %s", se->string); else diff --git a/gcc/d/dmd/dmodule.c b/gcc/d/dmd/dmodule.c index 3b74446c9f5..20dbb69a91c 100644 --- a/gcc/d/dmd/dmodule.c +++ b/gcc/d/dmd/dmodule.c @@ -35,6 +35,7 @@ Dsymbols Module::deferred3; // deferred Dsymbol's needing semantic3() run on the unsigned Module::dprogress; const char *lookForSourceFile(const char **path, const char *filename); +StringExp *semanticString(Scope *sc, Expression *exp, const char *s); void Module::_init() { @@ -727,14 +728,6 @@ void Module::importAll(Scope *) return; } - if (md && md->msg) - { - if (StringExp *se = md->msg->toStringExp()) - md->msg = se; - else - md->msg->error("string expected, not '%s'", md->msg->toChars()); - } - /* Note that modules get their own scope, from scratch. * This is so regardless of where in the syntax a module * gets imported, it is unaffected by context. @@ -742,6 +735,9 @@ void Module::importAll(Scope *) */ Scope *sc = Scope::createGlobal(this); // create root scope + if (md && md->msg) + md->msg = semanticString(sc, md->msg, "deprecation message"); + // Add import of "object", even for the "object" module. // If it isn't there, some compiler rewrites, like // classinst == classinst -> .object.opEquals(classinst, classinst) diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c index cbc38195cca..df373925e09 100644 --- a/gcc/d/dmd/expression.c +++ b/gcc/d/dmd/expression.c @@ -6850,6 +6850,43 @@ Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, Expression **pe0) return ae; } +/*********************************************************** + * Resolve `exp` as a compile-time known string. + * Params: + * sc = scope + * exp = Expression which expected as a string + * s = What the string is expected for, will be used in error diagnostic. + * Returns: + * String literal, or `null` if error happens. + */ +StringExp *semanticString(Scope *sc, Expression *exp, const char *s) +{ + sc = sc->startCTFE(); + exp = semantic(exp, sc); + exp = resolveProperties(sc, exp); + sc = sc->endCTFE(); + + if (exp->op == TOKerror) + return NULL; + + Expression *e = exp; + if (exp->type->isString()) + { + e = e->ctfeInterpret(); + if (e->op == TOKerror) + return NULL; + } + + StringExp *se = e->toStringExp(); + if (!se) + { + exp->error("string expected for %s, not (%s) of type %s", + s, exp->toChars(), exp->type->toChars()); + return NULL; + } + return se; +} + /************************************** * Runs semantic on se->lwr and se->upr. Declares a temporary variable * if '$' was used. diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c index d5319e55a6e..3fd5c1fa33f 100644 --- a/gcc/d/dmd/expressionsem.c +++ b/gcc/d/dmd/expressionsem.c @@ -74,6 +74,7 @@ Expression *binSemanticProp(BinExp *e, Scope *sc); Expression *semantic(Expression *e, Scope *sc); Expression *semanticY(DotIdExp *exp, Scope *sc, int flag); Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag); +StringExp *semanticString(Scope *sc, Expression *exp, const char *s); /**************************************** * Preprocess arguments to function. @@ -2259,27 +2260,9 @@ public: void visit(CompileExp *exp) { - sc = sc->startCTFE(); - exp->e1 = semantic(exp->e1, sc); - exp->e1 = resolveProperties(sc, exp->e1); - sc = sc->endCTFE(); - if (exp->e1->op == TOKerror) - { - result = exp->e1; - return; - } - if (!exp->e1->type->isString()) - { - exp->error("argument to mixin must be a string type, not %s", exp->e1->type->toChars()); - return setError(); - } - exp->e1 = exp->e1->ctfeInterpret(); - StringExp *se = exp->e1->toStringExp(); + StringExp *se = semanticString(sc, exp->e1, "argument to mixin"); if (!se) - { - exp->error("argument to mixin must be a string, not (%s)", exp->e1->toChars()); return setError(); - } se = se->toUTF8(sc); unsigned errors = global.errors; Parser p(exp->loc, sc->_module, (utf8_t *)se->string, se->len, 0); @@ -2301,27 +2284,16 @@ public: void visit(ImportExp *e) { - const char *name; - StringExp *se; - - sc = sc->startCTFE(); - e->e1 = semantic(e->e1, sc); - e->e1 = resolveProperties(sc, e->e1); - sc = sc->endCTFE(); - e->e1 = e->e1->ctfeInterpret(); - if (e->e1->op != TOKstring) - { - e->error("file name argument must be a string, not (%s)", e->e1->toChars()); - goto Lerror; - } - se = (StringExp *)e->e1; + StringExp *se = semanticString(sc, e->e1, "file name argument"); + if (!se) + return setError(); se = se->toUTF8(sc); - name = (char *)se->string; + const char *name = (char *)se->string; if (!global.params.fileImppath) { e->error("need -Jpath switch to import text file %s", name); - goto Lerror; + return setError(); } /* Be wary of CWE-22: Improper Limitation of a Pathname to a Restricted Directory @@ -2333,7 +2305,7 @@ public: if (!name) { e->error("file %s cannot be found or not in a path specified with -J", se->toChars()); - goto Lerror; + return setError(); } if (global.params.verbose) @@ -2363,7 +2335,7 @@ public: if (f.read()) { e->error("cannot read file %s", f.toChars()); - goto Lerror; + return setError(); } else { @@ -2372,10 +2344,6 @@ public: } } result = semantic(se, sc); - return; - - Lerror: - return setError(); } void visit(AssertExp *exp) diff --git a/gcc/d/dmd/statement.c b/gcc/d/dmd/statement.c index 95bb77268a5..2d3a11237cb 100644 --- a/gcc/d/dmd/statement.c +++ b/gcc/d/dmd/statement.c @@ -31,6 +31,7 @@ StorageClass mergeFuncAttrs(StorageClass s1, FuncDeclaration *f); bool checkEscapeRef(Scope *sc, Expression *e, bool gag); VarDeclaration *copyToTemp(StorageClass stc, const char *name, Expression *e); Expression *semantic(Expression *e, Scope *sc); +StringExp *semanticString(Scope *sc, Expression *exp, const char *s); Identifier *fixupLabelName(Scope *sc, Identifier *ident) { @@ -487,45 +488,36 @@ Statement *CompileStatement::syntaxCopy() return new CompileStatement(loc, exp->syntaxCopy()); } +static Statements *errorStatements() +{ + Statements *a = new Statements(); + a->push(new ErrorStatement()); + return a; +} + Statements *CompileStatement::flatten(Scope *sc) { //printf("CompileStatement::flatten() %s\n", exp->toChars()); - sc = sc->startCTFE(); - exp = semantic(exp, sc); - exp = resolveProperties(sc, exp); - sc = sc->endCTFE(); + StringExp *se = semanticString(sc, exp, "argument to mixin"); + if (!se) + return errorStatements(); + se = se->toUTF8(sc); + + unsigned errors = global.errors; + Parser p(loc, sc->_module, (utf8_t *)se->string, se->len, 0); + p.nextToken(); Statements *a = new Statements(); - if (exp->op != TOKerror) + while (p.token.value != TOKeof) { - Expression *e = exp->ctfeInterpret(); - if (e->op == TOKerror) // Bugzilla 15974 - goto Lerror; - StringExp *se = e->toStringExp(); - if (!se) - error("argument to mixin must be a string, not (%s) of type %s", exp->toChars(), exp->type->toChars()); - else + Statement *s = p.parseStatement(PSsemi | PScurlyscope); + if (!s || p.errors) { - se = se->toUTF8(sc); - unsigned errors = global.errors; - Parser p(loc, sc->_module, (utf8_t *)se->string, se->len, 0); - p.nextToken(); - - while (p.token.value != TOKeof) - { - Statement *s = p.parseStatement(PSsemi | PScurlyscope); - if (!s || p.errors) - { - assert(!p.errors || global.errors != errors); // make sure we caught all the cases - goto Lerror; - } - a->push(s); - } - return a; + assert(!p.errors || global.errors != errors); // make sure we caught all the cases + return errorStatements(); } + a->push(s); } -Lerror: - a->push(new ErrorStatement()); return a; } diff --git a/gcc/testsuite/gdc.test/compilable/imports/test19609a.d b/gcc/testsuite/gdc.test/compilable/imports/test19609a.d new file mode 100644 index 00000000000..53d4f887027 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test19609a.d @@ -0,0 +1 @@ +deprecated([]) module imports.test19609a; diff --git a/gcc/testsuite/gdc.test/compilable/imports/test19609b.d b/gcc/testsuite/gdc.test/compilable/imports/test19609b.d new file mode 100644 index 00000000000..91e26e2862b --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test19609b.d @@ -0,0 +1 @@ +deprecated(['h','e','l','l','o']) module imports.test19609b; diff --git a/gcc/testsuite/gdc.test/compilable/imports/test19609c.d b/gcc/testsuite/gdc.test/compilable/imports/test19609c.d new file mode 100644 index 00000000000..789585d6c88 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test19609c.d @@ -0,0 +1 @@ +deprecated(null) module imports.test19609c; diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail12567.d b/gcc/testsuite/gdc.test/compilable/test12567e.d similarity index 54% rename from gcc/testsuite/gdc.test/fail_compilation/fail12567.d rename to gcc/testsuite/gdc.test/compilable/test12567e.d index e1ecd19fee1..14c72bc5afb 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail12567.d +++ b/gcc/testsuite/gdc.test/compilable/test12567e.d @@ -2,7 +2,6 @@ /* TEST_OUTPUT: --- -fail_compilation/fail12567.d(8): Error: string expected, not '"a" ~ "b"' --- */ deprecated("a" ~ "b") module fail12567; diff --git a/gcc/testsuite/gdc.test/compilable/test19609.d b/gcc/testsuite/gdc.test/compilable/test19609.d new file mode 100644 index 00000000000..a3d69233249 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test19609.d @@ -0,0 +1,12 @@ +// https://issues.dlang.org/show_bug.cgi?id=19609 +/* +TEST_OUTPUT +--- +compilable/test19609.d(10): Deprecation: module `imports.test19609a` is deprecated - +compilable/test19609.d(11): Deprecation: module `imports.test19609b` is deprecated - hello +compilable/test19609.d(12): Deprecation: module `imports.test19609c` is deprecated - +--- +*/ +import imports.test19609a; +import imports.test19609b; +import imports.test19609c; diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19609.d b/gcc/testsuite/gdc.test/fail_compilation/fail19609.d new file mode 100644 index 00000000000..64d080ac5d0 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail19609.d @@ -0,0 +1,18 @@ +// https://issues.dlang.org/show_bug.cgi?id=19609 +/* +TEST_OUTPUT +--- +fail_compilation/imports/fail19609a.d(1): Error: `string` expected for deprecation message, not `([""])` of type `string[]` +fail_compilation/fail19609.d(16): Deprecation: module `imports.fail19609a` is deprecated +fail_compilation/imports/fail19609a.d(1): Error: `string` expected for deprecation message, not `([""])` of type `string[]` +fail_compilation/imports/fail19609b.d(1): Error: `string` expected for deprecation message, not `([1])` of type `int[]` +fail_compilation/fail19609.d(17): Deprecation: module `imports.fail19609b` is deprecated +fail_compilation/imports/fail19609b.d(1): Error: `string` expected for deprecation message, not `([1])` of type `int[]` +fail_compilation/imports/fail19609c.d(1): Error: `string` expected for deprecation message, not `(123.4F)` of type `float` +fail_compilation/fail19609.d(18): Deprecation: module `imports.fail19609c` is deprecated +fail_compilation/imports/fail19609c.d(1): Error: `string` expected for deprecation message, not `(123.4F)` of type `float` +--- +*/ +import imports.fail19609a; +import imports.fail19609b; +import imports.fail19609c; diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/fail19609a.d b/gcc/testsuite/gdc.test/fail_compilation/imports/fail19609a.d new file mode 100644 index 00000000000..6cf5d61c063 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/fail19609a.d @@ -0,0 +1 @@ +deprecated([""]) module imports.fail19609a; diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/fail19609b.d b/gcc/testsuite/gdc.test/fail_compilation/imports/fail19609b.d new file mode 100644 index 00000000000..2ba62fe7e6f --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/fail19609b.d @@ -0,0 +1 @@ +deprecated([1]) module imports.fail19609b; diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/fail19609c.d b/gcc/testsuite/gdc.test/fail_compilation/imports/fail19609c.d new file mode 100644 index 00000000000..4aadb600fa8 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/fail19609c.d @@ -0,0 +1 @@ +deprecated(123.4f) module imports.fail19609c; -- 2.30.2