d: Merge upstream dmd, druntime 17ccd12af3, phobos 8d3800bee.

D front-end changes:

	- Import dmd v2.104.0.
	- Assignment-style syntax is now allowed for `alias this'.
	- Overloading `extern(C)' functions is now an error.

D runtime changes:

	- Import druntime v2.104.0.

Phobos changes:

	- Import phobos v2.104.0.
	- Better static assert messages when instantiating
	`std.algorithm.iteration.permutations' with wrong inputs.
	- Added `std.system.instructionSetArchitecture' and
	  `std.system.ISA'.

gcc/d/ChangeLog:

	* dmd/MERGE: Merge upstream dmd 17ccd12af3.
	* dmd/VERSION: Bump version to v2.104.0.
	* Make-lang.in (D_FRONTEND_OBJS): Rename d/apply.o to
	d/postordervisitor.o.
	* d-codegen.cc (make_location_t): Update for new front-end interface.
	(build_filename_from_loc): Likewise.
	(build_assert_call): Likewise.
	(build_array_bounds_call): Likewise.
	(build_bounds_index_condition): Likewise.
	(build_bounds_slice_condition): Likewise.
	(build_frame_type): Likewise.
	(get_frameinfo): Likewise.
	* d-diagnostic.cc (d_diagnostic_report_diagnostic): Likewise.
	* decl.cc (build_decl_tree): Likewise.
	(start_function): Likewise.
	* expr.cc (ExprVisitor::visit (NewExp *)): Replace code generation of
	`new pointer' with front-end lowering.
	* runtime.def (NEWITEMT): Remove.
	(NEWITEMIT): Remove.
	* toir.cc (IRVisitor::visit (LabelStatement *)): Update for new
	front-end interface.
	* typeinfo.cc (check_typeinfo_type): Likewise.

libphobos/ChangeLog:

	* libdruntime/MERGE: Merge upstream druntime 17ccd12af3.
	* src/MERGE: Merge upstream phobos 8d3800bee.

gcc/testsuite/ChangeLog:

	* gdc.dg/asm4.d: Update test.
This commit is contained in:
Iain Buclaw 2023-07-10 03:07:41 +02:00
parent d41a57c46d
commit 0cafc3b627
147 changed files with 1849 additions and 929 deletions

View file

@ -81,7 +81,6 @@ D_FRONTEND_OBJS = \
d/access.o \
d/aggregate.o \
d/aliasthis.o \
d/apply.o \
d/arrayop.o \
d/arraytypes.o \
d/attrib.o \
@ -160,6 +159,7 @@ D_FRONTEND_OBJS = \
d/parse.o \
d/parsetimevisitor.o \
d/permissivevisitor.o \
d/postordervisitor.o \
d/printast.o \
d/root-aav.o \
d/root-array.o \

View file

@ -50,11 +50,11 @@ make_location_t (const Loc &loc)
{
location_t gcc_location = input_location;
if (loc.filename)
if (const char *filename = loc.filename ())
{
linemap_add (line_table, LC_ENTER, 0, loc.filename, loc.linnum);
linemap_line_start (line_table, loc.linnum, 0);
gcc_location = linemap_position_for_column (line_table, loc.charnum);
linemap_add (line_table, LC_ENTER, 0, filename, loc.linnum ());
linemap_line_start (line_table, loc.linnum (), 0);
gcc_location = linemap_position_for_column (line_table, loc.charnum ());
linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
}
@ -1872,8 +1872,10 @@ void_okay_p (tree t)
static tree
build_filename_from_loc (const Loc &loc)
{
const char *filename = loc.filename
? loc.filename : d_function_chain->module->srcfile.toChars ();
const char *filename = loc.filename ();
if (filename == NULL)
filename = d_function_chain->module->srcfile.toChars ();
unsigned length = strlen (filename);
tree str = build_string (length, filename);
@ -1890,17 +1892,17 @@ tree
build_assert_call (const Loc &loc, libcall_fn libcall, tree msg)
{
tree file;
tree line = size_int (loc.linnum);
tree line = size_int (loc.linnum ());
switch (libcall)
{
case LIBCALL_ASSERT_MSG:
case LIBCALL_UNITTEST_MSG:
/* File location is passed as a D string. */
if (loc.filename)
if (const char *filename = loc.filename ())
{
unsigned len = strlen (loc.filename);
tree str = build_string (len, loc.filename);
unsigned len = strlen (filename);
tree str = build_string (len, filename);
TREE_TYPE (str) = make_array_type (Type::tchar, len);
file = d_array_value (build_ctype (Type::tchar->arrayOf ()),
@ -1939,7 +1941,7 @@ build_array_bounds_call (const Loc &loc)
{
return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tvoid, 2,
build_filename_from_loc (loc),
size_int (loc.linnum));
size_int (loc.linnum ()));
}
}
@ -1968,7 +1970,8 @@ build_bounds_index_condition (IndexExp *ie, tree index, tree length)
{
boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tvoid, 4,
build_filename_from_loc (ie->e2->loc),
size_int (ie->e2->loc.linnum), index, length);
size_int (ie->e2->loc.linnum ()),
index, length);
}
return build_condition (TREE_TYPE (index), condition, boundserr, index);
@ -2017,7 +2020,7 @@ build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length)
boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP,
Type::tvoid, 5,
build_filename_from_loc (se->loc),
size_int (se->loc.linnum),
size_int (se->loc.linnum ()),
lower, upper, length);
}
@ -2659,8 +2662,8 @@ build_frame_type (tree ffi, FuncDeclaration *fd)
of the calling function non-locally. So we add all parameters with nested
refs to the function frame, this should also mean overriding methods will
have the same frame layout when inheriting a contract. */
if ((global.params.useIn == CHECKENABLEon && fd->frequire)
|| (global.params.useOut == CHECKENABLEon && fd->fensure))
if ((global.params.useIn == CHECKENABLEon && fd->frequire ())
|| (global.params.useOut == CHECKENABLEon && fd->fensure ()))
{
if (fd->parameters)
{
@ -2870,8 +2873,8 @@ get_frameinfo (FuncDeclaration *fd)
/* In checkNestedReference, references from contracts are not added to the
closureVars array, so assume all parameters referenced. */
if ((global.params.useIn == CHECKENABLEon && fd->frequire)
|| (global.params.useOut == CHECKENABLEon && fd->fensure))
if ((global.params.useIn == CHECKENABLEon && fd->frequire ())
|| (global.params.useOut == CHECKENABLEon && fd->fensure ()))
FRAMEINFO_CREATES_FRAME (ffi) = 1;
/* If however `fd` is nested (deeply) in a function that creates a

View file

@ -189,7 +189,7 @@ d_diagnostic_report_diagnostic (const Loc &loc, int opt, const char *format,
va_list argp;
va_copy (argp, ap);
if (loc.filename || !verbatim)
if (loc.filename () || !verbatim)
{
rich_location rich_loc (line_table, make_location_t (loc));
diagnostic_info diagnostic;

View file

@ -1083,7 +1083,7 @@ build_decl_tree (Dsymbol *d)
location_t saved_location = input_location;
/* Set input location, empty DECL_SOURCE_FILE can crash debug generator. */
if (d->loc.filename)
if (d->loc.filename ())
input_location = make_location_t (d->loc);
else
input_location = make_location_t (Loc ("<no_file>", 1, 0));
@ -2064,7 +2064,7 @@ start_function (FuncDeclaration *fd)
allocate_struct_function (fndecl, false);
/* Store the end of the function. */
if (fd->endloc.filename)
if (fd->endloc.filename ())
cfun->function_end_locus = make_location_t (fd->endloc);
else
cfun->function_end_locus = DECL_SOURCE_LOCATION (fndecl);

View file

@ -1,4 +1,4 @@
28a3b24c2e45de39cd3df528142fd06b6456e8fd
17ccd12af386543c0b9935bf7e0a8e701b903105
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.

View file

@ -99,7 +99,7 @@ Note that these groups have no strict meaning, the category assignments are a bi
| [strictvisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/strictvisitor.d) | Visitor that forces derived classes to implement `visit` for every possible node |
| [visitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/visitor.d) | A visitor implementing `visit` for all nodes present in the compiler |
| [transitivevisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/transitivevisitor.d) | Provide a mixin template with visit methods for the parse time AST |
| [apply.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/apply.d) | Depth-first expression visitor |
| [postordervisitor.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/postordervisitor.d) | Depth-first expression visitor |
| [sapply.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/sapply.d) | Depth-first statement visitor |
| [statement_rewrite_walker.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/statement_rewrite_walker.d) | Statement visitor that allows replacing the currently visited node |

View file

@ -1 +1 @@
v2.104.0-beta.1
v2.104.0

View file

@ -18,7 +18,6 @@ import core.stdc.stdio;
import core.checkedint;
import dmd.aliasthis;
import dmd.apply;
import dmd.arraytypes;
import dmd.astenums;
import dmd.attrib;
@ -764,21 +763,18 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
if (s)
{
// Finish all constructors semantics to determine this.noDefaultCtor.
struct SearchCtor
static int searchCtor(Dsymbol s, void*)
{
extern (C++) static int fp(Dsymbol s, void* ctxt)
{
auto f = s.isCtorDeclaration();
if (f && f.semanticRun == PASS.initial)
f.dsymbolSemantic(null);
return 0;
}
auto f = s.isCtorDeclaration();
if (f && f.semanticRun == PASS.initial)
f.dsymbolSemantic(null);
return 0;
}
for (size_t i = 0; i < members.length; i++)
{
auto sm = (*members)[i];
sm.apply(&SearchCtor.fp, null);
sm.apply(&searchCtor, null);
}
}
return s;
@ -814,3 +810,36 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
v.visit(this);
}
}
/*********************************
* Iterate this dsymbol or members of this scoped dsymbol, then
* call `fp` with the found symbol and `params`.
* Params:
* symbol = the dsymbol or parent of members to call fp on
* fp = function pointer to process the iterated symbol.
* If it returns nonzero, the iteration will be aborted.
* ctx = context parameter passed to fp.
* Returns:
* nonzero if the iteration is aborted by the return value of fp,
* or 0 if it's completed.
*/
int apply(Dsymbol symbol, int function(Dsymbol, void*) fp, void* ctx)
{
if (auto nd = symbol.isNspace())
{
return nd.members.foreachDsymbol( (s) { return s && s.apply(fp, ctx); } );
}
if (auto ad = symbol.isAttribDeclaration())
{
return ad.include(ad._scope).foreachDsymbol( (s) { return s && s.apply(fp, ctx); } );
}
if (auto tm = symbol.isTemplateMixin())
{
if (tm._scope) // if fwd reference
dsymbolSemantic(tm, null); // try to resolve it
return tm.members.foreachDsymbol( (s) { return s && s.apply(fp, ctx); } );
}
return fp(symbol, ctx);
}

View file

@ -14,7 +14,6 @@
module dmd.canthrow;
import dmd.aggregate;
import dmd.apply;
import dmd.arraytypes;
import dmd.attrib;
import dmd.astenums;
@ -26,6 +25,7 @@ import dmd.func;
import dmd.globals;
import dmd.init;
import dmd.mtype;
import dmd.postordervisitor;
import dmd.root.rootobject;
import dmd.tokens;
import dmd.visitor;
@ -133,16 +133,9 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN
*/
if (ce.f && ce.f == func)
return;
Type t = ce.e1.type.toBasetype();
auto tf = t.isTypeFunction();
const tf = ce.calledFunctionType();
if (tf && tf.isnothrow)
return;
else
{
auto td = t.isTypeDelegate();
if (td && td.nextOf().isTypeFunction().isnothrow)
return;
}
if (ce.f)
checkFuncThrows(ce, ce.f);

View file

@ -177,6 +177,8 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
errorMsg(null, e, (c_longsize == 4 ? "uint" : "ulong"), t);
else
errorMsg(null, e, (c_longsize == 4 ? "int" : "long"), t);
if (t.isintegral() && t.size() != c_longsize)
errorSupplemental(e.loc, "C `long` is %d bytes on your system", c_longsize);
}
break;

View file

@ -106,18 +106,18 @@ FuncDeclaration hasIdentityOpAssign(AggregateDeclaration ad, Scope* sc)
scope er = new NullExp(ad.loc, ad.type); // dummy rvalue
scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue
el.type = ad.type;
auto a = Expressions(1);
auto a = new Expressions(1);
const errors = global.startGagging(); // Do not report errors, even if the template opAssign fbody makes it.
sc = sc.push();
sc.tinst = null;
sc.minst = null;
a[0] = er;
auto f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(&a), FuncResolveFlag.quiet);
(*a)[0] = er;
auto f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(a), FuncResolveFlag.quiet);
if (!f)
{
a[0] = el;
f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(&a), FuncResolveFlag.quiet);
(*a)[0] = el;
f = resolveFuncCall(ad.loc, sc, assign, null, ad.type, ArgumentList(a), FuncResolveFlag.quiet);
}
sc = sc.pop();
@ -465,7 +465,7 @@ private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc)
*/
scope er = new NullExp(ad.loc, null); // dummy rvalue
scope el = new IdentifierExp(ad.loc, Id.p); // dummy lvalue
auto a = Expressions(1);
auto a = new Expressions(1);
bool hasIt(Type tthis)
{
@ -476,9 +476,9 @@ private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc)
FuncDeclaration rfc(Expression e)
{
a[0] = e;
a[0].type = tthis;
return resolveFuncCall(ad.loc, sc, eq, null, tthis, ArgumentList(&a), FuncResolveFlag.quiet);
(*a)[0] = e;
(*a)[0].type = tthis;
return resolveFuncCall(ad.loc, sc, eq, null, tthis, ArgumentList(a), FuncResolveFlag.quiet);
}
f = rfc(er);

View file

@ -259,7 +259,7 @@ extern (C++) final class StaticForeach : RootObject
auto sdecl = new StructDeclaration(loc, sid, false);
sdecl.storage_class |= STC.static_;
sdecl.members = new Dsymbols();
auto fid = Identifier.idPool(tupleFieldName.ptr, tupleFieldName.length);
auto fid = Identifier.idPool(tupleFieldName);
auto ty = new TypeTypeof(loc, new TupleExp(loc, e));
sdecl.members.push(new VarDeclaration(loc, ty, fid, null, 0));
auto r = cast(TypeStruct)sdecl.type;

View file

@ -324,6 +324,8 @@ final class CParser(AST) : Parser!AST
// atomic-type-specifier or type_qualifier
case TOK._Atomic:
case TOK.__attribute__:
Ldeclaration:
{
cparseDeclaration(LVL.local);
@ -2356,6 +2358,8 @@ final class CParser(AST) : Parser!AST
cparseGnuAttributes(tagSpecifier);
else if (token.value == TOK.__declspec)
cparseDeclspec(tagSpecifier);
else if (token.value == TOK.__pragma)
uupragmaDirective(sloc);
else
break;
}
@ -2710,7 +2714,7 @@ final class CParser(AST) : Parser!AST
*
* Params:
* declarator = declarator kind
* t = base type to start with
* tbase = base type to start with
* pident = set to Identifier if there is one, null if not
* specifier = specifiers in and out
* Returns:
@ -2718,12 +2722,26 @@ final class CParser(AST) : Parser!AST
* symbol table for the parameter-type-list, which will contain any
* declared struct, union or enum tags.
*/
private AST.Type cparseDeclarator(DTR declarator, AST.Type t,
private AST.Type cparseDeclarator(DTR declarator, AST.Type tbase,
out Identifier pident, ref Specifier specifier)
{
//printf("cparseDeclarator(%d, %p)\n", declarator, t);
AST.Types constTypes; // all the Types that will need `const` applied to them
/* Insert tx -> t into
* ts -> ... -> t
* so that
* ts -> ... -> tx -> t
*/
static void insertTx(ref AST.Type ts, AST.Type tx, AST.Type t)
{
AST.Type* pt;
for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next)
{
}
*pt = tx;
}
AST.Type parseDecl(AST.Type t)
{
AST.Type ts;
@ -2789,20 +2807,6 @@ final class CParser(AST) : Parser!AST
// parse DeclaratorSuffixes
while (1)
{
/* Insert tx -> t into
* ts -> ... -> t
* so that
* ts -> ... -> tx -> t
*/
static void insertTx(ref AST.Type ts, AST.Type tx, AST.Type t)
{
AST.Type* pt;
for (pt = &ts; *pt != t; pt = &(cast(AST.TypeNext)*pt).next)
{
}
*pt = tx;
}
switch (token.value)
{
case TOK.leftBracket:
@ -2915,7 +2919,17 @@ final class CParser(AST) : Parser!AST
return ts;
}
t = parseDecl(t);
auto t = parseDecl(tbase);
if (specifier.vector_size)
{
auto length = new AST.IntegerExp(token.loc, specifier.vector_size / tbase.size(), AST.Type.tuns32);
auto tsa = new AST.TypeSArray(tbase, length);
AST.Type tv = new AST.TypeVector(tsa);
specifier.vector_size = 0; // used it up
insertTx(t, tv, tbase); // replace tbase with tv
}
/* Because const is transitive, cannot assemble types from
* fragments. Instead, types to be annotated with const are put
@ -3553,7 +3567,19 @@ final class CParser(AST) : Parser!AST
{
nextToken();
check(TOK.leftParenthesis);
cparseConstantExp(); // TODO implement
if (token.value == TOK.int32Literal)
{
const n = token.unsvalue;
if (n < 1 || n & (n - 1) || ushort.max < n)
error("__attribute__((vector_size(%lld))) must be an integer positive power of 2 and be <= 32,768", cast(ulong)n);
specifier.vector_size = cast(uint) n;
nextToken();
}
else
{
error("value for vector_size expected, not `%s`", token.toChars());
nextToken();
}
check(TOK.rightParenthesis);
}
else
@ -3852,6 +3878,10 @@ final class CParser(AST) : Parser!AST
else if (!tag)
error("missing tag `identifier` after `%s`", Token.toChars(structOrUnion));
// many ways and places to declare alignment
if (packalign.isUnknown() && !this.packalign.isUnknown())
packalign.set(this.packalign.get());
/* Need semantic information to determine if this is a declaration,
* redeclaration, or reference to existing declaration.
* Defer to the semantic() pass with a TypeTag.
@ -4694,6 +4724,7 @@ final class CParser(AST) : Parser!AST
// atomic-type-specifier
case TOK._Atomic:
case TOK.typeof_:
case TOK.__attribute__:
t = peek(t);
if (t.value != TOK.leftParenthesis ||
!skipParens(t, &t))
@ -4959,6 +4990,7 @@ final class CParser(AST) : Parser!AST
bool dllexport; /// dllexport attribute
bool _deprecated; /// deprecated attribute
AST.Expression depMsg; /// deprecated message
uint vector_size; /// positive power of 2 multipe of base type size
SCW scw; /// storage-class specifiers
MOD mod; /// type qualifiers
@ -5400,6 +5432,24 @@ final class CParser(AST) : Parser!AST
pragmaDirective(scanloc);
return true;
}
else if (n.ident == Id.ident) // #ident "string"
{
scan(&n);
if (n.value == TOK.string_ && n.ptr[0] == '"' && n.postfix == 0)
{
/* gcc inserts string into the .comment section in the object file.
* Just ignore it for now, but can support it later by writing
* the string to obj_exestr()
*/
//auto comment = n.ustring;
scan(&n);
if (n.value == TOK.endOfFile || n.value == TOK.endOfLine)
return true;
}
error("\"string\" expected after `#ident`");
return false;
}
}
if (n.ident != Id.undef)
error("C preprocessor directive `#%s` is not supported", n.toChars());
@ -5416,20 +5466,39 @@ final class CParser(AST) : Parser!AST
private void uupragmaDirective(const ref Loc startloc)
{
const loc = startloc;
nextToken();
nextToken(); // move past __pragma
if (token.value != TOK.leftParenthesis)
{
error(loc, "left parenthesis expected to follow `__pragma`");
error(loc, "left parenthesis expected to follow `__pragma` instead of `%s`", token.toChars());
nextToken();
return;
}
nextToken();
if (token.value == TOK.identifier && token.ident == Id.pack)
pragmaPack(startloc, false);
if (token.value == TOK.identifier)
{
if (token.ident == Id.pack)
pragmaPack(startloc, false);
else
{
nextToken();
if (token.value == TOK.leftParenthesis)
cparseParens();
}
}
else if (token.value == TOK.endOfFile)
{
}
else if (token.value == TOK.rightParenthesis)
{
}
else
error(loc, "unrecognized __pragma");
error(loc, "unrecognized `__pragma(%s)`", token.toChars());
if (token.value != TOK.rightParenthesis)
{
error(loc, "right parenthesis expected to close `__pragma(...)`");
error(loc, "right parenthesis expected to close `__pragma(...)` instead of `%s`", token.toChars());
return;
}
nextToken();

View file

@ -446,7 +446,15 @@ private final class CppMangleVisitor : Visitor
if (this.context.res.dyncast() == DYNCAST.dsymbol)
parentti = this.context.res.asFuncDecl().parent.isTemplateInstance();
else
parentti = this.context.res.asType().toDsymbol(null).parent.isTemplateInstance();
{
auto parent = this.context.res.asType().toDsymbol(null).parent;
parentti = parent.isTemplateInstance();
// https://issues.dlang.org/show_bug.cgi?id=22760
// The template instance may sometimes have the form
// S1!int.S1, therefore the above instruction might yield null
if (parentti is null && parent.parent)
parentti = parent.parent.isTemplateInstance();
}
return (*parentti.tiargs)[arg];
}());
scope (exit) this.context.pop(prev);

View file

@ -71,6 +71,8 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
if (const match = (sc && sc.flags & SCOPE.Cfile) ? e.cimplicitConvTo(t) : e.implicitConvTo(t))
{
// no need for an extra cast when matching is exact
if (match == MATCH.convert && e.type.isTypeNoreturn())
{
return specialNoreturnCast(e, t);
@ -88,6 +90,8 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
auto ad = isAggregate(e.type);
if (ad && ad.aliasthis)
{
if (!ad.type || ad.type.isTypeError())
return e;
auto ts = ad.type.isTypeStruct();
const adMatch = ts
? ts.implicitConvToWithoutAliasThis(t)

View file

@ -17,7 +17,6 @@ import core.stdc.stdio;
import core.stdc.string;
import dmd.aggregate;
import dmd.apply;
import dmd.arraytypes;
import dmd.astenums;
import dmd.attrib;
@ -867,7 +866,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
* Resolve forward references to all class member functions,
* and determine whether this class is abstract.
*/
static int func(Dsymbol s)
static int func(Dsymbol s, void*)
{
auto fd = s.isFuncDeclaration();
if (!fd)
@ -883,7 +882,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
for (size_t i = 0; i < members.length; i++)
{
auto s = (*members)[i];
if (s.apply(&func))
if (s.apply(&func, null))
{
return yes();
}
@ -910,7 +909,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
* each of the virtual functions,
* which will fill in the vtbl[] overrides.
*/
static int virtualSemantic(Dsymbol s)
static int virtualSemantic(Dsymbol s, void*)
{
auto fd = s.isFuncDeclaration();
if (fd && !(fd.storage_class & STC.static_) && !fd.isUnitTestDeclaration())
@ -921,7 +920,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
for (size_t i = 0; i < members.length; i++)
{
auto s = (*members)[i];
s.apply(&virtualSemantic);
s.apply(&virtualSemantic,null);
}
}

View file

@ -44,6 +44,10 @@ import dmd.tokens;
import dmd.typesem;
import dmd.visitor;
version (IN_GCC) {}
else version (IN_LLVM) {}
else version = MARS;
/************************************
* Check to see the aggregate type is nested and its context pointer is
* accessible from the current scope.
@ -633,9 +637,7 @@ extern (C++) final class TupleDeclaration : Declaration
version (none)
{
buf.printf("_%s_%d", ident.toChars(), i);
const len = buf.offset;
const name = buf.extractSlice().ptr;
auto id = Identifier.idPool(name, len);
auto id = Identifier.idPool(buf.extractSlice());
auto arg = new Parameter(STC.in_, t, id, null);
}
else

View file

@ -534,22 +534,19 @@ enum class BUILTIN : unsigned char
Expression *eval_builtin(const Loc &loc, FuncDeclaration *fd, Expressions *arguments);
BUILTIN isBuiltin(FuncDeclaration *fd);
struct ContractInfo;
class FuncDeclaration : public Declaration
{
public:
Statements *frequires; // in contracts
Ensures *fensures; // out contracts
Statement *frequire; // lowered in contract
Statement *fensure; // lowered out contract
Statement *fbody;
FuncDeclarations foverrides; // functions this function overrides
FuncDeclaration *fdrequire; // function that does the in contract
FuncDeclaration *fdensure; // function that does the out contract
Expressions *fdrequireParams; // argument list for __require
Expressions *fdensureParams; // argument list for __ensure
private:
ContractInfo *contracts; // contract information
public:
const char *mangleString; // mangled symbol created from mangleExact()
VarDeclaration *vresult; // result variable for out contracts
@ -686,6 +683,22 @@ public:
static FuncDeclaration *create(const Loc &loc, const Loc &endloc, Identifier *id, StorageClass storage_class, Type *type, bool noreturn = false);
FuncDeclaration *syntaxCopy(Dsymbol *) override;
Statements *frequires();
Ensures *fensures();
Statement *frequire();
Statement *fensure();
FuncDeclaration *fdrequire();
FuncDeclaration *fdensure();
Expressions *fdrequireParams();
Expressions *fdensureParams();
Statements *frequires(Statements *frs);
Ensures *fensures(Statements *fes);
Statement *frequire(Statement *fr);
Statement *fensure(Statement *fe);
FuncDeclaration *fdrequire(FuncDeclaration *fdr);
FuncDeclaration *fdensure(FuncDeclaration *fde);
Expressions *fdrequireParams(Expressions *fdrp);
Expressions *fdensureParams(Expressions *fdep);
bool functionSemantic();
bool functionSemantic3();
bool equals(const RootObject * const o) const override final;

View file

@ -14,7 +14,6 @@
module dmd.delegatize;
import core.stdc.stdio;
import dmd.apply;
import dmd.astenums;
import dmd.declaration;
import dmd.dscope;
@ -27,6 +26,7 @@ import dmd.init;
import dmd.initsem;
import dmd.location;
import dmd.mtype;
import dmd.postordervisitor;
import dmd.statement;
import dmd.tokens;
import dmd.visitor;

View file

@ -169,7 +169,12 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
return defaultval;
}
//printf("EnumDeclaration::getDefaultValue() %p %s\n", this, toChars());
if (defaultval)
// https://issues.dlang.org/show_bug.cgi?id=23904
// Return defaultval only if it is not ErrorExp.
// A speculative context may set defaultval to ErrorExp;
// subsequent non-speculative contexts need to be able
// to print the error.
if (defaultval && !defaultval.isErrorExp())
return defaultval;
if (isCsymbol())

View file

@ -26,6 +26,7 @@ import dmd.location;
import dmd.mtype;
import dmd.visitor;
import core.stdc.stdio;
/***********************************************************
*/
extern (C++) final class Import : Dsymbol
@ -232,7 +233,20 @@ extern (C++) final class Import : Dsymbol
* most likely because of parsing errors.
* Therefore we cannot trust the resulting AST.
*/
if (load(sc)) return;
if (load(sc))
{
// https://issues.dlang.org/show_bug.cgi?id=23873
// For imports that are not at module or function level,
// e.g. aggregate level, the import symbol is added to the
// symbol table and later semantic is performed on it.
// This leads to semantic analysis on an malformed AST
// which causes all kinds of segfaults.
// The fix is to note that the module has errors and avoid
// semantic analysis on it.
if(mod)
mod.errors = true;
return;
}
if (!mod) return; // Failed

View file

@ -16,7 +16,6 @@ module dmd.dinterpret;
import core.stdc.stdio;
import core.stdc.stdlib;
import core.stdc.string;
import dmd.apply;
import dmd.arraytypes;
import dmd.astenums;
import dmd.attrib;

View file

@ -429,9 +429,9 @@ extern(C++) void gendocfile(Module m)
if (m.filetype == FileType.ddoc)
{
const ploc = m.md ? &m.md.loc : &m.loc;
const loc = Loc(ploc.filename ? ploc.filename : srcfilename.ptr,
ploc.linnum,
ploc.charnum);
Loc loc = *ploc;
if (!loc.filename)
loc.filename = srcfilename.ptr;
size_t commentlen = strlen(cast(char*)m.comment);
Dsymbols a;
@ -4151,7 +4151,7 @@ private size_t endRowAndTable(ref OutBuffer buf, size_t iStart, size_t iEnd, con
private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, size_t offset)
{
const incrementLoc = loc.linnum == 0 ? 1 : 0;
loc.linnum += incrementLoc;
loc.linnum = loc.linnum + incrementLoc;
loc.charnum = 0;
//printf("highlightText()\n");
bool leadingBlank = true;
@ -4256,7 +4256,7 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s
lineQuoted = false;
tableRowDetected = false;
iLineStart = i + 1;
loc.linnum += incrementLoc;
loc.linnum = loc.linnum + incrementLoc;
// update the paragraph start if we just entered a macro
if (previousMacroLevel < macroLevel && iParagraphStart < iLineStart)

View file

@ -17,7 +17,6 @@ import core.stdc.string;
import dmd.aggregate;
import dmd.aliasthis;
import dmd.apply;
import dmd.arraytypes;
import dmd.astcodegen;
import dmd.astenums;
@ -78,6 +77,10 @@ import dmd.templateparamsem;
import dmd.typesem;
import dmd.visitor;
version (IN_GCC) {}
else version (IN_LLVM) {}
else version = MARS;
enum LOG = false;
private uint setMangleOverride(Dsymbol s, const(char)[] sym)
@ -484,7 +487,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
// Infering the type requires running semantic,
// so mark the scope as ctfe if required
bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0;
bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0 || !sc.func;
if (needctfe)
{
sc.flags |= SCOPE.condition;
@ -1366,9 +1369,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
static if (LOG)
{
printf("Import::semantic('%s') %s\n", toPrettyChars(), id.toChars());
printf("Import::semantic('%s') %s\n", imp.toPrettyChars(), imp.id.toChars());
scope(exit)
printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
printf("-Import::semantic('%s'), pkg = %p\n", imp.toChars(), imp.pkg);
}
if (imp.semanticRun > PASS.initial)
return;
@ -1434,7 +1437,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
imp.addPackageAccess(scopesym);
}
imp.mod.dsymbolSemantic(null);
// if a module has errors it means that parsing has failed.
if (!imp.mod.errors)
imp.mod.dsymbolSemantic(null);
if (imp.mod.needmoduleinfo)
{
@ -1463,7 +1468,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
else
{
Dsymbol s = imp.mod.search_correct(imp.names[i]);
if (s)
// https://issues.dlang.org/show_bug.cgi?id=23908
// Don't suggest symbols from the importer's module
if (s && s.parent != importer)
imp.mod.error(imp.loc, "import `%s` not found, did you mean %s `%s`?", imp.names[i].toChars(), s.kind(), s.toPrettyChars());
else
imp.mod.error(imp.loc, "import `%s` not found", imp.names[i].toChars());
@ -7124,8 +7131,9 @@ bool determineFields(AggregateDeclaration ad)
// determineFields can be called recursively from one of the fields's v.semantic
ad.fields.setDim(0);
static int func(Dsymbol s, AggregateDeclaration ad)
static int func(Dsymbol s, void* ctx)
{
auto ad = cast(AggregateDeclaration)ctx;
auto v = s.isVarDeclaration();
if (!v)
return 0;
@ -7141,7 +7149,7 @@ bool determineFields(AggregateDeclaration ad)
if (v.aliasTuple)
{
// If this variable was really a tuple, process each element.
return v.aliasTuple.foreachVar(tv => tv.apply(&func, ad));
return v.aliasTuple.foreachVar(tv => tv.apply(&func, cast(void*) ad));
}
if (v.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.ctfe | STC.templateparameter))
@ -7173,7 +7181,7 @@ bool determineFields(AggregateDeclaration ad)
for (size_t i = 0; i < ad.members.length; i++)
{
auto s = (*ad.members)[i];
if (s.apply(&func, ad))
if (s.apply(&func, cast(void *)ad))
{
if (ad.sizeok != Sizeok.none)
{

View file

@ -4141,178 +4141,8 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
goto Lnomatch;
L2:
for (size_t i = 0; 1; i++)
{
//printf("\ttest: tempinst.tiargs[%zu]\n", i);
RootObject o1 = null;
if (i < t.tempinst.tiargs.length)
o1 = (*t.tempinst.tiargs)[i];
else if (i < t.tempinst.tdtypes.length && i < tp.tempinst.tiargs.length)
{
// Pick up default arg
o1 = t.tempinst.tdtypes[i];
}
else if (i >= tp.tempinst.tiargs.length)
break;
//printf("\ttest: o1 = %s\n", o1.toChars());
if (i >= tp.tempinst.tiargs.length)
{
size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg()))
{
i++;
}
if (i >= dim)
break; // match if all remained parameters are dependent
goto Lnomatch;
}
RootObject o2 = (*tp.tempinst.tiargs)[i];
Type t2 = isType(o2);
//printf("\ttest: o2 = %s\n", o2.toChars());
size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1)
? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
if (j != IDX_NOTFOUND && j == parameters.length - 1 &&
(*parameters)[j].isTemplateTupleParameter())
{
/* Given:
* struct A(B...) {}
* alias A!(int, float) X;
* static if (is(X Y == A!(Z), Z...)) {}
* deduce that Z is a tuple(int, float)
*/
/* Create tuple from remaining args
*/
size_t vtdim = (tempdecl.isVariadic() ? t.tempinst.tiargs.length : t.tempinst.tdtypes.length) - i;
auto vt = new Tuple(vtdim);
for (size_t k = 0; k < vtdim; k++)
{
RootObject o;
if (k < t.tempinst.tiargs.length)
o = (*t.tempinst.tiargs)[i + k];
else // Pick up default arg
o = t.tempinst.tdtypes[i + k];
vt.objects[k] = o;
}
Tuple v = cast(Tuple)(*dedtypes)[j];
if (v)
{
if (!match(v, vt))
goto Lnomatch;
}
else
(*dedtypes)[j] = vt;
break;
}
else if (!o1)
break;
Type t1 = isType(o1);
Dsymbol s1 = isDsymbol(o1);
Dsymbol s2 = isDsymbol(o2);
Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1));
Expression e2 = isExpression(o2);
version (none)
{
Tuple v1 = isTuple(o1);
Tuple v2 = isTuple(o2);
if (t1)
printf("t1 = %s\n", t1.toChars());
if (t2)
printf("t2 = %s\n", t2.toChars());
if (e1)
printf("e1 = %s\n", e1.toChars());
if (e2)
printf("e2 = %s\n", e2.toChars());
if (s1)
printf("s1 = %s\n", s1.toChars());
if (s2)
printf("s2 = %s\n", s2.toChars());
if (v1)
printf("v1 = %s\n", v1.toChars());
if (v2)
printf("v2 = %s\n", v2.toChars());
}
if (t1 && t2)
{
if (!deduceType(t1, sc, t2, parameters, dedtypes))
goto Lnomatch;
}
else if (e1 && e2)
{
Le:
e1 = e1.ctfeInterpret();
/* If it is one of the template parameters for this template,
* we should not attempt to interpret it. It already has a value.
*/
if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter))
{
/*
* (T:Number!(e2), int e2)
*/
j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters);
if (j != IDX_NOTFOUND)
goto L1;
// The template parameter was not from this template
// (it may be from a parent template, for example)
}
e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417
e2 = e2.ctfeInterpret();
//printf("e1 = %s, type = %s %d\n", e1.toChars(), e1.type.toChars(), e1.type.ty);
//printf("e2 = %s, type = %s %d\n", e2.toChars(), e2.type.toChars(), e2.type.ty);
if (!e1.equals(e2))
{
if (!e2.implicitConvTo(e1.type))
goto Lnomatch;
e2 = e2.implicitCastTo(sc, e1.type);
e2 = e2.ctfeInterpret();
if (!e1.equals(e2))
goto Lnomatch;
}
}
else if (e1 && t2 && t2.ty == Tident)
{
j = templateParameterLookup(t2, parameters);
L1:
if (j == IDX_NOTFOUND)
{
t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
if (e2)
goto Le;
goto Lnomatch;
}
if (!(*parameters)[j].matchArg(sc, e1, j, parameters, dedtypes, null))
goto Lnomatch;
}
else if (s1 && s2)
{
Ls:
if (!s1.equals(s2))
goto Lnomatch;
}
else if (s1 && t2 && t2.ty == Tident)
{
j = templateParameterLookup(t2, parameters);
if (j == IDX_NOTFOUND)
{
t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
if (s2)
goto Ls;
goto Lnomatch;
}
if (!(*parameters)[j].matchArg(sc, s1, j, parameters, dedtypes, null))
goto Lnomatch;
}
else
goto Lnomatch;
}
if (!resolveTemplateInstantiation(t.tempinst.tiargs, &t.tempinst.tdtypes, tempdecl, tp, dedtypes))
goto Lnomatch;
}
visit(cast(Type)t);
return;
@ -4322,6 +4152,198 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
result = MATCH.nomatch;
}
/********************
* Match template `parameters` to the target template instance.
* Example:
* struct Temp(U, int Z) {}
* void foo(T)(Temp!(T, 3));
* foo(Temp!(int, 3)());
* Input:
* this.parameters = template params of foo -> [T]
* tiargs = <Temp!(int, 3)>.tiargs -> [int, 3]
* tdtypes = <Temp!(int, 3)>.tdtypes -> [int, 3]
* tempdecl = <struct Temp!(T, int Z)> -> [T, Z]
* tp = <Temp!(T, 3)>
* Output:
* dedtypes = deduced params of `foo(Temp!(int, 3)())` -> [int]
*/
private bool resolveTemplateInstantiation(Objects* tiargs, Objects* tdtypes, TemplateDeclaration tempdecl, TypeInstance tp, Objects* dedtypes)
{
for (size_t i = 0; 1; i++)
{
//printf("\ttest: tempinst.tiargs[%zu]\n", i);
RootObject o1 = null;
if (i < tiargs.length)
o1 = (*tiargs)[i];
else if (i < tdtypes.length && i < tp.tempinst.tiargs.length)
{
// Pick up default arg
o1 = (*tdtypes)[i];
}
else if (i >= tp.tempinst.tiargs.length)
break;
//printf("\ttest: o1 = %s\n", o1.toChars());
if (i >= tp.tempinst.tiargs.length)
{
size_t dim = tempdecl.parameters.length - (tempdecl.isVariadic() ? 1 : 0);
while (i < dim && ((*tempdecl.parameters)[i].dependent || (*tempdecl.parameters)[i].hasDefaultArg()))
{
i++;
}
if (i >= dim)
break; // match if all remained parameters are dependent
return false;
}
RootObject o2 = (*tp.tempinst.tiargs)[i];
Type t2 = isType(o2);
//printf("\ttest: o2 = %s\n", o2.toChars());
size_t j = (t2 && t2.ty == Tident && i == tp.tempinst.tiargs.length - 1)
? templateParameterLookup(t2, parameters) : IDX_NOTFOUND;
if (j != IDX_NOTFOUND && j == parameters.length - 1 &&
(*parameters)[j].isTemplateTupleParameter())
{
/* Given:
* struct A(B...) {}
* alias A!(int, float) X;
* static if (is(X Y == A!(Z), Z...)) {}
* deduce that Z is a tuple(int, float)
*/
/* Create tuple from remaining args
*/
size_t vtdim = (tempdecl.isVariadic() ? tiargs.length : tdtypes.length) - i;
auto vt = new Tuple(vtdim);
for (size_t k = 0; k < vtdim; k++)
{
RootObject o;
if (k < tiargs.length)
o = (*tiargs)[i + k];
else // Pick up default arg
o = (*tdtypes)[i + k];
vt.objects[k] = o;
}
Tuple v = cast(Tuple)(*dedtypes)[j];
if (v)
{
if (!match(v, vt))
return false;
}
else
(*dedtypes)[j] = vt;
break;
}
else if (!o1)
break;
Type t1 = isType(o1);
Dsymbol s1 = isDsymbol(o1);
Dsymbol s2 = isDsymbol(o2);
Expression e1 = s1 ? getValue(s1) : getValue(isExpression(o1));
Expression e2 = isExpression(o2);
version (none)
{
Tuple v1 = isTuple(o1);
Tuple v2 = isTuple(o2);
if (t1)
printf("t1 = %s\n", t1.toChars());
if (t2)
printf("t2 = %s\n", t2.toChars());
if (e1)
printf("e1 = %s\n", e1.toChars());
if (e2)
printf("e2 = %s\n", e2.toChars());
if (s1)
printf("s1 = %s\n", s1.toChars());
if (s2)
printf("s2 = %s\n", s2.toChars());
if (v1)
printf("v1 = %s\n", v1.toChars());
if (v2)
printf("v2 = %s\n", v2.toChars());
}
if (t1 && t2)
{
if (!deduceType(t1, sc, t2, parameters, dedtypes))
return false;
}
else if (e1 && e2)
{
Le:
e1 = e1.ctfeInterpret();
/* If it is one of the template parameters for this template,
* we should not attempt to interpret it. It already has a value.
*/
if (e2.op == EXP.variable && (e2.isVarExp().var.storage_class & STC.templateparameter))
{
/*
* (T:Number!(e2), int e2)
*/
j = templateIdentifierLookup(e2.isVarExp().var.ident, parameters);
if (j != IDX_NOTFOUND)
goto L1;
// The template parameter was not from this template
// (it may be from a parent template, for example)
}
e2 = e2.expressionSemantic(sc); // https://issues.dlang.org/show_bug.cgi?id=13417
e2 = e2.ctfeInterpret();
//printf("e1 = %s, type = %s %d\n", e1.toChars(), e1.type.toChars(), e1.type.ty);
//printf("e2 = %s, type = %s %d\n", e2.toChars(), e2.type.toChars(), e2.type.ty);
if (!e1.equals(e2))
{
if (!e2.implicitConvTo(e1.type))
return false;
e2 = e2.implicitCastTo(sc, e1.type);
e2 = e2.ctfeInterpret();
if (!e1.equals(e2))
return false;
}
}
else if (e1 && t2 && t2.ty == Tident)
{
j = templateParameterLookup(t2, parameters);
L1:
if (j == IDX_NOTFOUND)
{
t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
if (e2)
goto Le;
return false;
}
if (!(*parameters)[j].matchArg(sc, e1, j, parameters, dedtypes, null))
return false;
}
else if (s1 && s2)
{
Ls:
if (!s1.equals(s2))
return false;
}
else if (s1 && t2 && t2.ty == Tident)
{
j = templateParameterLookup(t2, parameters);
if (j == IDX_NOTFOUND)
{
t2.resolve((cast(TypeIdentifier)t2).loc, sc, e2, t2, s2);
if (s2)
goto Ls;
return false;
}
if (!(*parameters)[j].matchArg(sc, s1, j, parameters, dedtypes, null))
return false;
}
else
return false;
}
return true;
}
override void visit(TypeStruct t)
{
/* If this struct is a template struct, and we're matching

View file

@ -377,13 +377,18 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId,
desc ~ " `%s` assigned to non-scope parameter calling `assert()`", v);
return;
}
bool isThis = fdc && fdc.needThis() && fdc.vthis == vPar; // implicit `this` parameter to member function
const(char)* msg =
(isThis) ? (desc ~ " `%s` calling non-scope member function `%s.%s()`") :
(fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s` calling `%s`") :
(fdc && !parId) ? (desc ~ " `%s` assigned to non-scope anonymous parameter calling `%s`") :
(!fdc && parId) ? (desc ~ " `%s` assigned to non-scope parameter `%s`") :
(desc ~ " `%s` assigned to non-scope anonymous parameter");
if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, parId ? parId : fdc, fdc))
auto param = isThis ? v : (parId ? parId : fdc);
if (sc.setUnsafeDIP1000(gag, arg.loc, msg, v, param, fdc))
{
result = true;
printScopeFailure(previewSupplementalFunc(sc.isDeprecated(), global.params.useDIP1000), vPar, 10);
@ -1746,20 +1751,8 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
/* Check each argument that is
* passed as 'return scope'.
*/
Type t1 = e.e1.type.toBasetype();
TypeFunction tf;
TypeDelegate dg;
if (t1.ty == Tdelegate)
{
dg = t1.isTypeDelegate();
tf = dg.next.isTypeFunction();
}
else if (t1.ty == Tfunction)
tf = t1.isTypeFunction();
else
return;
if (!e.type.hasPointers())
TypeFunction tf = e.calledFunctionType();
if (!tf || !e.type.hasPointers())
return;
if (e.arguments && e.arguments.length)
@ -1815,6 +1808,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
}
}
// If 'this' is returned, check it too
Type t1 = e.e1.type.toBasetype();
if (e.e1.op == EXP.dotVariable && t1.ty == Tfunction)
{
DotVarExp dve = e.e1.isDotVarExp();
@ -1880,7 +1874,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
/* If returning the result of a delegate call, the .ptr
* field of the delegate must be checked.
*/
if (dg)
if (t1.isTypeDelegate())
{
if (tf.isreturn)
escapeByValue(e.e1, er, live, retRefTransition);
@ -2066,13 +2060,8 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR
/* If the function returns by ref, check each argument that is
* passed as 'return ref'.
*/
Type t1 = e.e1.type.toBasetype();
TypeFunction tf;
if (t1.ty == Tdelegate)
tf = t1.isTypeDelegate().next.isTypeFunction();
else if (t1.ty == Tfunction)
tf = t1.isTypeFunction();
else
TypeFunction tf = e.calledFunctionType();
if (!tf)
return;
if (tf.isref)
{
@ -2107,6 +2096,7 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR
}
}
// If 'this' is returned by ref, check it too
Type t1 = e.e1.type.toBasetype();
if (e.e1.op == EXP.dotVariable && t1.ty == Tfunction)
{
DotVarExp dve = e.e1.isDotVarExp();

View file

@ -19,7 +19,6 @@ import core.stdc.string;
import dmd.aggregate;
import dmd.aliasthis;
import dmd.apply;
import dmd.arrayop;
import dmd.arraytypes;
import dmd.astenums;
@ -56,6 +55,7 @@ import dmd.nspace;
import dmd.objc;
import dmd.opover;
import dmd.optimize;
import dmd.postordervisitor;
import dmd.root.complex;
import dmd.root.ctfloat;
import dmd.root.filename;
@ -699,6 +699,20 @@ VarDeclaration expToVariable(Expression e)
case EXP.super_:
return (cast(ThisExp)e).var.isVarDeclaration();
// Temporaries for rvalues that need destruction
// are of form: (T s = rvalue, s). For these cases
// we can just return var declaration of `s`. However,
// this is intentionally not calling `Expression.extractLast`
// because at this point we cannot infer the var declaration
// of more complex generated comma expressions such as the
// one for the array append hook.
case EXP.comma:
{
if (auto ve = e.isCommaExp().e2.isVarExp())
return ve.var.isVarDeclaration();
return null;
}
default:
return null;
}
@ -723,7 +737,6 @@ extern (C++) abstract class Expression : ASTNode
Type type; // !=null means that semantic() has been run
Loc loc; // file location
const EXP op; // to minimize use of dynamic_cast
bool parens; // if this is a parenthesized expression
extern (D) this(const ref Loc loc, EXP op) scope
{
@ -1530,6 +1543,11 @@ extern (C++) abstract class Expression : ASTNode
return false;
if (sc.flags & (SCOPE.ctfe | SCOPE.debug_))
return false;
/* The original expression (`new S(...)`) will be verified instead. This
* is to keep errors related to the original code and not the lowering.
*/
if (f.ident == Id._d_newitemT)
return false;
if (!f.isNogc())
{
@ -2338,6 +2356,7 @@ extern (C++) final class ComplexExp : Expression
extern (C++) class IdentifierExp : Expression
{
Identifier ident;
bool parens; // if it appears as (identifier)
extern (D) this(const ref Loc loc, Identifier ident) scope
{
@ -3520,6 +3539,8 @@ extern (C++) final class CompoundLiteralExp : Expression
*/
extern (C++) final class TypeExp : Expression
{
bool parens; // if this is a parenthesized expression
extern (D) this(const ref Loc loc, Type type)
{
super(loc, EXP.type);
@ -3672,7 +3693,7 @@ extern (C++) final class NewExp : Expression
bool onstack; // allocate on stack
bool thrownew; // this NewExp is the expression of a ThrowStatement
Expression lowering; // lowered druntime hook: `_d_newclass`
Expression lowering; // lowered druntime hook: `_d_new{class,itemT}`
/// Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around.
/// The fields are still separate for backwards compatibility
@ -5188,6 +5209,7 @@ extern (C++) final class CallExp : UnaExp
bool directcall; // true if a virtual call is devirtualized
bool inDebugStatement; /// true if this was in a debug statement
bool ignoreAttributes; /// don't enforce attributes (e.g. call @gc function in @nogc code)
bool isUfcsRewrite; /// the first argument was pushed in here by a UFCS rewrite
VarDeclaration vthis2; // container for multi-context
/// Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around.
@ -5329,6 +5351,26 @@ extern (C++) final class CallExp : UnaExp
}
}
/**
* Get the called function type from a call expression
* Params:
* ce = function call expression. Must have had semantic analysis done.
* Returns: called function type, or `null` if error / no semantic analysis done
*/
TypeFunction calledFunctionType(CallExp ce)
{
Type t = ce.e1.type;
if (!t)
return null;
t = t.toBasetype();
if (auto tf = t.isTypeFunction())
return tf;
else if (auto td = t.isTypeDelegate())
return td.nextOf().isTypeFunction();
else
return null;
}
FuncDeclaration isFuncAddress(Expression e, bool* hasOverloads = null)
{
if (auto ae = e.isAddrExp())
@ -7058,9 +7100,7 @@ extern (C++) final class FileInitExp : DefaultInitExp
s = loc.isValid() ? loc.filename : sc._module.ident.toChars();
Expression e = new StringExp(loc, s.toDString());
e = e.expressionSemantic(sc);
e = e.castTo(sc, type);
return e;
return e.expressionSemantic(sc);
}
override void accept(Visitor v)
@ -7082,8 +7122,7 @@ extern (C++) final class LineInitExp : DefaultInitExp
override Expression resolveLoc(const ref Loc loc, Scope* sc)
{
Expression e = new IntegerExp(loc, loc.linnum, Type.tint32);
e = e.castTo(sc, type);
return e;
return e.expressionSemantic(sc);
}
override void accept(Visitor v)
@ -7106,9 +7145,7 @@ extern (C++) final class ModuleInitExp : DefaultInitExp
{
const auto s = (sc.callsc ? sc.callsc : sc)._module.toPrettyChars().toDString();
Expression e = new StringExp(loc, s);
e = e.expressionSemantic(sc);
e = e.castTo(sc, type);
return e;
return e.expressionSemantic(sc);
}
override void accept(Visitor v)
@ -7137,9 +7174,7 @@ extern (C++) final class FuncInitExp : DefaultInitExp
else
s = "";
Expression e = new StringExp(loc, s.toDString());
e = e.expressionSemantic(sc);
e.type = Type.tstring;
return e;
return e.expressionSemantic(sc);
}
override void accept(Visitor v)

View file

@ -83,7 +83,6 @@ public:
Type *type; // !=NULL means that semantic() has been run
Loc loc; // file location
EXP op; // to minimize use of dynamic_cast
d_bool parens; // if this is a parenthesized expression
size_t size() const;
static void _init();
@ -316,6 +315,7 @@ class IdentifierExp : public Expression
{
public:
Identifier *ident;
d_bool parens;
static IdentifierExp *create(const Loc &loc, Identifier *ident);
bool isLvalue() override final;
@ -839,6 +839,7 @@ public:
d_bool directcall; // true if a virtual call is devirtualized
d_bool inDebugStatement; // true if this was in a debug statement
d_bool ignoreAttributes; // don't enforce attributes (e.g. call @gc function in @nogc code)
d_bool isUfcsRewrite; // the first argument was pushed in here by a UFCS rewrite
VarDeclaration *vthis2; // container for multi-context
static CallExp *create(const Loc &loc, Expression *e, Expressions *exps);

View file

@ -653,7 +653,7 @@ private Expression resolveUFCS(Scope* sc, CallExp ce)
if (!ce.names)
ce.names = new Identifiers();
ce.names.shift(null);
ce.isUfcsRewrite = true;
return null;
}
@ -1254,12 +1254,12 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
return ErrorExp.get();
e2 = resolveProperties(sc, e2);
Expressions a;
Expressions* a = new Expressions();
a.push(e2);
for (size_t i = 0; i < os.a.length; i++)
{
if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, ArgumentList(&a), FuncResolveFlag.quiet))
if (FuncDeclaration f = resolveFuncCall(loc, sc, os.a[i], tiargs, tthis, ArgumentList(a), FuncResolveFlag.quiet))
{
if (f.errors)
return ErrorExp.get();
@ -1378,10 +1378,10 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
return ErrorExp.get();
e2 = resolveProperties(sc, e2);
Expressions a;
Expressions* a = new Expressions();
a.push(e2);
FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, ArgumentList(&a), FuncResolveFlag.quiet);
FuncDeclaration fd = resolveFuncCall(loc, sc, s, tiargs, tthis, ArgumentList(a), FuncResolveFlag.quiet);
if (fd && fd.type)
{
if (fd.errors)
@ -3574,6 +3574,51 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
result = exp;
}
/**
* Sets the `lowering` field of a `NewExp` to a call to `_d_newitemT` unless
* compiling with `-betterC` or within `__traits(compiles)`.
*
* Params:
* ne = the `NewExp` to lower
*/
private void tryLowerToNewItem(NewExp ne)
{
if (global.params.betterC || !sc.needsCodegen())
return;
auto hook = global.params.tracegc ? Id._d_newitemTTrace : Id._d_newitemT;
if (!verifyHookExist(ne.loc, *sc, hook, "new struct"))
return;
/* Lower the memory allocation and initialization of `new T()` to
* `_d_newitemT!T()`.
*/
Expression id = new IdentifierExp(ne.loc, Id.empty);
id = new DotIdExp(ne.loc, id, Id.object);
auto tiargs = new Objects();
/*
* Remove `inout`, `const`, `immutable` and `shared` to reduce the
* number of generated `_d_newitemT` instances.
*/
auto t = ne.type.nextOf.unqualify(MODFlags.wild | MODFlags.const_ |
MODFlags.immutable_ | MODFlags.shared_);
tiargs.push(t);
id = new DotTemplateInstanceExp(ne.loc, id, hook, tiargs);
auto arguments = new Expressions();
if (global.params.tracegc)
{
auto funcname = (sc.callsc && sc.callsc.func) ?
sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
arguments.push(new StringExp(ne.loc, ne.loc.filename.toDString()));
arguments.push(new IntegerExp(ne.loc, ne.loc.linnum, Type.tint32));
arguments.push(new StringExp(ne.loc, funcname.toDString()));
}
id = new CallExp(ne.loc, id, arguments);
ne.lowering = id.expressionSemantic(sc);
}
override void visit(NewExp exp)
{
static if (LOGSEMANTIC)
@ -4007,6 +4052,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
exp.type = exp.type.pointerTo();
tryLowerToNewItem(exp);
}
else if (tb.ty == Tarray)
{
@ -4078,6 +4124,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
exp.type = exp.type.pointerTo();
tryLowerToNewItem(exp);
}
else if (tb.ty == Taarray)
{
@ -5192,7 +5239,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
s = (cast(TemplateExp)exp.e1).td;
L2:
exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.argumentList, FuncResolveFlag.standard);
exp.f = resolveFuncCall(exp.loc, sc, s, tiargs, null, exp.argumentList,
exp.isUfcsRewrite ? FuncResolveFlag.ufcs : FuncResolveFlag.standard);
if (!exp.f || exp.f.errors)
return setError();
if (exp.f.needThis())
@ -5301,6 +5349,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
buf.writeByte(')');
//printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco);
if (exp.isUfcsRewrite)
{
const arg = (*exp.argumentList.arguments)[0];
.error(exp.loc, "no property `%s` for `%s` of type `%s`", exp.f.ident.toChars(), arg.toChars(), arg.type.toChars());
.errorSupplemental(exp.loc, "the following error occured while looking for a UFCS match");
}
.error(exp.loc, "%s `%s%s` is not callable using argument types `%s`",
exp.f.kind(), exp.f.toPrettyChars(), parametersTypeToChars(tf.parameterList), buf.peekChars());
if (failMessage)
@ -6733,7 +6788,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (exp.ident != Id.__sizeof)
{
result = fieldLookup(exp.e1, sc, exp.ident);
result = fieldLookup(exp.e1, sc, exp.ident, exp.arrow);
return;
}
}
@ -9068,7 +9123,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
else if (sc.flags & SCOPE.Cfile && e1x.isDotIdExp())
{
auto die = e1x.isDotIdExp();
e1x = fieldLookup(die.e1, sc, die.ident);
e1x = fieldLookup(die.e1, sc, die.ident, die.arrow);
}
else if (auto die = e1x.isDotIdExp())
{
@ -11023,7 +11078,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)
if (global.params.betterC || !sc.needsCodegen())
return;
if (auto ce = exp.isCatExp())
@ -13175,10 +13230,20 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag)
Expression se = new ScopeExp(exp.loc, imp.pkg);
return se.expressionSemantic(sc);
}
if (auto attr = s.isAttribDeclaration())
{
if (auto sm = ie.sds.search(exp.loc, exp.ident, flags))
{
auto es = new DsymbolExp(exp.loc, sm);
return es;
}
}
// BUG: handle other cases like in IdentifierExp::semantic()
debug
{
printf("s = '%s', kind = '%s'\n", s.toChars(), s.kind());
printf("s = %p '%s', kind = '%s'\n", s, s.toChars(), s.kind());
}
assert(0);
}

View file

@ -15,7 +15,6 @@ import core.stdc.stdio;
import core.stdc.stdlib;
import core.stdc.string;
import dmd.apply;
import dmd.arraytypes;
import dmd.astenums;
import dmd.attrib;
@ -33,6 +32,7 @@ import dmd.identifier;
import dmd.init;
import dmd.initsem;
import dmd.mtype;
import dmd.postordervisitor;
import dmd.printast;
import dmd.root.array;
import dmd.root.rootobject;

View file

@ -59,6 +59,10 @@ import dmd.statementsem;
import dmd.tokens;
import dmd.visitor;
version (IN_GCC) {}
else version (IN_LLVM) {}
else version = MARS;
/// Inline Status
enum ILS : ubyte
{
@ -259,21 +263,30 @@ extern (C++) struct Ensure
}
/***********************************************************
* Most functions don't have contracts, so save memory by grouping
* this information into a separate struct
*/
extern (C++) class FuncDeclaration : Declaration
private struct ContractInfo
{
Statements* frequires; /// in contracts
Ensures* fensures; /// out contracts
Statement frequire; /// lowered in contract
Statement fensure; /// lowered out contract
FuncDeclaration fdrequire; /// function that does the in contract
FuncDeclaration fdensure; /// function that does the out contract
Expressions* fdrequireParams; /// argument list for __require
Expressions* fdensureParams; /// argument list for __ensure
}
/***********************************************************
*/
extern (C++) class FuncDeclaration : Declaration
{
Statement fbody; /// function body
FuncDeclarations foverrides; /// functions this function overrides
FuncDeclaration fdrequire; /// function that does the in contract
FuncDeclaration fdensure; /// function that does the out contract
Expressions* fdrequireParams; /// argument list for __require
Expressions* fdensureParams; /// argument list for __ensure
private ContractInfo* contracts; /// contract information
const(char)* mangleString; /// mangled symbol created from mangleExact()
@ -403,6 +416,44 @@ extern (C++) class FuncDeclaration : Declaration
return new FuncDeclaration(loc, endloc, id, storage_class, type, noreturn);
}
final nothrow pure @safe
{
private ref ContractInfo getContracts()
{
if (!contracts)
contracts = new ContractInfo();
return *contracts;
}
// getters
inout(Statements*) frequires() inout { return contracts ? contracts.frequires : null; }
inout(Ensures*) fensures() inout { return contracts ? contracts.fensures : null; }
inout(Statement) frequire() inout { return contracts ? contracts.frequire: null; }
inout(Statement) fensure() inout { return contracts ? contracts.fensure : null; }
inout(FuncDeclaration) fdrequire() inout { return contracts ? contracts.fdrequire : null; }
inout(FuncDeclaration) fdensure() inout { return contracts ? contracts.fdensure: null; }
inout(Expressions*) fdrequireParams() inout { return contracts ? contracts.fdrequireParams: null; }
inout(Expressions*) fdensureParams() inout { return contracts ? contracts.fdensureParams: null; }
extern (D) private static string generateContractSetter(string field, string type)
{
return type ~ " " ~ field ~ "(" ~ type ~ " param)" ~
"{
if (!param && !contracts) return null;
return getContracts()." ~ field ~ " = param;
}";
}
mixin(generateContractSetter("frequires", "Statements*"));
mixin(generateContractSetter("fensures", "Ensures*"));
mixin(generateContractSetter("frequire", "Statement"));
mixin(generateContractSetter("fensure", "Statement"));
mixin(generateContractSetter("fdrequire", "FuncDeclaration"));
mixin(generateContractSetter("fdensure", "FuncDeclaration"));
mixin(generateContractSetter("fdrequireParams", "Expressions*"));
mixin(generateContractSetter("fdensureParams", "Expressions*"));
}
override FuncDeclaration syntaxCopy(Dsymbol s)
{
//printf("FuncDeclaration::syntaxCopy('%s')\n", toChars());
@ -2717,7 +2768,7 @@ extern (C++) class FuncDeclaration : Declaration
*/
static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, const(char)* name, StorageClass stc = 0)
{
return genCfunc(fparams, treturn, Identifier.idPool(name, cast(uint)strlen(name)), stc);
return genCfunc(fparams, treturn, Identifier.idPool(name[0 .. strlen(name)]), stc);
}
static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, Identifier id, StorageClass stc = 0)
@ -3199,6 +3250,7 @@ enum FuncResolveFlag : ubyte
quiet = 1, /// do not issue error message on no match, just return `null`.
overloadOnly = 2, /// only resolve overloads, i.e. do not issue error on ambiguous
/// matches and need explicit this.
ufcs = 4, /// trying to resolve UFCS call
}
/*******************************************
@ -3316,12 +3368,22 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
}
// no match, generate an error messages
if (flags & FuncResolveFlag.ufcs)
{
auto arg = (*fargs)[0];
.error(loc, "no property `%s` for `%s` of type `%s`", s.ident.toChars(), arg.toChars(), arg.type.toChars());
.errorSupplemental(loc, "the following error occured while looking for a UFCS match");
}
if (!fd)
{
// all of overloads are templates
if (td)
{
.error(loc, "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`",
const(char)* msg = "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`";
if (!od && !td.overnext)
msg = "%s `%s.%s` is not callable using argument types `!(%s)%s`";
.error(loc, msg,
td.kind(), td.parent.toPrettyChars(), td.ident.toChars(),
tiargsBuf.peekChars(), fargsBuf.peekChars());

View file

@ -26,6 +26,10 @@ import dmd.location;
import dmd.lexer : CompileEnv;
import dmd.utils;
version (IN_GCC) {}
else version (IN_LLVM) {}
else version = MARS;
/// Defines a setting for how compiler warnings and deprecations are handled
enum DiagnosticReporting : ubyte
{

View file

@ -353,10 +353,11 @@ typedef unsigned long long uinteger_t;
// file location
struct Loc
{
const char *filename; // either absolute or relative to cwd
unsigned linnum;
unsigned charnum;
private:
unsigned _linnum;
unsigned short _charnum;
unsigned short fileIndex;
public:
static void set(bool showColumns, MessageStyle messageStyle);
static bool showColumns;
@ -364,18 +365,25 @@ struct Loc
Loc()
{
linnum = 0;
charnum = 0;
filename = NULL;
_linnum = 0;
_charnum = 0;
fileIndex = 0;
}
Loc(const char *filename, unsigned linnum, unsigned charnum)
{
this->linnum = linnum;
this->charnum = charnum;
this->filename = filename;
this->linnum(linnum);
this->charnum(charnum);
this->filename(filename);
}
uint32_t charnum() const;
uint32_t charnum(uint32_t num);
uint32_t linnum() const;
uint32_t linnum(uint32_t num);
const char *filename() const;
void filename(const char *name);
const char *toChars(
bool showColumns = Loc::showColumns,
MessageStyle messageStyle = Loc::messageStyle) const;

View file

@ -48,25 +48,6 @@ version (NoBackend)
}
}
}
else version (MARS)
{
public import dmd.backend.cc : block, Blockx, Symbol;
public import dmd.backend.type : type;
public import dmd.backend.el : elem;
public import dmd.backend.code_x86 : code;
extern (C++)
{
Statement asmSemantic(AsmStatement s, Scope* sc);
void toObjFile(Dsymbol ds, bool multiobj);
extern(C++) abstract class ObjcGlue
{
static void initialize();
}
}
}
else version (IN_GCC)
{
extern (C++) union tree_node;
@ -88,4 +69,12 @@ else version (IN_GCC)
}
}
else
static assert(false, "Unsupported compiler backend");
{
public import dmd.backend.cc : block, Blockx, Symbol;
public import dmd.backend.type : type;
public import dmd.backend.el : elem;
public import dmd.backend.code_x86 : code;
public import dmd.iasm : asmSemantic;
public import dmd.objc_glue : ObjcGlue;
public import dmd.toobj : toObjFile;
}

View file

@ -23,14 +23,15 @@ import dmd.tokens;
import dmd.statement;
import dmd.statementsem;
version (MARS)
{
import dmd.iasmdmd;
}
else version (IN_GCC)
version (IN_GCC)
{
import dmd.iasmgcc;
}
else
{
import dmd.iasmdmd;
version = MARS;
}
/************************ AsmStatement ***************************************/

View file

@ -315,6 +315,8 @@ immutable Msgtable[] msgtable =
{ "_d_newThrowable" },
{ "_d_newclassT" },
{ "_d_newclassTTrace" },
{ "_d_newitemT" },
{ "_d_newitemTTrace" },
{ "_d_assert_fail" },
{ "dup" },
{ "_aaApply" },
@ -549,6 +551,7 @@ immutable Msgtable[] msgtable =
{ "_pure", "pure" },
{ "define" },
{ "undef" },
{ "ident" },
];

View file

@ -274,12 +274,7 @@ nothrow:
return idPool(s[0 .. len]);
}
extern (D) static Identifier idPool(const(char)[] s)
{
return idPool(s, false);
}
extern (D) private static Identifier idPool(const(char)[] s, bool isAnonymous)
extern (D) static Identifier idPool(const(char)[] s, bool isAnonymous = false)
{
auto sv = stringtable.update(s);
auto id = sv.value;
@ -291,18 +286,18 @@ nothrow:
return id;
}
extern (D) static Identifier idPool(const(char)* s, size_t len, int value)
{
return idPool(s[0 .. len], value);
}
extern (D) static Identifier idPool(const(char)[] s, int value)
/******************************************
* Used for inserting keywords into the string table.
* Params:
* s = string for keyword
* value = TOK.xxxx for the keyword
*/
extern (D) static void idPool(const(char)[] s, TOK value)
{
auto sv = stringtable.insert(s, null);
assert(sv);
auto id = new Identifier(sv.toString(), value);
sv.value = id;
return id;
}
/**********************************

View file

@ -108,11 +108,12 @@ Expression arrayFuncConv(Expression e, Scope* sc)
* e = evaluates to an instance of a struct
* sc = context
* id = identifier of a field in that struct
* arrow = -> was used
* Returns:
* if successful `e.ident`
* if not then `ErrorExp` and message is printed
*/
Expression fieldLookup(Expression e, Scope* sc, Identifier id)
Expression fieldLookup(Expression e, Scope* sc, Identifier id, bool arrow)
{
e = e.expressionSemantic(sc);
if (e.isErrorExp())
@ -123,6 +124,9 @@ Expression fieldLookup(Expression e, Scope* sc, Identifier id)
if (t.isTypePointer())
{
t = t.isTypePointer().next;
auto pe = e.toChars();
if (!arrow)
e.error("since `%s` is a pointer, use `%s->%s` instead of `%s.%s`", pe, pe, id.toChars(), pe, id.toChars());
e = new PtrExp(e.loc, e);
}
if (auto ts = t.isTypeStruct())
@ -237,15 +241,16 @@ Expression castCallAmbiguity(Expression e, Scope* sc)
case EXP.call:
auto ce = (*pe).isCallExp();
if (ce.e1.parens)
auto ie = ce.e1.isIdentifierExp();
if (ie && ie.parens)
{
ce.e1 = expressionSemantic(ce.e1, sc);
ce.e1 = expressionSemantic(ie, sc);
if (ce.e1.op == EXP.type)
{
const numArgs = ce.arguments ? ce.arguments.length : 0;
if (numArgs >= 1)
{
ce.e1.parens = false;
ie.parens = false;
Expression arg;
foreach (a; (*ce.arguments)[])
{

View file

@ -587,6 +587,9 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
*/
t = t.toBasetype();
if (auto tv = t.isTypeVector())
t = tv.basetype;
/* If `{ expression }` return the expression initializer
*/
ExpInitializer isBraceExpression()

View file

@ -119,7 +119,7 @@ class Lexer
this(const(char)* filename, const(char)* base, size_t begoffset,
size_t endoffset, bool doDocComment, bool commentToken,
ErrorSink errorSink,
const CompileEnv* compileEnv) pure scope
const CompileEnv* compileEnv) scope
{
scanloc = Loc(filename, 1, 1);
// debug printf("Lexer::Lexer(%p)\n", base);
@ -573,7 +573,7 @@ class Lexer
}
break;
}
Identifier id = Identifier.idPool(cast(char*)t.ptr, cast(uint)(p - t.ptr));
Identifier id = Identifier.idPool((cast(char*)t.ptr)[0 .. p - t.ptr], false);
t.ident = id;
t.value = cast(TOK)id.getValue();
@ -2672,9 +2672,9 @@ class Lexer
return result;
}
final Loc loc() pure @nogc
final Loc loc() @nogc
{
scanloc.charnum = cast(uint)(1 + p - line);
scanloc.charnum = cast(ushort)(1 + p - line);
version (LocOffset)
scanloc.fileOffset = cast(uint)(p - base);
return scanloc;
@ -3098,9 +3098,9 @@ class Lexer
/**************************
* `p` should be at start of next line
*/
private void endOfLine() pure @nogc @safe
private void endOfLine() @nogc @safe
{
scanloc.linnum++;
scanloc.linnum = scanloc.linnum + 1;
line = p;
}
}

View file

@ -11,7 +11,10 @@
module dmd.location;
import core.stdc.stdio;
import dmd.common.outbuffer;
import dmd.root.array;
import dmd.root.filename;
version (DMDLIB)
@ -34,10 +37,9 @@ debug info etc.
*/
struct Loc
{
/// zero-terminated filename string, either absolute or relative to cwd
const(char)* filename;
uint linnum; /// line number, starting from 1
uint charnum; /// utf8 code unit index relative to start of line, starting from 1
private uint _linnum;
private ushort _charnum;
private ushort fileIndex; // index into filenames[], starting from 1 (0 means no filename)
version (LocOffset)
uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0
@ -46,6 +48,8 @@ struct Loc
extern (C++) __gshared bool showColumns;
extern (C++) __gshared MessageStyle messageStyle;
__gshared Array!(const(char)*) filenames;
nothrow:
/*******************************
@ -60,19 +64,69 @@ nothrow:
this.messageStyle = messageStyle;
}
extern (D) this(const(char)* filename, uint linnum, uint charnum) pure
extern (D) this(const(char)* filename, uint linnum, uint charnum)
{
this.linnum = linnum;
this.charnum = charnum;
this._linnum = linnum;
this._charnum = cast(ushort) charnum;
this.filename = filename;
}
/// utf8 code unit index relative to start of line, starting from 1
extern (C++) uint charnum() const @nogc @safe
{
return _charnum;
}
/// ditto
extern (C++) uint charnum(uint num) @nogc @safe
{
return _charnum = cast(ushort) num;
}
/// line number, starting from 1
extern (C++) uint linnum() const @nogc @safe
{
return _linnum;
}
/// ditto
extern (C++) uint linnum(uint num) @nogc @safe
{
return _linnum = num;
}
/***
* Returns: filename for this location, null if none
*/
extern (C++) const(char)* filename() const @nogc
{
return fileIndex ? filenames[fileIndex - 1] : null;
}
/***
* Set file name for this location
* Params:
* name = file name for location, null for no file name
*/
extern (C++) void filename(const(char)* name)
{
if (name)
{
//printf("setting %s\n", name);
filenames.push(name);
fileIndex = cast(ushort)filenames.length;
assert(fileIndex); // no overflow
}
else
fileIndex = 0;
}
extern (C++) const(char)* toChars(
bool showColumns = Loc.showColumns,
MessageStyle messageStyle = Loc.messageStyle) const pure nothrow
MessageStyle messageStyle = Loc.messageStyle) const nothrow
{
OutBuffer buf;
if (filename)
if (fileIndex)
{
buf.writestring(filename);
}
@ -126,7 +180,7 @@ nothrow:
* may lead to multiple equivalent filenames (`foo.d-mixin-<line>`),
* e.g., for test/runnable/test18880.d.
*/
extern (D) bool opEquals(ref const(Loc) loc) const @trusted pure nothrow @nogc
extern (D) bool opEquals(ref const(Loc) loc) const @trusted nothrow @nogc
{
import core.stdc.string : strcmp;
@ -137,7 +191,7 @@ nothrow:
}
/// ditto
extern (D) size_t toHash() const @trusted pure nothrow
extern (D) size_t toHash() const @trusted nothrow
{
import dmd.root.string : toDString;
@ -153,6 +207,6 @@ nothrow:
*/
bool isValid() const pure
{
return filename !is null;
return fileIndex != 0;
}
}

View file

@ -2448,7 +2448,7 @@ extern (C++) abstract class Type : ASTNode
//printf("%p %s, deco = %s, name = %s\n", this, toChars(), deco, name);
assert(0 < length && length < namelen); // don't overflow the buffer
auto id = Identifier.idPool(name, length);
auto id = Identifier.idPool(name[0 .. length]);
if (name != namebuf.ptr)
free(name);
@ -7119,9 +7119,9 @@ bool isCopyable(Type t)
assert(ctor);
scope el = new IdentifierExp(Loc.initial, Id.p); // dummy lvalue
el.type = cast() ts;
Expressions args;
Expressions* args = new Expressions();
args.push(el);
FuncDeclaration f = resolveFuncCall(Loc.initial, null, ctor, null, cast()ts, ArgumentList(&args), FuncResolveFlag.quiet);
FuncDeclaration f = resolveFuncCall(Loc.initial, null, ctor, null, cast()ts, ArgumentList(args), FuncResolveFlag.quiet);
if (!f || f.storage_class & STC.disable)
return false;
}

View file

@ -16,7 +16,6 @@ module dmd.nogc;
import core.stdc.stdio;
import dmd.aggregate;
import dmd.apply;
import dmd.astenums;
import dmd.declaration;
import dmd.dscope;
@ -26,6 +25,7 @@ import dmd.func;
import dmd.globals;
import dmd.init;
import dmd.mtype;
import dmd.postordervisitor;
import dmd.tokens;
import dmd.visitor;

View file

@ -20,7 +20,6 @@ import dmd.root.rootobject;
import dmd.root.rmem;
import dmd.aggregate;
import dmd.apply;
import dmd.arraytypes;
import dmd.astenums;
import dmd.declaration;

View file

@ -607,8 +607,6 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
//printf("BinExp::op_overload() (%s)\n", e.toChars());
Identifier id = opId(e);
Identifier id_r = opId_r(e);
Expressions args1;
Expressions args2;
int argsset = 0;
AggregateDeclaration ad1 = isAggregate(e.e1.type);
AggregateDeclaration ad2 = isAggregate(e.e2.type);
@ -701,6 +699,8 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
}
}
}
Expressions* args1 = new Expressions();
Expressions* args2 = new Expressions();
if (s || s_r)
{
/* Try:
@ -709,16 +709,16 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
* and see which is better.
*/
args1.setDim(1);
args1[0] = e.e1;
expandTuples(&args1);
(*args1)[0] = e.e1;
expandTuples(args1);
args2.setDim(1);
args2[0] = e.e2;
expandTuples(&args2);
(*args2)[0] = e.e2;
expandTuples(args2);
argsset = 1;
MatchAccumulator m;
if (s)
{
functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2));
functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
{
return ErrorExp.get();
@ -727,7 +727,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
FuncDeclaration lastf = m.lastf;
if (s_r)
{
functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1));
functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
{
return ErrorExp.get();
@ -791,16 +791,16 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
if (!argsset)
{
args1.setDim(1);
args1[0] = e.e1;
expandTuples(&args1);
(*args1)[0] = e.e1;
expandTuples(args1);
args2.setDim(1);
args2[0] = e.e2;
expandTuples(&args2);
(*args2)[0] = e.e2;
expandTuples(args2);
}
MatchAccumulator m;
if (s_r)
{
functionResolve(m, s_r, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2));
functionResolve(m, s_r, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
{
return ErrorExp.get();
@ -809,7 +809,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
FuncDeclaration lastf = m.lastf;
if (s)
{
functionResolve(m, s, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1));
functionResolve(m, s, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
{
return ErrorExp.get();
@ -1197,7 +1197,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
return ErrorExp.get();
}
Identifier id = opId(e);
Expressions args2;
Expressions* args2 = new Expressions();
AggregateDeclaration ad1 = isAggregate(e.e1.type);
Dsymbol s = null;
Objects* tiargs = null;
@ -1240,10 +1240,10 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
* a.opOpAssign(b)
*/
args2.setDim(1);
args2[0] = e.e2;
expandTuples(&args2);
(*args2)[0] = e.e2;
expandTuples(args2);
MatchAccumulator m;
functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2));
functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
{
return ErrorExp.get();
@ -1322,12 +1322,12 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop
* b.opEquals(a)
* and see which is better.
*/
Expressions args1 = Expressions(1);
args1[0] = e.e1;
expandTuples(&args1);
Expressions args2 = Expressions(1);
args2[0] = e.e2;
expandTuples(&args2);
Expressions* args1 = new Expressions(1);
(*args1)[0] = e.e1;
expandTuples(args1);
Expressions* args2 = new Expressions(1);
(*args2)[0] = e.e2;
expandTuples(args2);
MatchAccumulator m;
if (0 && s && s_r)
{
@ -1336,7 +1336,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop
}
if (s)
{
functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(&args2));
functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
return ErrorExp.get();
}
@ -1344,7 +1344,7 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop
int count = m.count;
if (s_r)
{
functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(&args1));
functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
return ErrorExp.get();
}

View file

@ -769,11 +769,8 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
return;
if (e.arguments)
{
Type t1 = e.e1.type.toBasetype();
if (auto td = t1.isTypeDelegate())
t1 = td.next;
// t1 can apparently be void for __ArrayDtor(T) calls
if (auto tf = t1.isTypeFunction())
if (auto tf = e.calledFunctionType())
{
foreach (i, ref arg; (*e.arguments)[])
{

View file

@ -4515,10 +4515,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
if (_init)
{
if (isThis)
error(token.loc, "cannot use syntax `alias this = %s`, use `alias %s this` instead", _init.toChars(), _init.toChars());
else
error("alias cannot have initializer");
error("alias cannot have initializer");
}
v = new AST.AliasDeclaration(aliasLoc, ident, t);
@ -4780,23 +4777,20 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
addComment(s, comment);
return a;
}
version (none)
/* Look for:
* alias this = identifier;
*/
if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier)
{
/* Look for:
* alias this = identifier;
*/
if (token.value == TOK.this_ && peekNext() == TOK.assign && peekNext2() == TOK.identifier)
{
check(TOK.this_);
check(TOK.assign);
auto s = new AliasThis(loc, token.ident);
nextToken();
check(TOK.semicolon, "`alias this = Identifier`");
auto a = new Dsymbols();
a.push(s);
addComment(s, comment);
return a;
}
check(TOK.this_);
check(TOK.assign);
auto s = new AST.AliasThis(loc, token.ident);
nextToken();
check(TOK.semicolon, "`alias this = Identifier`");
auto a = new AST.Dsymbols();
a.push(s);
addComment(s, comment);
return a;
}
/* Look for:
* alias identifier = type;
@ -5032,7 +5026,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
stc = STC.ref_;
nextToken();
}
if (token.value != TOK.leftParenthesis && token.value != TOK.leftCurly)
if (token.value != TOK.leftParenthesis && token.value != TOK.leftCurly &&
token.value != TOK.goesTo)
{
// function type (parameters) { statements... }
// delegate type (parameters) { statements... }
@ -5331,7 +5326,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
error("cannot use function constraints for non-template functions. Use `static if` instead");
}
else
error("semicolon expected following function declaration");
error("semicolon expected following function declaration, not `%s`", token.toChars());
}
break;
}
@ -7081,7 +7076,7 @@ LagainStc:
private void checkParens(TOK value, AST.Expression e)
{
if (precedence[e.op] == PREC.rel && !e.parens)
if (precedence[e.op] == PREC.rel)
error(e.loc, "`%s` must be surrounded by parentheses when next to operator `%s`", e.toChars(), Token.toChars(value));
}
@ -8485,7 +8480,6 @@ LagainStc:
// ( expression )
nextToken();
e = parseExpression();
e.parens = true;
check(loc, TOK.rightParenthesis);
break;
}
@ -8806,9 +8800,9 @@ LagainStc:
nextToken();
return AST.ErrorExp.get();
}
e = new AST.TypeExp(loc, t);
e.parens = true;
e = parsePostExp(e);
auto te = new AST.TypeExp(loc, t);
te.parens = true;
e = parsePostExp(te);
}
else
{
@ -9115,14 +9109,18 @@ LagainStc:
private AST.Expression parseAndExp()
{
Loc loc = token.loc;
bool parens = token.value == TOK.leftParenthesis;
auto e = parseCmpExp();
while (token.value == TOK.and)
{
checkParens(TOK.and, e);
nextToken();
if (!parens)
checkParens(TOK.and, e);
parens = nextToken() == TOK.leftParenthesis;
auto e2 = parseCmpExp();
checkParens(TOK.and, e2);
if (!parens)
checkParens(TOK.and, e2);
e = new AST.AndExp(loc, e, e2);
parens = true; // don't call checkParens() for And
loc = token.loc;
}
return e;
@ -9130,32 +9128,42 @@ LagainStc:
private AST.Expression parseXorExp()
{
const loc = token.loc;
Loc loc = token.loc;
bool parens = token.value == TOK.leftParenthesis;
auto e = parseAndExp();
while (token.value == TOK.xor)
{
checkParens(TOK.xor, e);
nextToken();
if (!parens)
checkParens(TOK.xor, e);
parens = nextToken() == TOK.leftParenthesis;
auto e2 = parseAndExp();
checkParens(TOK.xor, e2);
if (!parens)
checkParens(TOK.xor, e2);
e = new AST.XorExp(loc, e, e2);
parens = true;
loc = token.loc;
}
return e;
}
private AST.Expression parseOrExp()
{
const loc = token.loc;
Loc loc = token.loc;
bool parens = token.value == TOK.leftParenthesis;
auto e = parseXorExp();
while (token.value == TOK.or)
{
checkParens(TOK.or, e);
nextToken();
if (!parens)
checkParens(TOK.or, e);
parens = nextToken() == TOK.leftParenthesis;
auto e2 = parseXorExp();
checkParens(TOK.or, e2);
if (!parens)
checkParens(TOK.or, e2);
e = new AST.OrExp(loc, e, e2);
parens = true;
loc = token.loc;
}
return e;
}
@ -9206,6 +9214,7 @@ LagainStc:
AST.Expression parseAssignExp()
{
bool parens = token.value == TOK.leftParenthesis;
AST.Expression e;
e = parseCondExp();
if (e is null)
@ -9214,7 +9223,7 @@ LagainStc:
// require parens for e.g. `t ? a = 1 : b = 2`
void checkRequiredParens()
{
if (e.op == EXP.question && !e.parens)
if (e.op == EXP.question && !parens)
eSink.error(e.loc, "`%s` must be surrounded by parentheses when next to operator `%s`",
e.toChars(), Token.toChars(token.value));
}

View file

@ -9,11 +9,9 @@
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/apply.d
*/
module dmd.apply;
module dmd.postordervisitor;
import dmd.arraytypes;
import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.expression;
import dmd.root.array;
@ -26,39 +24,6 @@ bool walkPostorder(Expression e, StoppableVisitor v)
return v.stop;
}
/*********************************
* Iterate this dsymbol or members of this scoped dsymbol, then
* call `fp` with the found symbol and `params`.
* Params:
* symbol = the dsymbol or parent of members to call fp on
* fp = function pointer to process the iterated symbol.
* If it returns nonzero, the iteration will be aborted.
* params = any parameters passed to fp.
* Returns:
* nonzero if the iteration is aborted by the return value of fp,
* or 0 if it's completed.
*/
int apply(FP, Params...)(Dsymbol symbol, FP fp, Params params)
{
if (auto nd = symbol.isNspace())
{
return nd.members.foreachDsymbol( (s) { return s && s.apply(fp, params); } );
}
if (auto ad = symbol.isAttribDeclaration())
{
return ad.include(ad._scope).foreachDsymbol( (s) { return s && s.apply(fp, params); } );
}
if (auto tm = symbol.isTemplateMixin())
{
if (tm._scope) // if fwd reference
dsymbolSemantic(tm, null); // try to resolve it
return tm.members.foreachDsymbol( (s) { return s && s.apply(fp, params); } );
}
return fp(symbol, params);
}
/**************************************
* An Expression tree walker that will visit each Expression e in the tree,
* in depth-first evaluation order, and call fp(e,param) on it.

View file

@ -447,14 +447,12 @@ private extern(C++) final class Semantic2Visitor : Visitor
const sameParams = tf1.parameterList == tf2.parameterList;
// Allow the hack to declare overloads with different parameters/STC's
// @@@DEPRECATED_2.104@@@
// Deprecated in 2020-08, make this an error in 2.104
if (parent1.isModule() &&
linkage1 != LINK.d && linkage1 != LINK.cpp &&
(!sameAttr || !sameParams)
)
{
f2.deprecation("cannot overload `extern(%s)` function at %s",
f2.error("cannot overload `extern(%s)` function at %s",
linkageToChars(f1._linkage),
f1.loc.toChars());
return 0;

View file

@ -11,7 +11,6 @@
module dmd.sideeffect;
import dmd.apply;
import dmd.astenums;
import dmd.declaration;
import dmd.dscope;
@ -22,6 +21,7 @@ import dmd.globals;
import dmd.identifier;
import dmd.init;
import dmd.mtype;
import dmd.postordervisitor;
import dmd.tokens;
import dmd.visitor;
@ -101,9 +101,11 @@ extern (C++) bool hasSideEffect(Expression e, bool assumeImpureCalls = false)
int callSideEffectLevel(FuncDeclaration f)
{
/* https://issues.dlang.org/show_bug.cgi?id=12760
* ctor call always has side effects.
* https://issues.dlang.org/show_bug.cgi?id=16384
*
* ctor calls and invariant calls always have side effects
*/
if (f.isCtorDeclaration())
if (f.isCtorDeclaration() || f.isInvariantDeclaration())
return 0;
assert(f.type.ty == Tfunction);
TypeFunction tf = cast(TypeFunction)f.type;

View file

@ -1273,8 +1273,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
else if (auto td = sfront.isTemplateDeclaration())
{
Expressions a;
if (auto f = resolveFuncCall(loc, sc, td, null, tab, ArgumentList(&a), FuncResolveFlag.quiet))
if (auto f = resolveFuncCall(loc, sc, td, null, tab, ArgumentList(), FuncResolveFlag.quiet))
tfront = f.type;
}
else if (auto d = sfront.toAlias().isDeclaration())
@ -2733,7 +2732,8 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
tbret = tret.toBasetype();
}
if (inferRef) // deduce 'auto ref'
// https://issues.dlang.org/show_bug.cgi?id=23914
if (inferRef && !resType.isTypeNoreturn()) // deduce 'auto ref'
tf.isref = false;
if (tbret.ty != Tvoid && !resType.isTypeNoreturn()) // if non-void return
@ -3593,6 +3593,11 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
cas.error("`asm` statement is assumed to be impure - mark it with `pure` if it is not");
if (!(cas.stc & STC.nogc) && sc.func.setGC(cas.loc, "`asm` statement in %s `%s` is assumed to use the GC - mark it with `@nogc` if it does not"))
cas.error("`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not");
// @@@DEPRECATED_2.114@@@
// change deprecation() to error(), add `else` and remove `| STC.safe`
// to turn deprecation into an error when deprecation cycle is over
if (cas.stc & STC.safe)
cas.deprecation("`asm` statement cannot be marked `@safe`, use `@system` or `@trusted` instead");
if (!(cas.stc & (STC.trusted | STC.safe)))
{
sc.setUnsafe(false, cas.loc, "`asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not");
@ -4045,6 +4050,13 @@ void catchSemantic(Catch c, Scope* sc)
// reference .object.Throwable
c.type = getThrowable();
}
else if (!c.type.isNaked() && !c.type.isConst())
{
// @@@DEPRECATED_2.113@@@
// Deprecated in 2.103, change into an error & uncomment in 2.113
deprecation(c.loc, "can only catch mutable or const qualified types, not `%s`", c.type.toChars());
//c.errors = true;
}
c.type = c.type.typeSemantic(c.loc, sc);
if (c.type == Type.terror)
{

View file

@ -593,7 +593,7 @@ shared static this() nothrow
foreach (kw; keywords)
{
//printf("keyword[%d] = '%s'\n",kw, Token.tochars[kw].ptr);
Identifier.idPool(Token.tochars[kw].ptr, Token.tochars[kw].length, cast(uint)kw);
Identifier.idPool(Token.tochars[kw], kw);
}
}

View file

@ -1215,7 +1215,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
{
if (fd.overnext)
{
deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", fd.toChars());
deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not the overload set `%s`", fd.toChars());
deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from");
}
}
@ -1225,7 +1225,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
{
if (td.overnext || td.funcroot)
{
deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `%s`", td.ident.toChars());
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");
}
}

View file

@ -161,6 +161,16 @@ package mixin template ParseVisitMethods(AST)
s._body.accept(this);
}
override void visit(AST.StaticForeachStatement s)
{
// printf("Visiting StaticForeachStatement\n");
if (s.sfe.aggrfe)
s.sfe.aggrfe.accept(this);
if (s.sfe.rangefe)
s.sfe.rangefe.accept(this);
}
override void visit(AST.IfStatement s)
{
//printf("Visiting IfStatement\n");

View file

@ -163,7 +163,7 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb
/* Look for what user might have intended
*/
const p = mt.mutableOf().unSharedOf().toChars();
auto id = Identifier.idPool(p, cast(uint)strlen(p));
auto id = Identifier.idPool(p[0 .. strlen(p)]);
if (const n = importHint(id.toString()))
error(loc, "`%s` is not defined, perhaps `import %.*s;` ?", p, cast(int)n.length, n.ptr);
else if (auto s2 = sc.search_correct(id))

View file

@ -2296,11 +2296,12 @@ public:
return;
}
/* This case should have been rewritten to `_d_newitemT' during the
semantic phase. */
gcc_assert (e->lowering);
/* Generate: _d_newitemT() */
libcall_fn libcall = htype->isZeroInit ()
? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
tree arg = build_typeinfo (e, e->newtype);
new_call = build_libcall (libcall, tb, 1, arg);
new_call = build_expr (e->lowering);
if (e->member || !e->arguments)
{
@ -2423,11 +2424,12 @@ public:
return;
}
libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
/* This case should have been rewritten to `_d_newitemT' during the
semantic phase. */
gcc_assert (e->lowering);
tree arg = build_typeinfo (e, e->newtype);
result = build_libcall (libcall, tb, 1, arg);
/* Generate: _d_newitemT() */
result = build_expr (e->lowering);
if (e->arguments && e->arguments->length == 1)
{

View file

@ -70,11 +70,6 @@ DEF_D_RUNTIME (DYNAMIC_CAST, "_d_dynamic_cast", RT(OBJECT),
DEF_D_RUNTIME (INTERFACE_CAST, "_d_interface_cast", RT(OBJECT),
P2(OBJECT, CLASSINFO), 0)
/* Used when calling new on a pointer. The `i' variant is for when the
initializer is nonzero. */
DEF_D_RUNTIME (NEWITEMT, "_d_newitemT", RT(VOIDPTR), P1(CONST_TYPEINFO), 0)
DEF_D_RUNTIME (NEWITEMIT, "_d_newitemiT", RT(VOIDPTR), P1(CONST_TYPEINFO), 0)
/* Used when calling new on an array. The `i' variant is for when the
initializer is nonzero, and the `m' variant is when initializing a
multi-dimensional array. */

View file

@ -780,8 +780,8 @@ public:
this->do_label (label);
if (this->is_return_label (s->ident) && this->func_->fensure != NULL)
this->build_stmt (this->func_->fensure);
if (this->is_return_label (s->ident) && this->func_->fensure () != NULL)
this->build_stmt (this->func_->fensure ());
else if (s->statement)
this->build_stmt (s->statement);
}

View file

@ -1421,7 +1421,7 @@ check_typeinfo_type (const Loc &loc, Scope *sc, Expression *expr)
/* If TypeInfo has not been declared, warn about each location once. */
static Loc warnloc;
if (loc.filename && !warnloc.equals (loc))
if (loc.filename () && !warnloc.equals (loc))
{
error_at (make_location_t (loc),
"%<object.TypeInfo%> could not be found, "

View file

@ -6,7 +6,7 @@ module asm4;
void test1()
{
asm pure nothrow @nogc @trusted {}
asm @safe {}
asm @system {}
}
void test2() pure nothrow @nogc @safe

View file

@ -36,12 +36,12 @@ void main()
enum a = 1;
}
/+ struct S
struct S2
{
int value;
alias this = value;
}
auto s = S(10);
auto s = S2(10);
int n = s;
assert(n == 10); +/
assert(n == 10);
}

View file

@ -0,0 +1,13 @@
// REQUIRED_ARGS: -preview=nosharedaccess
import core.atomic;
class Foo
{
}
void oops()
{
auto f0 = new shared Foo;
auto f1 = new shared Foo;
atomicStore(f0, f1);
}

View file

@ -0,0 +1,5 @@
typedef enum SomeEnum
{
foo = 0,
bar = -10000,
} SomeEnum;

View file

@ -91,8 +91,8 @@ auto ref forwardOrExit(ref int num)
static assert( is(typeof(forwardOrExit(global)) == int));
// // Must not infer ref due to the noreturn rvalue
static assert(!is(typeof(&forwardOrExit(global))));
// Noreturn types do not affect `auto ref` deduction
static assert(is(typeof(&forwardOrExit(global))));
auto ref forwardOrExit2(ref int num)
{
@ -104,8 +104,8 @@ auto ref forwardOrExit2(ref int num)
static assert( is(typeof(forwardOrExit2(global)) == int));
// // Must not infer ref due to the noreturn rvalue
static assert(!is(typeof(&forwardOrExit2(global))));
// Noreturn types do not affect `auto ref` deduction
static assert(is(typeof(&forwardOrExit2(global))));
/*****************************************************************************/

View file

@ -0,0 +1,15 @@
// https://issues.dlang.org/show_bug.cgi?id=22760
extern(C++) void f(T)(T)
{
}
struct S1(T)
{
struct S2
{
}
}
void fun()
{
f(S1!int.S2());
}

View file

@ -0,0 +1,10 @@
// https://issues.dlang.org/show_bug.cgi?id=23874
// REQUIRED_ARGS: -profile=gc
string myToString()
{
return "";
}
enum x = myToString ~ "";
immutable x2 = myToString ~ "";

View file

@ -0,0 +1,17 @@
// https://issues.dlang.org/show_bug.cgi?id=23912
// REQUIRED_ARGS: -preview=dip1000
struct Test
{
string val;
this(return scope string val) scope @safe {}
~this() scope @safe {}
}
void giver(scope string input) @safe
{
accepts(Test(input));
}
void accepts(scope Test test) @safe {}

View file

@ -0,0 +1,7 @@
// EXTRA_FILES: imports/library.c
// https://issues.dlang.org/show_bug.cgi?id=23913
import imports.library;
alias x = __traits(getMember, imports.library, "SomeEnum");

View file

@ -0,0 +1,29 @@
// https://issues.dlang.org/show_bug.cgi?id=23948
void foo1(const(char)* fun = __FILE__)() {
}
void foo2(const(char)* fun = __FILE_FULL_PATH__)() {
}
void foo3(const(char)* fun = __MODULE__)() {
}
void foo4(const(char)* fun = __FUNCTION__)() {
}
void foo5(const(char)* fun = __PRETTY_FUNCTION__)() {
}
void main() {
foo1();
foo2();
foo3();
foo4();
foo5();
}

View file

@ -91,9 +91,9 @@ TEST_OUTPUT:
---
fail_compilation/bug9631.d(106): Error: function `bug9631.targ.ft!().ft(S __param_0)` is not callable using argument types `(S)`
fail_compilation/bug9631.d(106): cannot pass argument `x` of type `bug9631.S` to parameter `bug9631.tem!().S __param_0`
fail_compilation/bug9631.d(107): Error: none of the overloads of template `bug9631.targ.ft` are callable using argument types `!()(S)`
fail_compilation/bug9631.d(107): Error: template `bug9631.targ.ft` is not callable using argument types `!()(S)`
fail_compilation/bug9631.d(105): Candidate is: `ft()(tem!().S)`
fail_compilation/bug9631.d(109): Error: none of the overloads of template `bug9631.targ.ft2` are callable using argument types `!()(S, int)`
fail_compilation/bug9631.d(109): Error: template `bug9631.targ.ft2` is not callable using argument types `!()(S, int)`
fail_compilation/bug9631.d(108): Candidate is: `ft2(T)(S, T)`
---
*/

View file

@ -19,7 +19,11 @@ fail_compilation/chkformat.d(115): Deprecation: argument `& u` for format specif
fail_compilation/chkformat.d(116): Deprecation: argument `16L` for format specification `"%c"` must be `char`, not `long`
fail_compilation/chkformat.d(117): Deprecation: argument `17L` for format specification `"%c"` must be `char`, not `long`
fail_compilation/chkformat.d(118): Deprecation: argument `& u` for format specification `"%s"` must be `char*`, not `int*`
fail_compilation/chkformat.d(119): Deprecation: argument `& u` for format specification `"%ls"` must be `wchar_t*`, not `int*`
fail_compilation/chkformat.d(119): Deprecation: argument `& u` for format specification `"%ls"` must be `wchar_t*`, not `int*`$?:windows=
fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specification `"%lu"` must be `uint`, not `ulong`
fail_compilation/chkformat.d(122): C `long` is 4 bytes on your system|32=
fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specification `"%lu"` must be `uint`, not `ulong`
fail_compilation/chkformat.d(122): C `long` is 4 bytes on your system$
fail_compilation/chkformat.d(201): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long`
fail_compilation/chkformat.d(202): Deprecation: more format specifiers than 1 arguments
fail_compilation/chkformat.d(203): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long`
@ -81,6 +85,7 @@ void test18() { int u; printf("%s\n", &u); }
void test19() { int u; printf("%ls\n", &u); }
//void test20() { int u; char[] s; sprintf(&s[0], "%d\n", &u); }
//void test21() { int u; fprintf(null, "%d\n", &u); }
void test20() { printf("%lu", ulong.init); }
#line 200

View file

@ -2,12 +2,12 @@
EXTRA_FILES: imports/constraints.d
TEST_OUTPUT:
---
fail_compilation/constraints_aggr.d(32): Error: none of the overloads of template `imports.constraints.C.f` are callable using argument types `!()(int)`
fail_compilation/constraints_aggr.d(32): Error: template `imports.constraints.C.f` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(60): Candidate is: `f(T)(T v)`
with `T = int`
must satisfy the following constraint:
` !P!T`
fail_compilation/constraints_aggr.d(33): Error: none of the overloads of template `imports.constraints.C.g` are callable using argument types `!()()`
fail_compilation/constraints_aggr.d(33): Error: template `imports.constraints.C.g` is not callable using argument types `!()()`
fail_compilation/imports/constraints.d(63): Candidate is: `g(this T)()`
with `T = imports.constraints.C`
must satisfy the following constraint:

View file

@ -2,72 +2,72 @@
EXTRA_FILES: imports/constraints.d
TEST_OUTPUT:
---
fail_compilation/constraints_func1.d(79): Error: none of the overloads of template `imports.constraints.test1` are callable using argument types `!()(int)`
fail_compilation/constraints_func1.d(79): Error: template `imports.constraints.test1` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(9): Candidate is: `test1(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
fail_compilation/constraints_func1.d(80): Error: none of the overloads of template `imports.constraints.test2` are callable using argument types `!()(int)`
fail_compilation/constraints_func1.d(80): Error: template `imports.constraints.test2` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(10): Candidate is: `test2(T)(T v)`
with `T = int`
must satisfy the following constraint:
` !P!T`
fail_compilation/constraints_func1.d(81): Error: none of the overloads of template `imports.constraints.test3` are callable using argument types `!()(int)`
fail_compilation/constraints_func1.d(81): Error: template `imports.constraints.test3` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(11): Candidate is: `test3(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
fail_compilation/constraints_func1.d(82): Error: none of the overloads of template `imports.constraints.test4` are callable using argument types `!()(int)`
fail_compilation/constraints_func1.d(82): Error: template `imports.constraints.test4` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(12): Candidate is: `test4(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
fail_compilation/constraints_func1.d(83): Error: none of the overloads of template `imports.constraints.test5` are callable using argument types `!()(int)`
fail_compilation/constraints_func1.d(83): Error: template `imports.constraints.test5` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(13): Candidate is: `test5(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
N!T`
fail_compilation/constraints_func1.d(84): Error: none of the overloads of template `imports.constraints.test6` are callable using argument types `!()(int)`
fail_compilation/constraints_func1.d(84): Error: template `imports.constraints.test6` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(14): Candidate is: `test6(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
N!T
!P!T`
fail_compilation/constraints_func1.d(85): Error: none of the overloads of template `imports.constraints.test7` are callable using argument types `!()(int)`
fail_compilation/constraints_func1.d(85): Error: template `imports.constraints.test7` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(15): Candidate is: `test7(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
N!T`
fail_compilation/constraints_func1.d(86): Error: none of the overloads of template `imports.constraints.test8` are callable using argument types `!()(int)`
fail_compilation/constraints_func1.d(86): Error: template `imports.constraints.test8` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(16): Candidate is: `test8(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
fail_compilation/constraints_func1.d(87): Error: none of the overloads of template `imports.constraints.test9` are callable using argument types `!()(int)`
fail_compilation/constraints_func1.d(87): Error: template `imports.constraints.test9` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(17): Candidate is: `test9(T)(T v)`
with `T = int`
must satisfy the following constraint:
` !P!T`
fail_compilation/constraints_func1.d(88): Error: none of the overloads of template `imports.constraints.test10` are callable using argument types `!()(int)`
fail_compilation/constraints_func1.d(88): Error: template `imports.constraints.test10` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(18): Candidate is: `test10(T)(T v)`
with `T = int`
must satisfy the following constraint:
` !P!T`
fail_compilation/constraints_func1.d(89): Error: none of the overloads of template `imports.constraints.test11` are callable using argument types `!()(int)`
fail_compilation/constraints_func1.d(89): Error: template `imports.constraints.test11` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(19): Candidate is: `test11(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
!P!T`
fail_compilation/constraints_func1.d(90): Error: none of the overloads of template `imports.constraints.test12` are callable using argument types `!()(int)`
fail_compilation/constraints_func1.d(90): Error: template `imports.constraints.test12` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(20): Candidate is: `test12(T)(T v)`
with `T = int`
must satisfy the following constraint:
` !P!T`
fail_compilation/constraints_func1.d(92): Error: none of the overloads of template `imports.constraints.test1` are callable using argument types `!()(int, int)`
fail_compilation/constraints_func1.d(92): Error: template `imports.constraints.test1` is not callable using argument types `!()(int, int)`
fail_compilation/imports/constraints.d(9): Candidate is: `test1(T)(T v)`
---
*/

View file

@ -2,83 +2,83 @@
EXTRA_FILES: imports/constraints.d
TEST_OUTPUT:
---
fail_compilation/constraints_func2.d(94): Error: none of the overloads of template `imports.constraints.test13` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(94): Error: template `imports.constraints.test13` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(23): Candidate is: `test13(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
!P!T`
fail_compilation/constraints_func2.d(95): Error: none of the overloads of template `imports.constraints.test14` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(95): Error: template `imports.constraints.test14` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(24): Candidate is: `test14(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` !P!T
N!T`
fail_compilation/constraints_func2.d(96): Error: none of the overloads of template `imports.constraints.test15` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(96): Error: template `imports.constraints.test15` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(25): Candidate is: `test15(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` !P!T
!P!T`
fail_compilation/constraints_func2.d(97): Error: none of the overloads of template `imports.constraints.test16` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(97): Error: template `imports.constraints.test16` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(26): Candidate is: `test16(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
N!T`
fail_compilation/constraints_func2.d(98): Error: none of the overloads of template `imports.constraints.test17` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(98): Error: template `imports.constraints.test17` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(27): Candidate is: `test17(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
fail_compilation/constraints_func2.d(99): Error: none of the overloads of template `imports.constraints.test18` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(99): Error: template `imports.constraints.test18` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(28): Candidate is: `test18(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
N!T`
fail_compilation/constraints_func2.d(100): Error: none of the overloads of template `imports.constraints.test19` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(100): Error: template `imports.constraints.test19` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(29): Candidate is: `test19(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
!P!T
N!T`
fail_compilation/constraints_func2.d(101): Error: none of the overloads of template `imports.constraints.test20` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(101): Error: template `imports.constraints.test20` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(30): Candidate is: `test20(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
fail_compilation/constraints_func2.d(102): Error: none of the overloads of template `imports.constraints.test21` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(102): Error: template `imports.constraints.test21` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(31): Candidate is: `test21(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` N!T
N!T`
fail_compilation/constraints_func2.d(103): Error: none of the overloads of template `imports.constraints.test22` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(103): Error: template `imports.constraints.test22` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(32): Candidate is: `test22(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` !P!T
!P!T`
fail_compilation/constraints_func2.d(104): Error: none of the overloads of template `imports.constraints.test23` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(104): Error: template `imports.constraints.test23` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(33): Candidate is: `test23(T)(T v)`
with `T = int`
must satisfy one of the following constraints:
` !P!T
N!T
!P!T`
fail_compilation/constraints_func2.d(105): Error: none of the overloads of template `imports.constraints.test24` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(105): Error: template `imports.constraints.test24` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(34): Candidate is: `test24(R)(R r)`
with `R = int`
must satisfy the following constraint:
` __traits(hasMember, R, "stuff")`
fail_compilation/constraints_func2.d(106): Error: none of the overloads of template `imports.constraints.test25` are callable using argument types `!()(int)`
fail_compilation/constraints_func2.d(106): Error: template `imports.constraints.test25` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(35): Candidate is: `test25(T)(T v)`
with `T = int`
must satisfy the following constraint:
` N!T`
fail_compilation/constraints_func2.d(107): Error: none of the overloads of template `imports.constraints.test26` are callable using argument types `!(float)(int)`
fail_compilation/constraints_func2.d(107): Error: template `imports.constraints.test26` is not callable using argument types `!(float)(int)`
fail_compilation/imports/constraints.d(36): Candidate is: `test26(T, U)(U u)`
with `T = float,
U = int`

View file

@ -23,21 +23,21 @@ fail_compilation/imports/constraints.d(42): `overload(T,
must satisfy one of the following constraints:
` N!T
N!V`
fail_compilation/constraints_func3.d(56): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()()`
fail_compilation/constraints_func3.d(56): Error: template `imports.constraints.variadic` is not callable using argument types `!()()`
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
fail_compilation/constraints_func3.d(57): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int)`
fail_compilation/constraints_func3.d(57): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int)`
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
with `A = int,
T = ()`
must satisfy the following constraint:
` N!int`
fail_compilation/constraints_func3.d(58): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int)`
fail_compilation/constraints_func3.d(58): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int)`
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
with `A = int,
T = (int)`
must satisfy the following constraint:
` N!int`
fail_compilation/constraints_func3.d(59): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int, int)`
fail_compilation/constraints_func3.d(59): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int, int)`
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
with `A = int,
T = (int, int)`

View file

@ -44,13 +44,13 @@ fail_compilation/imports/constraints.d(42): `overload(T,
N!V`
void overload(T, V)(T v1, V v2) if (N!T || N!V);
^
fail_compilation/constraints_func4.d(93): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()()`
fail_compilation/constraints_func4.d(93): Error: template `imports.constraints.variadic` is not callable using argument types `!()()`
variadic();
^
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
void variadic(A, T...)(A a, T v) if (N!int);
^
fail_compilation/constraints_func4.d(94): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int)`
fail_compilation/constraints_func4.d(94): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int)`
variadic(0);
^
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
@ -60,7 +60,7 @@ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T.
` N!int`
void variadic(A, T...)(A a, T v) if (N!int);
^
fail_compilation/constraints_func4.d(95): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int)`
fail_compilation/constraints_func4.d(95): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int)`
variadic(0, 1);
^
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`
@ -70,7 +70,7 @@ fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T.
` N!int`
void variadic(A, T...)(A a, T v) if (N!int);
^
fail_compilation/constraints_func4.d(96): Error: none of the overloads of template `imports.constraints.variadic` are callable using argument types `!()(int, int, int)`
fail_compilation/constraints_func4.d(96): Error: template `imports.constraints.variadic` is not callable using argument types `!()(int, int, int)`
variadic(0, 1, 2);
^
fail_compilation/imports/constraints.d(43): Candidate is: `variadic(A, T...)(A a, T v)`

View file

@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/diag13942.d(18): Error: template instance `isRawStaticArray!()` does not match template declaration `isRawStaticArray(T, A...)`
fail_compilation/diag13942.d(26): Error: none of the overloads of template `diag13942.to!double.to` are callable using argument types `!()()`
fail_compilation/diag13942.d(26): Error: template `diag13942.to!double.to` is not callable using argument types `!()()`
fail_compilation/diag13942.d(17): Candidate is: `to(A...)(A args)`
---
*/

View file

@ -3,7 +3,7 @@ TEST_OUTPUT:
---
fail_compilation/diag16977.d(25): Error: undefined identifier `undefined`, did you mean function `undefinedId`?
fail_compilation/diag16977.d(26): Error: cannot implicitly convert expression `"\x01string"` of type `string` to `int`
fail_compilation/diag16977.d(27): Error: none of the overloads of template `diag16977.templ` are callable using argument types `!()(int)`
fail_compilation/diag16977.d(27): Error: template `diag16977.templ` is not callable using argument types `!()(int)`
fail_compilation/diag16977.d(20): Candidate is: `templ(S)(S s)`
with `S = int`
must satisfy the following constraint:

View file

@ -3,7 +3,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/diag20268.d(12): Error: none of the overloads of template `diag20268.__lambda4` are callable using argument types `!()(int)`
fail_compilation/diag20268.d(12): Error: template `diag20268.__lambda4` is not callable using argument types `!()(int)`
fail_compilation/diag20268.d(11): Candidate is: `__lambda4(__T1, __T2)(x, y)`
---
*/

View file

@ -2,10 +2,10 @@
TEST_OUTPUT:
---
fail_compilation/diag23355.d(1): Error: undefined identifier `n`
fail_compilation/diag23355.d(4): Error: none of the overloads of template `diag23355.ffi1` are callable using argument types `!()(int[4])`
fail_compilation/diag23355.d(4): Error: template `diag23355.ffi1` is not callable using argument types `!()(int[4])`
fail_compilation/diag23355.d(1): Candidate is: `ffi1(T)(T[n] s)`
fail_compilation/diag23355.d(2): Error: undefined identifier `n`
fail_compilation/diag23355.d(4): Error: none of the overloads of template `diag23355.ffi2` are callable using argument types `!()(int[4])`
fail_compilation/diag23355.d(4): Error: template `diag23355.ffi2` is not callable using argument types `!()(int[4])`
fail_compilation/diag23355.d(2): Candidate is: `ffi2()(T[n] s)`
---
*/

View file

@ -14,7 +14,7 @@ fail_compilation/diag8101.d(41): `diag8101.f_2(int, int,
fail_compilation/diag8101.d(42): `diag8101.f_2(int, int, int, int, int)`
fail_compilation/diag8101.d(43): `diag8101.f_2(int, int, int, int, int, int)`
fail_compilation/diag8101.d(63): ... (1 more, -v to show) ...
fail_compilation/diag8101.d(65): Error: none of the overloads of template `diag8101.t_0` are callable using argument types `!()()`
fail_compilation/diag8101.d(65): Error: template `diag8101.t_0` is not callable using argument types `!()()`
fail_compilation/diag8101.d(46): Candidate is: `t_0(T1)()`
fail_compilation/diag8101.d(66): Error: none of the overloads of template `diag8101.t_1` are callable using argument types `!()()`
fail_compilation/diag8101.d(48): Candidates are: `t_1(T1)()`

View file

@ -2,13 +2,13 @@
TEST_OUTPUT:
---
fail_compilation/diag8648.d(18): Error: undefined identifier `X`
fail_compilation/diag8648.d(29): Error: none of the overloads of template `diag8648.foo` are callable using argument types `!()(Foo!(int, 1))`
fail_compilation/diag8648.d(29): Error: template `diag8648.foo` is not callable using argument types `!()(Foo!(int, 1))`
fail_compilation/diag8648.d(18): Candidate is: `foo(T, n)(X!(T, n))`
fail_compilation/diag8648.d(20): Error: undefined identifier `a`
fail_compilation/diag8648.d(31): Error: none of the overloads of template `diag8648.bar` are callable using argument types `!()(Foo!(int, 1))`
fail_compilation/diag8648.d(31): Error: template `diag8648.bar` is not callable using argument types `!()(Foo!(int, 1))`
fail_compilation/diag8648.d(20): Candidate is: `bar(T)(Foo!(T, a))`
fail_compilation/diag8648.d(20): Error: undefined identifier `a`
fail_compilation/diag8648.d(32): Error: none of the overloads of template `diag8648.bar` are callable using argument types `!()(Foo!(int, f))`
fail_compilation/diag8648.d(32): Error: template `diag8648.bar` is not callable using argument types `!()(Foo!(int, f))`
fail_compilation/diag8648.d(20): Candidate is: `bar(T)(Foo!(T, a))`
---
*/

View file

@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/diag9004.d(21): Error: none of the overloads of template `diag9004.bar` are callable using argument types `!()(Foo!int, int)`
fail_compilation/diag9004.d(21): Error: template `diag9004.bar` is not callable using argument types `!()(Foo!int, int)`
fail_compilation/diag9004.d(14): Candidate is: `bar(FooT)(FooT foo, FooT.T x)`
---
*/

View file

@ -1,19 +0,0 @@
/*
TEST_OUTPUT:
---
fail_compilation/diag9574.d(12): Error: cannot use syntax `alias this = x`, use `alias x this` instead
fail_compilation/diag9574.d(18): Error: cannot use syntax `alias this = x`, use `alias x this` instead
---
*/
struct S
{
int x;
alias this = x;
}
class C
{
int x;
alias this = x;
}

View file

@ -3,7 +3,7 @@ TEST_OUTPUT:
---
fail_compilation/diag_template_alias.d(1): Error: identifier expected for template `alias` parameter
fail_compilation/diag_template_alias.d(1): Error: found `alias` when expecting `(`
fail_compilation/diag_template_alias.d(1): Error: semicolon expected following function declaration
fail_compilation/diag_template_alias.d(1): Error: semicolon expected following function declaration, not `(`
fail_compilation/diag_template_alias.d(1): Error: declaration expected, not `(`
---
*/

View file

@ -3,7 +3,7 @@ TEST_OUTPUT:
---
fail_compilation/diag_template_this.d(1): Error: identifier expected for template `this` parameter
fail_compilation/diag_template_this.d(1): Error: found `this` when expecting `(`
fail_compilation/diag_template_this.d(1): Error: semicolon expected following function declaration
fail_compilation/diag_template_this.d(1): Error: semicolon expected following function declaration, not `(`
fail_compilation/diag_template_this.d(1): Error: declaration expected, not `(`
---
*/

View file

@ -4,7 +4,7 @@ TEST_OUTPUT:
---
fail_compilation/diagin.d(14): Error: function `diagin.foo(in int)` is not callable using argument types `()`
fail_compilation/diagin.d(14): too few arguments, expected 1, got 0
fail_compilation/diagin.d(16): Error: none of the overloads of template `diagin.foo1` are callable using argument types `!()(bool[])`
fail_compilation/diagin.d(16): Error: template `diagin.foo1` is not callable using argument types `!()(bool[])`
fail_compilation/diagin.d(20): Candidate is: `foo1(T)(in T v, string)`
---
*/

View file

@ -21,7 +21,7 @@ __error__
}
}
)`
fail_compilation/e15876_3.d(28): Error: semicolon expected following function declaration
fail_compilation/e15876_3.d(28): Error: semicolon expected following function declaration, not `End of File`
---
*/
d(={for

View file

@ -14,10 +14,10 @@ fail_compilation/fail12744.d(61): Error: template instance `fail12744.bar12744L!
fail_compilation/fail12744.d(40): Error: incompatible parameter storage classes `lazy` and `out`
fail_compilation/fail12744.d(62): Error: template instance `fail12744.bar12744L!(foo12744O)` error instantiating
fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `out`
fail_compilation/fail12744.d(67): Error: none of the overloads of template `fail12744.bar12744A` are callable using argument types `!(foo12744O)(int)`
fail_compilation/fail12744.d(67): Error: template `fail12744.bar12744A` is not callable using argument types `!(foo12744O)(int)`
fail_compilation/fail12744.d(41): Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)`
fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes `auto ref` and `lazy`
fail_compilation/fail12744.d(68): Error: none of the overloads of template `fail12744.bar12744A` are callable using argument types `!(foo12744L)(int)`
fail_compilation/fail12744.d(68): Error: template `fail12744.bar12744A` is not callable using argument types `!(foo12744L)(int)`
fail_compilation/fail12744.d(41): Candidate is: `bar12744A(alias f)(auto ref PTT12744!f args)`
---
*/

View file

@ -4,7 +4,7 @@ TEST_OUTPUT:
fail_compilation/fail14669.d(11): Error: `auto` can only be used as part of `auto ref` for template function parameters
fail_compilation/fail14669.d(16): Error: template instance `fail14669.foo1!()` error instantiating
fail_compilation/fail14669.d(12): Error: `auto` can only be used as part of `auto ref` for template function parameters
fail_compilation/fail14669.d(17): Error: none of the overloads of template `fail14669.foo2` are callable using argument types `!()(int)`
fail_compilation/fail14669.d(17): Error: template `fail14669.foo2` is not callable using argument types `!()(int)`
fail_compilation/fail14669.d(12): Candidate is: `foo2()(auto int a)`
---
*/

View file

@ -5,7 +5,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail15414.d(20): Deprecation: `__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `fun`
fail_compilation/fail15414.d(20): Deprecation: `__traits(getAttributes)` may only be used for individual functions, not the overload set `fun`
fail_compilation/fail15414.d(20): the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from
---
*/

View file

@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail162.d(25): Error: none of the overloads of template `fail162.testHelper` are callable using argument types `!()(string, string)`
fail_compilation/fail162.d(25): Error: template `fail162.testHelper` is not callable using argument types `!()(string, string)`
fail_compilation/fail162.d(10): Candidate is: `testHelper(A...)()`
fail_compilation/fail162.d(30): Error: template instance `fail162.test!("hello", "world")` error instantiating
---

View file

@ -3,7 +3,7 @@ REQUIRED_ARGS: -verrors=spec -o-
TEST_OUTPUT:
---
(spec:1) fail_compilation/fail20730b.d-mixin-43(43): Error: C style cast illegal, use `cast(int)mod`
fail_compilation/fail20730b.d(26): Error: none of the overloads of template `fail20730b.atomicOp` are callable using argument types `!("+=")(shared(uint), int)`
fail_compilation/fail20730b.d(26): Error: template `fail20730b.atomicOp` is not callable using argument types `!("+=")(shared(uint), int)`
fail_compilation/fail20730b.d(41): Candidate is: `atomicOp(string op, T, V1)(shared ref T val, V1 mod)`
with `op = "+=",
T = uint,

View file

@ -2,7 +2,7 @@
TEST_OUTPUT:
---
fail_compilation/fail236.d(14): Error: undefined identifier `x`
fail_compilation/fail236.d(22): Error: none of the overloads of template `fail236.Templ2` are callable using argument types `!()(int)`
fail_compilation/fail236.d(22): Error: template `fail236.Templ2` is not callable using argument types `!()(int)`
fail_compilation/fail236.d(12): Candidate is: `Templ2(alias a)(x)`
---
*/

View file

@ -1,7 +1,7 @@
/* TEST_OUTPUT:
---
fail_compilation/fail23626a.d(10): Deprecation: function `fail23626a.ambig` cannot overload `extern(D)` function at fail_compilation/fail23626a.d(9)
fail_compilation/fail23626a.d(13): Deprecation: function `fail23626a.ambigC` cannot overload `extern(C)` function at fail_compilation/fail23626a.d(12)
fail_compilation/fail23626a.d(13): Error: function `fail23626a.ambigC` cannot overload `extern(C)` function at fail_compilation/fail23626a.d(12)
fail_compilation/fail23626a.d(16): Error: function `fail23626a.ambigCxx(int a)` conflicts with previous declaration at fail_compilation/fail23626a.d(15)
---
*/

View file

@ -108,3 +108,17 @@ void test2456b()
catch (Throwable) {} // NG
}
}
/*
TEST_OUTPUT:
---
fail_compilation/fail2456.d(121): Deprecation: can only catch mutable or const qualified types, not `immutable(Exception)`
---
*/
void main() {
try {
throw new Exception("");
} catch (immutable Exception e) {
assert(0);
}
}

View file

@ -61,8 +61,8 @@ auto f6() { return ""; } // string(), conflict
TEST_OUTPUT:
---
fail_compilation/fail2789.d(67): Error: function `fail2789.f_ExternC1()` conflicts with previous declaration at fail_compilation/fail2789.d(66)
fail_compilation/fail2789.d(70): Deprecation: function `fail2789.f_ExternC2` cannot overload `extern(C)` function at fail_compilation/fail2789.d(69)
fail_compilation/fail2789.d(73): Deprecation: function `fail2789.f_ExternC3` cannot overload `extern(C)` function at fail_compilation/fail2789.d(72)
fail_compilation/fail2789.d(70): Error: function `fail2789.f_ExternC2` cannot overload `extern(C)` function at fail_compilation/fail2789.d(69)
fail_compilation/fail2789.d(73): Error: function `fail2789.f_ExternC3` cannot overload `extern(C)` function at fail_compilation/fail2789.d(72)
---
*/

View file

@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail8009.d(9): Error: none of the overloads of template `fail8009.filter` are callable using argument types `!()(void)`
fail_compilation/fail8009.d(9): Error: template `fail8009.filter` is not callable using argument types `!()(void)`
fail_compilation/fail8009.d(8): Candidate is: `filter(R)(scope bool delegate(ref BAD!R) func)`
---
*/

View file

@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail95.d(19): Error: none of the overloads of template `fail95.A` are callable using argument types `!()(int)`
fail_compilation/fail95.d(19): Error: template `fail95.A` is not callable using argument types `!()(int)`
fail_compilation/fail95.d(11): Candidate is: `A(alias T)(T)`
---
*/

View file

@ -4,8 +4,8 @@ fail_compilation/failcontracts.d(18): Error: missing `{ ... }` for function lite
fail_compilation/failcontracts.d(18): Error: semicolon expected following auto declaration, not `bode`
fail_compilation/failcontracts.d(19): Error: function declaration without return type. (Note that constructors are always named `this`)
fail_compilation/failcontracts.d(19): Error: no identifier for declarator `test1()`
fail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration
fail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration
fail_compilation/failcontracts.d(19): Error: semicolon expected following function declaration, not `bode`
fail_compilation/failcontracts.d(20): Error: semicolon expected following function declaration, not `bode`
fail_compilation/failcontracts.d(22): Error: unexpected `(` in declarator
fail_compilation/failcontracts.d(22): Error: found `T` when expecting `)`
fail_compilation/failcontracts.d(22): Error: enum declaration is invalid

Some files were not shown because too many files have changed in this diff Show more