Commit 8f5439be by Iain Buclaw

d/dmd: Merge upstream dmd d517c0e6a

Fixes https://gcc.gnu.org/PR89016

Reviewed-on: https://github.com/dlang/dmd/pull/9427

From-SVN: r269465
parent 59d9a0aa
ed71446aaa2bd0e548c3bf2154a638826dfe3db0
d517c0e6a10b548f44d82b71b3c079663cb94f8e
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
......@@ -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,22 +978,11 @@ 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;
......@@ -1012,7 +1002,6 @@ void PragmaDeclaration::semantic(Scope *sc)
}
mem.xfree(name);
}
}
goto Lnodecl;
}
else if (ident == Id::startaddress)
......@@ -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,22 +1399,11 @@ 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();
if (exp->op != TOKerror)
{
Expression *e = exp->ctfeInterpret();
if (e->op == TOKerror) // Bugzilla 15974
return;
StringExp *se = e->toStringExp();
StringExp *se = semanticString(sc, exp, "argument to mixin");
if (!se)
exp->error("argument to mixin must be a string, not (%s) of type %s", exp->toChars(), exp->type->toChars());
else
{
return;
se = se->toUTF8(sc);
unsigned errors = global.errors;
Parser p(loc, sc->_module, (utf8_t *)se->string, se->len, 0);
p.nextToken();
......@@ -1446,8 +1416,6 @@ void CompileDeclaration::compileIt(Scope *sc)
assert(global.errors != errors);
decl = NULL;
}
}
}
}
void CompileDeclaration::semantic(Scope *sc)
......
......@@ -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
......
......@@ -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)
......
......@@ -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.
......
......@@ -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)
......
......@@ -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,46 +488,37 @@ 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();
Statements *a = new Statements();
if (exp->op != TOKerror)
{
Expression *e = exp->ctfeInterpret();
if (e->op == TOKerror) // Bugzilla 15974
goto Lerror;
StringExp *se = e->toStringExp();
StringExp *se = semanticString(sc, exp, "argument to mixin");
if (!se)
error("argument to mixin must be a string, not (%s) of type %s", exp->toChars(), exp->type->toChars());
else
{
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();
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;
return errorStatements();
}
a->push(s);
}
return a;
}
}
Lerror:
a->push(new ErrorStatement());
return a;
}
/******************************** CompoundStatement ***************************/
......
deprecated([]) module imports.test19609a;
deprecated(['h','e','l','l','o']) module imports.test19609b;
deprecated(null) module imports.test19609c;
......@@ -2,7 +2,6 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail12567.d(8): Error: string expected, not '"a" ~ "b"'
---
*/
deprecated("a" ~ "b") module fail12567;
// 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;
// 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;
deprecated([""]) module imports.fail19609a;
deprecated([1]) module imports.fail19609b;
deprecated(123.4f) module imports.fail19609c;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment