if (fd2->isFuture ())
continue;
- if (FuncDeclaration::leastAsSpecialized (fd, fd2, NULL)
- == MATCH::nomatch
- && FuncDeclaration::leastAsSpecialized (fd2, fd, NULL)
- == MATCH::nomatch)
+ if (dmd::leastAsSpecialized (fd, fd2, NULL) == MATCH::nomatch
+ && dmd::leastAsSpecialized (fd2, fd, NULL) == MATCH::nomatch)
continue;
/* Hiding detected; same name, overlapping specializations. */
-c11e1d1708646c9ac81ac2aafb57fa1ef5d289ad
+07bc5b9b3c81cc0d4314e0040de981124b363ea5
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
| [libelf.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/libelf.d) | Library in ELF format (Unix) |
| [libmach.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/libmach.d) | Library in Mach-O format (macOS) |
| [libmscoff.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/libmscoff.d) | Library in COFF format (32/64-bit Windows) |
-| [libomf.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/libomf.d) | Library in OMF format (legacy 32-bit Windows) |
| [scanelf.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/scanelf.d) | Extract symbol names from a library in ELF format |
| [scanmach.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/scanmach.d) | Extract symbol names from a library in Mach-O format |
| [scanmscoff.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/scanmscoff.d) | Extract symbol names from a library in COFF format |
-| [scanomf.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/scanomf.d) | Extract symbol names from a library in OMF format |
### Code generation / back-end interfacing
return dmd.funcsem.functionSemantic3(fd);
}
+MATCH leastAsSpecialized(FuncDeclaration f, FuncDeclaration g, Identifiers* names)
+{
+ import dmd.funcsem;
+ return dmd.funcsem.leastAsSpecialized(f, g, names);
+}
+
/***********************************************************
* hdrgen.d
*/
{
bool functionSemantic(FuncDeclaration* fd);
bool functionSemantic3(FuncDeclaration* fd);
+ MATCH leastAsSpecialized(FuncDeclaration *f, FuncDeclaration *g, Identifiers *names);
}
//enum STC : ulong from astenums.d:
bool overloadInsert(Dsymbol *s) override;
bool inUnittest();
- static MATCH leastAsSpecialized(FuncDeclaration *f, FuncDeclaration *g, Identifiers *names);
LabelDsymbol *searchLabel(Identifier *ident, const Loc &loc);
const char *toPrettyChars(bool QualifyTypes = false) override;
const char *toFullSignature(); // for diagnostics, e.g. 'int foo(int x, int y) pure'
{
filetype = FileType.c;
- global.compileEnv.masm = target.os == Target.OS.Windows && !target.omfobj; // Microsoft inline assembler format
+ global.compileEnv.masm = target.os == Target.OS.Windows; // Microsoft inline assembler format
scope p = new CParser!AST(this, buf, cast(bool) docfile, global.errorSink, target.c, &defines, &global.compileEnv);
global.compileEnv.masm = false;
p.nextToken();
*/
structsize = 4;
}
- else if (target.c.bitFieldStyle == TargetC.BitFieldStyle.DM)
- {
- structsize = 0;
- alignsize = 0;
- }
else
structsize = 0;
break;
return;
}
}
- else if (style == TargetC.BitFieldStyle.DM)
- {
- if (anon && bfd.fieldWidth && (!fieldState.inFlight || fieldState.bitOffset == 0))
- return; // this probably should be a bug in DMC
- if (ad.alignsize == 0)
- ad.alignsize = 1;
- if (bfd.fieldWidth == 0)
- {
- if (fieldState.inFlight && !isunion)
- {
- const alsz = memsize;
- fieldState.offset = (fieldState.offset + alsz - 1) & ~(alsz - 1);
- ad.structsize = fieldState.offset;
- }
-
- fieldState.inFlight = false;
- return;
- }
- }
if (!fieldState.inFlight)
{
}
}
}
- else if (style == TargetC.BitFieldStyle.DM ||
- style == TargetC.BitFieldStyle.MS)
+ else if (style == TargetC.BitFieldStyle.MS)
{
if (memsize != fieldState.fieldSize ||
fieldState.bitOffset + bfd.fieldWidth > fieldState.fieldSize * 8)
return buf.extractChars();
}
+ /****************************
+ * Similar to `toChars`, but does not print the template constraints
+ */
+ const(char)* toCharsNoConstraints() const
+ {
+ HdrGenState hgs = { skipConstraints: true };
+ OutBuffer buf;
+ toCharsMaybeConstraints(this, buf, hgs);
+ return buf.extractChars();
+ }
+
override Visibility visible() pure nothrow @nogc @safe
{
return visibility;
if (EnumMember em = s.isEnumMember())
{
em.type = commonType;
- em.value = em.value.castTo(sc, commonType);
+ // optimize out the cast so that other parts of the compiler can
+ // assume that an integral enum's members are `IntegerExp`s.
+ // https://issues.dlang.org/show_bug.cgi?id=24504
+ em.value = em.value.castTo(sc, commonType).optimize(WANTvalue);
}
});
}
// Possible to cast to one type while painting to another type
Type *to; // type to cast to
unsigned char mod; // MODxxxxx
+ d_bool trusted; // assume cast is safe
CastExp *syntaxCopy() override;
bool isLvalue() override;
if (auto te = exp.e1.isTupleExp())
{
- if (exp.ident == Id.offsetof)
+ if (exp.ident == Id.offsetof ||
+ exp.ident == Id.bitoffsetof ||
+ exp.ident == Id.bitwidth)
{
/* 'distribute' the .offsetof to each of the tuple elements.
*/
auto exps = new Expressions(te.exps.length);
foreach (i, e; (*te.exps)[])
{
- (*exps)[i] = new DotIdExp(e.loc, e, Id.offsetof);
+ (*exps)[i] = new DotIdExp(e.loc, e, exp.ident);
}
// Don't evaluate te.e0 in runtime
Expression e = new TupleExp(exp.loc, null, exps);
!cfile &&
(exp.ident == Id._mangleof ||
exp.ident == Id.offsetof ||
+ exp.ident == Id.bitoffsetof ||
+ exp.ident == Id.bitwidth ||
exp.ident == Id._init ||
exp.ident == Id.stringof)
))
Expression visitStructLiteral(StructLiteralExp exp)
{
+ if (!exp.elements)
+ return exp;
+
foreach (ref element; *exp.elements)
{
if (element)
if (exp.lowering)
exp.lowering = exp.lowering.resolveLoc(loc, sc);
+ if (!exp.arguments)
+ return exp;
+
foreach (ref element; *exp.arguments)
{
if (element)
Expression visitCall(CallExp exp)
{
+ if (!exp.arguments)
+ return exp;
+
foreach (ref element; *exp.arguments)
{
if (element)
{
exp.e1 = exp.e1.resolveLoc(loc, sc);
+ if (!exp.arguments)
+ return exp;
+
foreach (ref element; *exp.arguments)
{
if (element)
if (exp.basis)
exp.basis = exp.basis.resolveLoc(loc, sc);
+ if (!exp.elements)
+ return exp;
+
foreach (ref element; *exp.elements)
{
if (element)
return false;
}
- /****************************************************
- * Determine if 'this' overrides fd.
- * Return !=0 if it does.
- */
- extern (D) final int overrides(FuncDeclaration fd)
- {
- int result = 0;
- if (fd.ident == ident)
- {
- const cov = type.covariant(fd.type);
- if (cov != Covariant.distinct)
- {
- ClassDeclaration cd1 = toParent().isClassDeclaration();
- ClassDeclaration cd2 = fd.toParent().isClassDeclaration();
- if (cd1 && cd2 && cd2.isBaseOf(cd1, null))
- result = 1;
- }
- }
- return result;
- }
-
/****************************************************
* Overload this FuncDeclaration with the new one f.
* Return true if successful; i.e. no conflict.
return false;
}
- /*************************************
- * Determine partial specialization order of functions `f` vs `g`.
- * This is very similar to TemplateDeclaration::leastAsSpecialized().
- * Params:
- * f = first function
- * g = second function
- * names = names of parameters
- * Returns:
- * match 'this' is at least as specialized as g
- * 0 g is more specialized than 'this'
- */
- static MATCH leastAsSpecialized(FuncDeclaration f, FuncDeclaration g, Identifiers* names)
- {
- enum LOG_LEASTAS = 0;
- static if (LOG_LEASTAS)
- {
- import core.stdc.stdio : printf;
- printf("leastAsSpecialized(%s, %s, %s)\n", f.toChars(), g.toChars(), names ? names.toChars() : "null");
- printf("%s, %s\n", f.type.toChars(), g.type.toChars());
- }
-
- /* This works by calling g() with f()'s parameters, and
- * if that is possible, then f() is at least as specialized
- * as g() is.
- */
-
- TypeFunction tf = f.type.toTypeFunction();
- TypeFunction tg = g.type.toTypeFunction();
-
- /* If both functions have a 'this' pointer, and the mods are not
- * the same and g's is not const, then this is less specialized.
- */
- if (f.needThis() && g.needThis() && tf.mod != tg.mod)
- {
- if (f.isCtorDeclaration())
- {
- if (!MODimplicitConv(tg.mod, tf.mod))
- return MATCH.nomatch;
- }
- else
- {
- if (!MODimplicitConv(tf.mod, tg.mod))
- return MATCH.nomatch;
- }
- }
-
- /* Create a dummy array of arguments out of the parameters to f()
- */
- Expressions args;
- foreach (u, p; tf.parameterList)
- {
- Expression e;
- if (p.isReference())
- {
- e = new IdentifierExp(Loc.initial, p.ident);
- e.type = p.type;
- }
- else
- e = p.type.defaultInitLiteral(Loc.initial);
- args.push(e);
- }
-
- MATCH m = tg.callMatch(null, ArgumentList(&args, names), 1);
- if (m > MATCH.nomatch)
- {
- /* A variadic parameter list is less specialized than a
- * non-variadic one.
- */
- if (tf.parameterList.varargs && !tg.parameterList.varargs)
- goto L1; // less specialized
-
- static if (LOG_LEASTAS)
- {
- printf(" matches %d, so is least as specialized\n", m);
- }
- return m;
- }
- L1:
- static if (LOG_LEASTAS)
- {
- printf(" doesn't match, so is not as specialized\n");
- }
- return MATCH.nomatch;
- }
-
/********************************
* Searches for a label with the given identifier. This function will insert a new
* `LabelDsymbol` into `labtab` if it does not contain a mapping for `ident`.
return false;
}
- /****************************************************
- * Determine whether an 'out' contract is declared inside
- * the given function or any of its overrides.
- * Params:
- * fd = the function to search
- * Returns:
- * true found an 'out' contract
- */
- static bool needsFensure(FuncDeclaration fd) @safe
- {
- if (fd.fensures)
- return true;
-
- foreach (fdv; fd.foverrides)
- {
- if (needsFensure(fdv))
- return true;
- }
- return false;
- }
-
/*********************************************
* Returns: the function's parameter list, and whether
* it is variadic or not.
return fd;
}
- /+
- + Checks the parameter and return types iff this is a `main` function.
- +
- + The following signatures are allowed for a `D main`:
- + - Either no or a single parameter of type `string[]`
- + - Return type is either `void`, `int` or `noreturn`
- +
- + The following signatures are standard C:
- + - `int main()`
- + - `int main(int, char**)`
- +
- + This function accepts the following non-standard extensions:
- + - `char** envp` as a third parameter
- + - `void` / `noreturn` as return type
- +
- + This function will issue errors for unexpected arguments / return types.
- +/
- extern (D) final void checkMain()
- {
- if (ident != Id.main || isMember() || isNested())
- return; // Not a main function
-
- TypeFunction tf = type.toTypeFunction();
-
- Type retType = tf.nextOf();
- if (!retType)
- {
- // auto main(), check after semantic
- assert(this.inferRetType);
- return;
- }
-
- /// Checks whether `t` is equivalent to `char**`
- /// Ignores qualifiers and treats enums according to their base type
- static bool isCharPtrPtr(Type t)
- {
- auto tp = t.toBasetype().isTypePointer();
- if (!tp)
- return false;
-
- tp = tp.next.toBasetype().isTypePointer();
- if (!tp)
- return false;
-
- return tp.next.toBasetype().ty == Tchar;
- }
-
- // Neither of these qualifiers is allowed because they affect the ABI
- enum invalidSTC = STC.out_ | STC.ref_ | STC.lazy_;
-
- const nparams = tf.parameterList.length;
- bool argerr;
-
- const linkage = resolvedLinkage();
- if (linkage == LINK.d)
- {
- if (nparams == 1)
- {
- auto fparam0 = tf.parameterList[0];
- auto t = fparam0.type.toBasetype();
- if (t.ty != Tarray ||
- t.nextOf().ty != Tarray ||
- t.nextOf().nextOf().ty != Tchar ||
- fparam0.storageClass & invalidSTC)
- {
- argerr = true;
- }
- }
-
- if (tf.parameterList.varargs || nparams >= 2 || argerr)
- .error(loc, "%s `%s` parameter list must be empty or accept one parameter of type `string[]`", kind, toPrettyChars);
- }
-
- else if (linkage == LINK.c)
- {
- if (nparams == 2 || nparams == 3)
- {
- // Argument count must be int
- auto argCount = tf.parameterList[0];
- argerr |= !!(argCount.storageClass & invalidSTC);
- argerr |= argCount.type.toBasetype().ty != Tint32;
-
- // Argument pointer must be char**
- auto argPtr = tf.parameterList[1];
- argerr |= !!(argPtr.storageClass & invalidSTC);
- argerr |= !isCharPtrPtr(argPtr.type);
-
- // `char** environ` is a common extension, see J.5.1 of the C standard
- if (nparams == 3)
- {
- auto envPtr = tf.parameterList[2];
- argerr |= !!(envPtr.storageClass & invalidSTC);
- argerr |= !isCharPtrPtr(envPtr.type);
- }
- }
- else
- argerr = nparams != 0;
-
- // Disallow variadic main() - except for K&R declarations in C files.
- // E.g. int main(), int main(argc, argv) int argc, char** argc { ... }
- if (tf.parameterList.varargs && (!this.isCsymbol() || (!tf.parameterList.hasIdentifierList && nparams)))
- argerr |= true;
-
- if (argerr)
- {
- .error(loc, "%s `%s` parameters must match one of the following signatures", kind, toPrettyChars);
- loc.errorSupplemental("`main()`");
- loc.errorSupplemental("`main(int argc, char** argv)`");
- loc.errorSupplemental("`main(int argc, char** argv, char** environ)` [POSIX extension]");
- }
- }
- else
- return; // Neither C nor D main, ignore (should probably be an error)
-
- // Allow enums with appropriate base types (same ABI)
- retType = retType.toBasetype();
-
- if (retType.ty != Tint32 && retType.ty != Tvoid && retType.ty != Tnoreturn)
- .error(loc, "%s `%s` must return `int`, `void` or `noreturn`, not `%s`", kind, toPrettyChars, tf.nextOf().toChars());
- }
-
- /***********************************************
- * Check all return statements for a function to verify that returning
- * using NRVO is possible.
- *
- * Returns:
- * `false` if the result cannot be returned by hidden reference.
- */
- extern (D) final bool checkNRVO()
- {
- if (!isNRVO() || returns is null)
- return false;
-
- auto tf = type.toTypeFunction();
- if (tf.isref)
- return false;
-
- foreach (rs; *returns)
- {
- if (auto ve = rs.exp.isVarExp())
- {
- auto v = ve.var.isVarDeclaration();
- if (!v || v.isReference())
- return false;
- else if (nrvo_var is null)
- {
- // Variables in the data segment (e.g. globals, TLS or not),
- // parameters and closure variables cannot be NRVOed.
- if (v.isDataseg() || v.isParameter() || v.toParent2() != this)
- return false;
- if (v.nestedrefs.length && needsClosure())
- return false;
- // don't know if the return storage is aligned
- version (MARS)
- {
- if (alignSectionVars && (*alignSectionVars).contains(v))
- return false;
- }
- // The variable type needs to be equivalent to the return type.
- if (!v.type.equivalent(tf.next))
- return false;
- //printf("Setting nrvo to %s\n", v.toChars());
- nrvo_var = v;
- }
- else if (nrvo_var != v)
- return false;
- }
- else //if (!exp.isLvalue()) // keep NRVO-ability
- return false;
- }
- return true;
- }
-
override final inout(FuncDeclaration) isFuncDeclaration() inout
{
return this;
assert(mismatches.isMutable);
}
-/**************************************
- * Returns an indirect type one step from t.
- */
-Type getIndirection(Type t)
-{
- t = t.baseElemOf();
- if (t.ty == Tarray || t.ty == Tpointer)
- return t.nextOf().toBasetype();
- if (t.ty == Taarray || t.ty == Tclass)
- return t;
- if (t.ty == Tstruct)
- return t.hasPointers() ? t : null; // TODO
-
- // should consider TypeDelegate?
- return null;
-}
-
/**************************************
* Performs type-based alias analysis between a newly created value and a pre-
* existing memory reference:
import dmd.typesem;
import dmd.visitor;
+version (IN_GCC) {}
+else version (IN_LLVM) {}
+else version = MARS;
+
/* Tweak all return statements and dtor call for nrvo_var, for correct NRVO.
*/
extern (C++) final class NrvoWalker : StatementRewriteWalker
{
if (fdv.isFuture())
{
- deprecation(funcdecl.loc, "`@__future` base class method `%s` is being overridden by `%s`; rename the latter", fdv.toPrettyChars(), funcdecl.toPrettyChars());
+ deprecation(funcdecl.loc, "method `%s` implicitly overrides `@__future` base class method; rename the former",
+ funcdecl.toPrettyChars());
+ deprecationSupplemental(fdv.loc, "base method `%s` defined here",
+ fdv.toPrettyChars());
// Treat 'this' as an introducing function, giving it a separate hierarchy in the vtbl[]
goto Lintro;
}
// max num of overloads to print (-v or -verror-supplements overrides this).
const uint DisplayLimit = global.params.v.errorSupplementCount();
const(char)* constraintsTip;
- // determine if the first candidate was printed
- int printed;
- bool matchSymbol(Dsymbol s, bool print, bool single_candidate = false)
+ int printed = 0; // number of candidates printed
+ int count = 0; // total candidates
+ bool child; // true if inside an eponymous template
+ const(char)* errorPrefix() @safe
+ {
+ if (child)
+ return " - Containing: ";
+
+ // align with blank spaces after first message
+ enum plural = "Candidates are: ";
+ enum spaces = " ";
+ if (printed)
+ return spaces;
+
+ return (count == 1) ? "Candidate is: " : plural;
+ }
+ bool matchSymbol(Dsymbol s, bool print)
{
if (auto fd = s.isFuncDeclaration())
{
return true;
auto tf = cast(TypeFunction) fd.type;
OutBuffer buf;
- buf.writestring(fd.toPrettyChars());
+ buf.writestring(child ? fd.toChars() : fd.toPrettyChars());
buf.writestring(parametersTypeToChars(tf.parameterList));
if (tf.mod)
{
buf.writeByte(' ');
buf.MODtoBuffer(tf.mod);
}
- .errorSupplemental(fd.loc,
- printed ? " `%s`" :
- single_candidate ? "Candidate is: `%s`" : "Candidates are: `%s`", buf.peekChars());
+ .errorSupplemental(fd.loc, "%s`%s`", errorPrefix(), buf.peekChars());
}
else if (auto td = s.isTemplateDeclaration())
{
if (!print)
return true;
+
+ // td.onemember may not have overloads set
+ // (see fail_compilation/onemember_overloads.d)
+ // assume if more than one member it is overloaded internally
+ bool recurse = td.onemember && td.members.length > 1;
OutBuffer buf;
HdrGenState hgs;
hgs.skipConstraints = true;
+ hgs.showOneMember = !recurse;
toCharsMaybeConstraints(td, buf, hgs);
const tmsg = buf.peekChars();
- const cmsg = td.getConstraintEvalError(constraintsTip);
-
- // add blank space if there are multiple candidates
- // the length of the blank space is `strlen("Candidates are: ")`
+ const cmsg = child ? null : td.getConstraintEvalError(constraintsTip);
if (cmsg)
- {
- .errorSupplemental(td.loc,
- printed ? " `%s`\n%s" :
- single_candidate ? "Candidate is: `%s`\n%s" : "Candidates are: `%s`\n%s",
- tmsg, cmsg);
- }
+ .errorSupplemental(td.loc, "%s`%s`\n%s", errorPrefix(), tmsg, cmsg);
else
+ .errorSupplemental(td.loc, "%s`%s`", errorPrefix(), tmsg);
+
+ if (recurse)
{
- .errorSupplemental(td.loc,
- printed ? " `%s`" :
- single_candidate ? "Candidate is: `%s`" : "Candidates are: `%s`",
- tmsg);
+ child = true;
+ foreach (d; *td.members)
+ {
+ if (d.ident != td.ident)
+ continue;
+
+ if (auto fd2 = d.isFuncDeclaration())
+ matchSymbol(fd2, print);
+ else if (auto td2 = d.isTemplateDeclaration())
+ matchSymbol(td2, print);
+ }
+ child = false;
}
}
return true;
}
// determine if there's > 1 candidate
- int count = 0;
overloadApply(declaration, (s) {
if (matchSymbol(s, false))
count++;
overloadApply(declaration, (s) {
if (global.params.v.verbose || printed < DisplayLimit)
{
- if (matchSymbol(s, true, count == 1))
+ if (matchSymbol(s, true))
printed++;
}
else
return fd;
}
+/****************************************************
+ * Determine if fd1 overrides fd2.
+ * Return !=0 if it does.
+ */
+int overrides(FuncDeclaration fd1, FuncDeclaration fd2)
+{
+ int result = 0;
+ if (fd1.ident == fd2.ident)
+ {
+ const cov = fd1.type.covariant(fd2.type);
+ if (cov != Covariant.distinct)
+ {
+ ClassDeclaration cd1 = fd1.toParent().isClassDeclaration();
+ ClassDeclaration cd2 = fd2.toParent().isClassDeclaration();
+ if (cd1 && cd2 && cd2.isBaseOf(cd1, null))
+ result = 1;
+ }
+ }
+ return result;
+}
+
+/*************************************
+ * Determine partial specialization order of functions `f` vs `g`.
+ * This is very similar to TemplateDeclaration::leastAsSpecialized().
+ * Params:
+ * f = first function
+ * g = second function
+ * names = names of parameters
+ * Returns:
+ * match 'this' is at least as specialized as g
+ * 0 g is more specialized than 'this'
+ */
+MATCH leastAsSpecialized(FuncDeclaration f, FuncDeclaration g, Identifiers* names)
+{
+ enum LOG_LEASTAS = 0;
+ static if (LOG_LEASTAS)
+ {
+ import core.stdc.stdio : printf;
+ printf("leastAsSpecialized(%s, %s, %s)\n", f.toChars(), g.toChars(), names ? names.toChars() : "null");
+ printf("%s, %s\n", f.type.toChars(), g.type.toChars());
+ }
+
+ /* This works by calling g() with f()'s parameters, and
+ * if that is possible, then f() is at least as specialized
+ * as g() is.
+ */
+
+ TypeFunction tf = f.type.toTypeFunction();
+ TypeFunction tg = g.type.toTypeFunction();
+
+ /* If both functions have a 'this' pointer, and the mods are not
+ * the same and g's is not const, then this is less specialized.
+ */
+ if (f.needThis() && g.needThis() && tf.mod != tg.mod)
+ {
+ if (f.isCtorDeclaration())
+ {
+ if (!MODimplicitConv(tg.mod, tf.mod))
+ return MATCH.nomatch;
+ }
+ else
+ {
+ if (!MODimplicitConv(tf.mod, tg.mod))
+ return MATCH.nomatch;
+ }
+ }
+
+ /* Create a dummy array of arguments out of the parameters to f()
+ */
+ Expressions args;
+ foreach (u, p; tf.parameterList)
+ {
+ Expression e;
+ if (p.isReference())
+ {
+ e = new IdentifierExp(Loc.initial, p.ident);
+ e.type = p.type;
+ }
+ else
+ e = p.type.defaultInitLiteral(Loc.initial);
+ args.push(e);
+ }
+
+ MATCH m = tg.callMatch(null, ArgumentList(&args, names), 1);
+ if (m > MATCH.nomatch)
+ {
+ /* A variadic parameter list is less specialized than a
+ * non-variadic one.
+ */
+ if (tf.parameterList.varargs && !tg.parameterList.varargs)
+ goto L1; // less specialized
+
+ static if (LOG_LEASTAS)
+ {
+ printf(" matches %d, so is least as specialized\n", m);
+ }
+ return m;
+ }
+L1:
+ static if (LOG_LEASTAS)
+ {
+ printf(" doesn't match, so is not as specialized\n");
+ }
+ return MATCH.nomatch;
+}
+
/********************************************
* Find function in overload list that matches to the 'this' modifier.
* There's four result types.
}
}
+/****************************************************
+ * Determine whether an 'out' contract is declared inside
+ * the given function or any of its overrides.
+ * Params:
+ * fd = the function to search
+ * Returns:
+ * true found an 'out' contract
+ */
+bool needsFensure(FuncDeclaration fd) @safe
+{
+ if (fd.fensures)
+ return true;
+
+ foreach (fdv; fd.foverrides)
+ {
+ if (needsFensure(fdv))
+ return true;
+ }
+ return false;
+}
+
/****************************************************
* Merge into this function the 'out' contracts of all it overrides.
* 'out's are AND'd together, i.e. all of them need to pass.
* https://issues.dlang.org/show_bug.cgi?id=3602 and
* https://issues.dlang.org/show_bug.cgi?id=5230
*/
- if (fd.needsFensure(fdv) && fdv.semanticRun != PASS.semantic3done)
+ if (needsFensure(fdv) && fdv.semanticRun != PASS.semantic3done)
{
assert(fdv._scope);
Scope* sc = fdv._scope.push();
return false;
}
}
+
+/+
+ + Checks the parameter and return types iff this is a `main` function.
+ +
+ + The following signatures are allowed for a `D main`:
+ + - Either no or a single parameter of type `string[]`
+ + - Return type is either `void`, `int` or `noreturn`
+ +
+ + The following signatures are standard C:
+ + - `int main()`
+ + - `int main(int, char**)`
+ +
+ + This function accepts the following non-standard extensions:
+ + - `char** envp` as a third parameter
+ + - `void` / `noreturn` as return type
+ +
+ + This function will issue errors for unexpected arguments / return types.
+ +/
+extern (D) void checkMain(FuncDeclaration fd)
+{
+ if (fd.ident != Id.main || fd.isMember() || fd.isNested())
+ return; // Not a main function
+
+ TypeFunction tf = fd.type.toTypeFunction();
+
+ Type retType = tf.nextOf();
+ if (!retType)
+ {
+ // auto main(), check after semantic
+ assert(fd.inferRetType);
+ return;
+ }
+
+ /// Checks whether `t` is equivalent to `char**`
+ /// Ignores qualifiers and treats enums according to their base type
+ static bool isCharPtrPtr(Type t)
+ {
+ auto tp = t.toBasetype().isTypePointer();
+ if (!tp)
+ return false;
+
+ tp = tp.next.toBasetype().isTypePointer();
+ if (!tp)
+ return false;
+
+ return tp.next.toBasetype().ty == Tchar;
+ }
+
+ // Neither of these qualifiers is allowed because they affect the ABI
+ enum invalidSTC = STC.out_ | STC.ref_ | STC.lazy_;
+
+ const nparams = tf.parameterList.length;
+ bool argerr;
+
+ const linkage = fd.resolvedLinkage();
+ if (linkage == LINK.d)
+ {
+ if (nparams == 1)
+ {
+ auto fparam0 = tf.parameterList[0];
+ auto t = fparam0.type.toBasetype();
+ if (t.ty != Tarray ||
+ t.nextOf().ty != Tarray ||
+ t.nextOf().nextOf().ty != Tchar ||
+ fparam0.storageClass & invalidSTC)
+ {
+ argerr = true;
+ }
+ }
+
+ if (tf.parameterList.varargs || nparams >= 2 || argerr)
+ .error(fd.loc, "%s `%s` parameter list must be empty or accept one parameter of type `string[]`", fd.kind, fd.toPrettyChars);
+ }
+
+ else if (linkage == LINK.c)
+ {
+ if (nparams == 2 || nparams == 3)
+ {
+ // Argument count must be int
+ auto argCount = tf.parameterList[0];
+ argerr |= !!(argCount.storageClass & invalidSTC);
+ argerr |= argCount.type.toBasetype().ty != Tint32;
+
+ // Argument pointer must be char**
+ auto argPtr = tf.parameterList[1];
+ argerr |= !!(argPtr.storageClass & invalidSTC);
+ argerr |= !isCharPtrPtr(argPtr.type);
+
+ // `char** environ` is a common extension, see J.5.1 of the C standard
+ if (nparams == 3)
+ {
+ auto envPtr = tf.parameterList[2];
+ argerr |= !!(envPtr.storageClass & invalidSTC);
+ argerr |= !isCharPtrPtr(envPtr.type);
+ }
+ }
+ else
+ argerr = nparams != 0;
+
+ // Disallow variadic main() - except for K&R declarations in C files.
+ // E.g. int main(), int main(argc, argv) int argc, char** argc { ... }
+ if (tf.parameterList.varargs && (!fd.isCsymbol() || (!tf.parameterList.hasIdentifierList && nparams)))
+ argerr |= true;
+
+ if (argerr)
+ {
+ .error(fd.loc, "%s `%s` parameters must match one of the following signatures", fd.kind, fd.toPrettyChars);
+ fd.loc.errorSupplemental("`main()`");
+ fd.loc.errorSupplemental("`main(int argc, char** argv)`");
+ fd.loc.errorSupplemental("`main(int argc, char** argv, char** environ)` [POSIX extension]");
+ }
+ }
+ else
+ return; // Neither C nor D main, ignore (should probably be an error)
+
+ // Allow enums with appropriate base types (same ABI)
+ retType = retType.toBasetype();
+
+ if (retType.ty != Tint32 && retType.ty != Tvoid && retType.ty != Tnoreturn)
+ .error(fd.loc, "%s `%s` must return `int`, `void` or `noreturn`, not `%s`", fd.kind, fd.toPrettyChars, tf.nextOf().toChars());
+}
+
+/***********************************************
+ * Check all return statements for a function to verify that returning
+ * using NRVO is possible.
+ *
+ * Returns:
+ * `false` if the result cannot be returned by hidden reference.
+ */
+extern (D) bool checkNRVO(FuncDeclaration fd)
+{
+ if (!fd.isNRVO() || fd.returns is null)
+ return false;
+
+ auto tf = fd.type.toTypeFunction();
+ if (tf.isref)
+ return false;
+
+ foreach (rs; *fd.returns)
+ {
+ if (auto ve = rs.exp.isVarExp())
+ {
+ auto v = ve.var.isVarDeclaration();
+ if (!v || v.isReference())
+ return false;
+ else if (fd.nrvo_var is null)
+ {
+ // Variables in the data segment (e.g. globals, TLS or not),
+ // parameters and closure variables cannot be NRVOed.
+ if (v.isDataseg() || v.isParameter() || v.toParent2() != fd)
+ return false;
+ if (v.nestedrefs.length && fd.needsClosure())
+ return false;
+ // don't know if the return storage is aligned
+ version (MARS)
+ {
+ if (fd.alignSectionVars && (*fd.alignSectionVars).contains(v))
+ return false;
+ }
+ // The variable type needs to be equivalent to the return type.
+ if (!v.type.equivalent(tf.next))
+ return false;
+ //printf("Setting nrvo to %s\n", v.toChars());
+ fd.nrvo_var = v;
+ }
+ else if (fd.nrvo_var != v)
+ return false;
+ }
+ else //if (!exp.isLvalue()) // keep NRVO-ability
+ return false;
+ }
+ return true;
+}
struct Symbol;
struct code;
struct block;
- struct Blockx;
+ struct BlockState;
struct elem;
struct TYPE;
alias type = TYPE;
}
else
{
- public import dmd.backend.cc : block, Blockx, Symbol;
+ public import dmd.backend.cc : block, BlockState, Symbol;
public import dmd.backend.type : type;
public import dmd.backend.el : elem;
- public import dmd.backend.code_x86 : code;
+ public import dmd.backend.x86.code_x86 : code;
public import dmd.objc_glue : ObjcGlue;
}
bool doFuncBodies; /// include function bodies in output
bool vcg_ast; /// write out codegen-ast
bool skipConstraints; // skip constraints when doing templates
+ bool showOneMember = true;
bool fullQual; /// fully qualify types when printing
int tpltMember;
}
buf.writeByte(')');
- if (td.onemember)
+ if (hgs.showOneMember && td.onemember)
{
if (const fd = td.onemember.isFuncDeclaration())
{
{ "ctfe", "__ctfe" },
{ "offset" },
{ "offsetof" },
+ { "bitoffsetof" },
+ { "bitwidth" },
{ "ModuleInfo" },
{ "ClassInfo" },
{ "classinfo" },
{ "isAbstractClass" },
{ "isArithmetic" },
{ "isAssociativeArray" },
+ { "isBitfield" },
{ "isFinalClass" },
{ "isTemplate" },
{ "isPOD" },
tsize_t = basic[isLP64 ? Tuns64 : Tuns32];
tptrdiff_t = basic[isLP64 ? Tint64 : Tint32];
thash_t = tsize_t;
+
+ static if (__VERSION__ == 2081)
+ {
+ // Related issue: https://issues.dlang.org/show_bug.cgi?id=19134
+ // D 2.081.x regressed initializing class objects at compile time.
+ // As a workaround initialize this global at run-time instead.
+ TypeTuple.empty = new TypeTuple();
+ }
}
/**
extern (C++) final class TypeTuple : Type
{
// 'logically immutable' cached global - don't modify!
- __gshared TypeTuple empty = new TypeTuple();
+ static if (__VERSION__ == 2081)
+ __gshared TypeTuple empty; // See comment in Type._init
+ else
+ __gshared TypeTuple empty = new TypeTuple();
Parameters* arguments; // types making up the tuple
fds.checkInContractOverrides();
// Remember whether we need to generate an 'out' contract.
- immutable bool needEnsure = FuncDeclaration.needsFensure(funcdecl);
+ immutable bool needEnsure = funcdecl.needsFensure();
if (funcdecl.fbody || funcdecl.frequires || needEnsure)
{
ls2.statement = ls;
sc = sc.push();
+ sc.lastVar = sc.enclosing.lastVar;
sc.scopesym = sc.enclosing.scopesym;
sc.ctorflow.orCSX(CSX.label);
sc.slabel = ls;
if (ls.statement)
ls.statement = ls.statement.statementSemantic(sc);
+
+ //issue 24534: lastVar may have been updated in the nested scope
+ sc.enclosing.lastVar = sc.lastVar;
+
sc.pop();
result = ls;
const(char)[] architectureName;
CPU cpu; // CPU instruction set to target
bool isX86_64; // generate 64 bit code for x86_64; true by default for 64 bit dmd
+ bool isX86; // generate 32 bit Intel x86 code
bool isLP64; // pointers are 64 bits
// Environmental
const(char)[] lib_ext; /// extension for static library files
const(char)[] dll_ext; /// extension for dynamic library files
bool run_noext; /// allow -run sources without extensions
- bool omfobj; // for Win32: write OMF object files instead of MsCoff
/**
* Values representing all properties for floating point types
*/
{
Unspecified,
Bionic,
- DigitalMars,
Glibc,
Microsoft,
Musl,
enum BitFieldStyle : ubyte
{
Unspecified,
- DM, /// Digital Mars 32 bit C compiler
MS, /// Microsoft 32 and 64 bit C compilers
/// https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160
/// https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160
{
Unspecified,
Clang,
- DigitalMars,
Gcc,
Microsoft,
Sun
{
Unspecified,
Bionic,
- DigitalMars,
Glibc,
Microsoft,
Musl,
enum class BitFieldStyle : unsigned char
{
Unspecified,
- DM, // Digital Mars 32 bit C compiler
MS, // Microsoft 32 and 64 bit C compilers
// https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160
// https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160
{
Unspecified,
Clang,
- DigitalMars,
Gcc,
Microsoft,
Sun
DString architectureName; // name of the platform architecture (e.g. X86_64)
CPU cpu; // CPU instruction set to target
d_bool isX86_64; // generate 64 bit code for x86_64; true by default for 64 bit dmd
+ d_bool isX86; // generate 32 bit Intel x86 code
d_bool isLP64; // pointers are 64 bits
// Environmental
DString lib_ext; /// extension for static library files
DString dll_ext; /// extension for dynamic library files
d_bool run_noext; /// allow -run sources without extensions
- d_bool omfobj; /// for Win32: write OMF object files instead of COFF
template <typename T>
struct FPTypeProperties
import dmd.typesem;
import dmd.visitor;
+alias funcLeastAsSpecialized = dmd.funcsem.leastAsSpecialized;
+
/************************************
* Perform semantic analysis on template.
* Params:
* This is because f() is "more specialized."
*/
{
- MATCH c1 = FuncDeclaration.leastAsSpecialized(fd, m.lastf, argumentList.names);
- MATCH c2 = FuncDeclaration.leastAsSpecialized(m.lastf, fd, argumentList.names);
+ MATCH c1 = funcLeastAsSpecialized(fd, m.lastf, argumentList.names);
+ MATCH c2 = funcLeastAsSpecialized(m.lastf, fd, argumentList.names);
//printf("c1 = %d, c2 = %d\n", c1, c2);
if (c1 > c2) return firstIsBetter();
if (c1 < c2) return 0;
}
{
// Disambiguate by picking the most specialized FunctionDeclaration
- MATCH c1 = FuncDeclaration.leastAsSpecialized(fd, m.lastf, argumentList.names);
- MATCH c2 = FuncDeclaration.leastAsSpecialized(m.lastf, fd, argumentList.names);
+ MATCH c1 = funcLeastAsSpecialized(fd, m.lastf, argumentList.names);
+ MATCH c2 = funcLeastAsSpecialized(m.lastf, fd, argumentList.names);
//printf("3: c1 = %d, c2 = %d\n", c1, c2);
if (c1 > c2) goto Ltd;
if (c1 < c2) goto Ltd_best;
sm => sm.isTemplateDeclaration() !is null) != 0;
});
}
+ if (e.ident == Id.isBitfield)
+ {
+ if (dim != 1)
+ return dimError(1);
+
+ return isDsymX((s)
+ {
+ s = s.toAlias();
+ return s.isBitFieldDeclaration() !is null;
+ });
+ }
if (e.ident == Id.isPOD)
{
if (dim != 1)
}
}
+/**************************************
+ * Returns an indirect type one step from t.
+ */
+Type getIndirection(Type t)
+{
+ t = t.baseElemOf();
+ if (t.ty == Tarray || t.ty == Tpointer)
+ return t.nextOf().toBasetype();
+ if (t.ty == Taarray || t.ty == Tclass)
+ return t;
+ if (t.ty == Tstruct)
+ return t.hasPointers() ? t : null; // TODO
+
+ // should consider TypeDelegate?
+ return null;
+}
+
/******************************************
* Perform semantic analysis on a type.
* Params:
}
if (v)
{
- if (ident == Id.offsetof)
+ if (ident == Id.offsetof ||
+ ident == Id.bitoffsetof ||
+ ident == Id.bitwidth)
{
v.dsymbolSemantic(null);
if (v.isField())
ad.size(e.loc);
if (ad.sizeok != Sizeok.done)
return ErrorExp.get();
- return new IntegerExp(e.loc, v.offset, Type.tsize_t);
+ uint value;
+ if (ident == Id.offsetof)
+ value = v.offset;
+ else // Id.bitoffsetof || Id.bitwidth
+ {
+ auto bf = v.isBitFieldDeclaration();
+ if (bf)
+ {
+ value = ident == Id.bitoffsetof ? bf.bitOffset : bf.fieldWidth;
+ }
+ else
+ error(v.loc, "`%s` is not a bitfield, cannot apply `%s`", v.toChars(), ident.toChars());
+ }
+ return new IntegerExp(e.loc, value, Type.tsize_t);
}
}
else if (ident == Id._init)
ident != Id._mangleof &&
ident != Id.stringof &&
ident != Id.offsetof &&
+ ident != Id.bitoffsetof &&
+ ident != Id.bitwidth &&
// https://issues.dlang.org/show_bug.cgi?id=15045
// Don't forward special built-in member functions.
ident != Id.ctor &&
t = new TypeSArray(t, (cast(TypeSArray)type).dim.syntaxCopy());
else if (type.ty == Taarray)
{
- t = new TypeAArray(t, (cast(TypeAArray)type).index.syntaxCopy());
+ t = new TypeAArray(t, (cast(TypeAArray)type).index.substWildTo(mod));
}
else if (type.ty == Tdelegate)
{
--- /dev/null
+module b20243;
+
+inout(int) f(inout(int)[inout(string)] x);
+const(int)[const(string)] x;
+static assert(is(typeof(f(x)) == const(int)));
+
+inout(int)[inout(string)] g(inout(int) y);
+const(int) y;
+static assert(is(typeof(g(y)) == const(int)[const(string)]));
import core.stdc.stdio;
version (CppRuntime_Clang) version = CppMangle_Itanium;
-version (CppRuntime_DigitalMars) version = CppMangle_MSVC;
version (CppRuntime_Gcc) version = CppMangle_Itanium;
version (CppRuntime_Microsoft) version = CppMangle_MSVC;
version (CppRuntime_Sun) version = CppMangle_Itanium;
module cppmangle3;
version (CppRuntime_Clang) version = CppMangle_Itanium;
-version (CppRuntime_DigitalMars) version = CppMangle_MSVC;
version (CppRuntime_Gcc) version = CppMangle_Itanium;
version (CppRuntime_Microsoft) version = CppMangle_MSVC;
version (CppRuntime_Sun) version = CppMangle_Itanium;
--- /dev/null
+// REQUIRED_ARGS: -identifiers=c99
+
+// verify that the C99 identifier set is applied.
+
+int ªideµnt;
--- /dev/null
+/*
+REQUIRED_ARGS: -verrors=3
+TEST_OUTPUT:
+---
+compilable/deprecationlimit.d(18): Deprecation: function `deprecationlimit.f` is deprecated
+compilable/deprecationlimit.d(19): Deprecation: function `deprecationlimit.f` is deprecated
+compilable/deprecationlimit.d(20): Deprecation: function `deprecationlimit.f` is deprecated
+1 deprecation warning omitted, use `-verrors=0` to show all
+---
+*/
+
+deprecated void f()
+{
+}
+
+void main()
+{
+ f();
+ f();
+ f();
+ f();
+}
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
struct Foo final
{
int32_t a;
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
class C;
extern void importFunc();
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
template <typename T, typename U>
struct TS final
{
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
struct S final
{
union
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
namespace nameSpace
{
extern void fn();
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
class ForwardClass;
class BaseClass
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
struct Outer final
{
int32_t a;
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
union U1
{
int32_t a;
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
enum : int32_t { Anon = 10 };
enum : bool { Anon2 = true };
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
static int32_t const Anon = 10;
static bool const Anon2 = true;
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
extern int32_t foo();
extern int32_t* somePtr;
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
struct Child;
class Struct;
enum class Enum;
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
struct S final
{
int32_t i;
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
extern void register(int32_t* ptr);
namespace const_cast
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
extern "C" int32_t freeC();
// Ignored function dtoh_mangling.bar because C++ doesn't support explicit mangling
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
struct Outer final
{
static Outer* outerPtr;
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
struct S1 final
{
int32_t a;
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
class ExternDClass;
struct ExternDStruct2;
struct ExternDStruct3;
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
enum class __c_not_special;
extern "C" void fn_long(long __param_0_);
#include <stddef.h>
#include <stdint.h>
-#ifdef CUSTOM_D_ARRAY_TYPE
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE
-#else
-/// Represents a D [] array
-template<typename T>
-struct _d_dynamicArray final
-{
- size_t length;
- T *ptr;
-
- _d_dynamicArray() : length(0), ptr(NULL) { }
-
- _d_dynamicArray(size_t length_in, T *ptr_in)
- : length(length_in), ptr(ptr_in) { }
-
- T& operator[](const size_t idx) {
- assert(idx < length);
- return ptr[idx];
- }
-
- const T& operator[](const size_t idx) const {
- assert(idx < length);
- return ptr[idx];
- }
-};
-#endif
-
---
*/
#include <stddef.h>\r
#include <stdint.h>\r
\r
-#ifdef CUSTOM_D_ARRAY_TYPE\r
-#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE\r
-#else\r
-/// Represents a D [] array\r
-template<typename T>\r
-struct _d_dynamicArray final\r
-{\r
- size_t length;\r
- T *ptr;\r
-\r
- _d_dynamicArray() : length(0), ptr(NULL) { }\r
-\r
- _d_dynamicArray(size_t length_in, T *ptr_in)\r
- : length(length_in), ptr(ptr_in) { }\r
-\r
- T& operator[](const size_t idx) {\r
- assert(idx < length);\r
- return ptr[idx];\r
- }\r
-\r
- const T& operator[](const size_t idx) const {\r
- assert(idx < length);\r
- return ptr[idx];\r
- }\r
-};\r
-#endif\r
-\r
extern void importFunc();\r
\r
// Ignored function dtoh_verbose.foo because of linkage\r
--- /dev/null
+/++
+REQUIRED_ARGS: -HC -o-
+TEST_OUTPUT:
+---
+// Automatically generated by Digital Mars D Compiler
+
+#pragma once
+
+#include <assert.h>
+#include <math.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#ifndef _WIN32
+#define EXTERN_SYSTEM_AFTER __stdcall
+#define EXTERN_SYSTEM_BEFORE
+#else
+#define EXTERN_SYSTEM_AFTER
+#define EXTERN_SYSTEM_BEFORE extern "C"
+#endif
+
+EXTERN_SYSTEM_BEFORE int32_t EXTERN_SYSTEM_AFTER exSystem(int32_t x);
+
+int32_t __stdcall exWindows(int32_t y);
+---
+++/
+
+extern(System) int exSystem(int x)
+{
+ return x;
+}
+
+extern(Windows) int exWindows(int y)
+{
+ return y;
+}
+++ /dev/null
-/* PERMUTE_ARGS:
- * TEST_OUTPUT:
----
-compilable/future.d(15): Deprecation: `@__future` base class method `future.A.msg` is being overridden by `future.B.msg`; rename the latter
----
- */
-
-class A
-{
- @__future char msg() { return 'a'; }
-}
-
-class B : A
-{
- char msg() { return 'b'; }
-}
-
-class C : B
-{
- override char msg() { return 'c'; }
-}
-
-class D : A
-{
- override char msg() { return 'd'; }
-}
-
-int main()
-{
- auto a = new A();
- assert(a.msg() == 'a');
- auto b = new B();
- assert(b.msg() == 'b');
- auto c = new C();
- assert(c.msg() == 'c');
- auto d = new D();
- assert(d.msg() == 'd');
-
- assert(b.A.msg() == 'a');
-
- auto ba = cast(A)b;
- assert(ba.msg() == 'a');
-
- auto da = cast(A)d;
- assert(da.msg() == 'd');
- return 0;
-}
--- /dev/null
+// REQUIRED_ARGS: -identifiers=UAX31
+
+// verify that the UAX31 identifier set is applied.
+
+int øideùnt;
--- /dev/null
+// REQUIRED_ARGS: -identifiers=all
+
+// verify that the UAX31 identifier set is applied.
+
+int øideùnt;
+int ªideµnt;
+int ¨ide¯nt;
+
+// just to play it safe, do we support one unicode then another at start?
+int øùident;
--- /dev/null
+// REQUIRED_ARGS: -identifiers=c11
+
+// verify that the C11 identifier set is applied.
+
+int ¨ide¯nt;
S* s = cast(S*)malloc();
free(s.p); // consumes s
}
+
+/*******************************
+ * https://issues.dlang.org/show_bug.cgi?id=21854
+ */
+
+@live void test21854()
+{
+ foreach(int tmp; 0..10) { }
+
+ int key = 0;
+ int limit = 10;
+ for (; key < limit; key += 1)
+ {
+ int tmp = key;
+ }
+}
--- /dev/null
+// Stack pointers are being escaped here, but without
+// @safe and dip1000, it should still be allowed
+// because return scope could have been inferred incorrectly,
+// and it breaks existing code:
+// https://issues.dlang.org/show_bug.cgi?id=23657
+
+int* identity(return scope int* x);
+
+auto identityAuto(int* x) => x;
+
+int* f()
+{
+ int x;
+ return identity(&x);
+ return identityAuto(&x);
+}
// PERMUTE_ARGS:
-// REQUIRED_ARGS: -unittest
+// REQUIRED_ARGS: -unittest -verrors=0
/*
TEST_OUTPUT:
// REQUIRED_ARGS: -g
-// If this is failing, you need optlink 8.00.14 or higher
-
string gen()
{
string m;
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=24479
+
+/*
+TEST_OUTPUT:
+---
+1
+2
+---
+*/
+
+struct S
+{
+ @1
+ S opBinary(string op: "-")(S rhs) const pure nothrow @nogc
+ {
+ return rhs;
+ }
+ @2
+ S opBinary(string op: "*")(S dur) const pure nothrow @nogc
+ {
+ return dur;
+ }
+}
+
+private enum hasExternalUDA(alias A) = is(A == External) || is(typeof(A) == External);
+
+void foo()
+{
+ static foreach (t; __traits(getOverloads, S, "opBinary", true))
+ static foreach(attr; __traits(getAttributes, t))
+ pragma(msg, attr);
+
+ static assert(__traits(getOverloads, S, "opBinary", true).length == 2);
+ alias A = __traits(getAttributes, __traits(getOverloads, S, "opBinary", true)[1]);
+}
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=24560
+
+class C { }
+struct S
+{
+ static void fun(C heur = new C) { }
+}
+
+void main()
+{
+ S.fun();
+}
--- /dev/null
+/*
+TEST_OUTPUT:
+---
+Hello
+World
+from
+CTFE
+Hello[1 .. 3] = el
+S.str
+abcdefghij[2 .. 6] = cdef
+---
+*/
+
+struct S
+{
+ string str = "S.str";
+ alias str this;
+}
+
+int greeting(scope const char[][] values) pure nothrow @safe @nogc
+{
+ const string newline = "\n";
+
+ foreach (const val; values)
+ {
+ __ctfeWrite(val);
+ __ctfeWrite(newline);
+ }
+
+ // Test slices
+ const val = values[0];
+ __ctfeWrite(val[]);
+ __ctfeWrite(['[','1',' ','.','.',' ','3',']',' ','=',' ']);
+ __ctfeWrite(val[1 .. 3]);
+ __ctfeWrite(newline);
+
+ S s;
+ __ctfeWrite(s);
+ __ctfeWrite(newline);
+
+ // Test mutable slices
+ char[10] buffer;
+ fill(buffer); // Avoid potential shortcuts for literals
+ __ctfeWrite(buffer[0 .. $]);
+ __ctfeWrite("[2 .. 6] = ");
+ __ctfeWrite(buffer[2 .. 6]);
+ __ctfeWrite(newline);
+
+ return 0;
+}
+
+void fill(ref char[10] buffer) pure nothrow @safe @nogc
+{
+ foreach (const idx, ref ch; buffer)
+ ch = cast(char)('a' + idx);
+}
+
+enum forceCTFE = greeting(["Hello", "World", "from", "CTFE"]);
else
static assert(S.sizeof == 0);
-version (CRuntime_DigitalMars)
- static assert(S.alignof == 0);
-else
- static assert(S.alignof == 1);
+static assert(S.alignof == 1);
extern (C++) struct T { }
--- /dev/null
+/*
+TEST_OUTPUT:
+---
+fail_compilation/alias_instance_member.d(18): Error: cannot alias member of variable `that`
+fail_compilation/alias_instance_member.d(18): Use `typeof(that)` instead to preserve behaviour
+---
+*/
+
+@__edition_latest_do_not_use
+module aim;
+
+struct Foo
+{
+ int v;
+ void test(Foo that) const
+ {
+ alias a = this.v; // OK
+ alias b = that.v;
+ assert(&a is &b);
+ }
+}
+
+void main()
+{
+ Foo a = Foo(1);
+ Foo b = Foo(2);
+ a.test(b);
+}
--- /dev/null
+/*
+TEST_OUTPUT:
+---
+fail_compilation/alias_instance_member2.d(20): Error: cannot alias member of variable `f`
+fail_compilation/alias_instance_member2.d(20): Use `typeof(f)` instead to preserve behaviour
+---
+*/
+
+@__edition_latest_do_not_use
+module aim;
+
+struct Foo
+{
+ int v;
+}
+
+struct Bar
+{
+ Foo f;
+ alias v = f.v;
+}
--- /dev/null
+/* REQUIRED_ARGS: -preview=bitfields
+ */
+
+struct S
+{
+ int a;
+ int b:5, c:6;
+}
+
+static if (0)
+{
+ pragma(msg, __traits(isBitfield, S.a));
+ pragma(msg, __traits(isBitfield, S.b));
+ pragma(msg, S.b.bitoffsetof);
+ pragma(msg, S.b.bitwidth);
+ pragma(msg, S.c.bitoffsetof);
+ pragma(msg, S.c.bitwidth);
+ pragma(msg, S.a.bitoffsetof);
+ pragma(msg, S.a.bitwidth);
+}
+
+static assert(__traits(isBitfield, S.a) == false);
+static assert(__traits(isBitfield, S.b) == true);
+static assert(S.b.bitoffsetof == 0);
+static assert(S.b.bitwidth == 5);
+static assert(S.c.bitoffsetof == 5);
+static assert(S.c.bitwidth == 6);
+
+/* TEST_OUTPUT:
+---
+fail_compilation/bitintro.d(6): Error: `a` is not a bitfield, cannot apply `bitoffsetof`
+fail_compilation/bitintro.d(37): while evaluating: `static assert(a.bitoffsetof)`
+fail_compilation/bitintro.d(6): Error: `a` is not a bitfield, cannot apply `bitwidth`
+fail_compilation/bitintro.d(38): while evaluating: `static assert(a.bitwidth)`
+---
+*/
+static assert(S.a.bitoffsetof);
+static assert(S.a.bitwidth);
--- /dev/null
+/*
+REQUIRED_ARGS: -preview=dip1000 -de
+TEST_OUTPUT:
+---
+fail_compilation/cast_qual.d(15): Deprecation: cast from `const(int)` to `int` cannot be used as an lvalue in @safe code
+fail_compilation/cast_qual.d(17): Deprecation: cast from `const(int)` to `int` cannot be used as an lvalue in @safe code
+---
+*/
+
+@safe:
+
+void main() {
+ const int i = 3;
+ int j = cast() i; // OK
+ int* p = &cast() i; // this should not compile in @safe code
+ *p = 4; // oops
+ cast() i = 5; // NG
+ auto q = &cast(const) j; // OK, int* to const int*
+}
-// REQUIRED_ARGS: -de
-
/*
TEST_OUTPUT:
---
-fail_compilation/deprecate1553.d(18): Deprecation: cannot use `foreach_reverse` with a delegate
+fail_compilation/deprecate1553.d(16): Error: cannot use `foreach_reverse` with a delegate
---
*/
--- /dev/null
+/**
+Test language editions (currently experimental)
+
+TEST_OUTPUT:
+---
+fail_compilation/editions.d(15): Error: scope parameter `x` may not be returned
+---
+*/
+@__edition_latest_do_not_use
+module editions;
+
+@safe:
+int* f(scope int* x)
+{
+ return x;
+}
--- /dev/null
+/*
+TEST_OUTPUT:
+---
+fail_compilation/empty_statement.d(11): Error: use `{ }` for an empty statement, not `;`
+fail_compilation/empty_statement.d(12): Error: use `{ }` for an empty statement, not `;`
+fail_compilation/empty_statement.d(13): Error: use `{ }` for an empty statement, not `;`
+---
+*/
+void main()
+{
+ for (;;);
+ if (0);
+ while (0);
+}
/*
TEST_OUTPUT:
---
-fail_compilation/fail125.d(15): Error: array index `[2]` is outside array bounds `[0 .. 2]`
+fail_compilation/fail125.d(15): Error: sequence index `[2]` is outside bounds `[0 .. 2]`
fail_compilation/fail125.d(18): Error: template instance `fail125.main.recMove!(1, a, b)` error instantiating
fail_compilation/fail125.d(25): instantiated from here: `recMove!(0, a, b)`
---
/* TEST_OUTPUT:
---
-fail_compilation/fail17612.d(14): Error: undefined identifier `string`
-fail_compilation/fail17612.d(17): Error: class `object.TypeInfo` missing or corrupt object.d
+fail_compilation/fail17612.d(16): Error: undefined identifier `string`
+fail_compilation/fail17612.d(19): Error: `TypeInfo` not found. object.d may be incorrectly installed or corrupt.
+fail_compilation/fail17612.d(19): dmd might not be correctly installed. Run 'dmd -man' for installation instructions.
+fail_compilation/fail17612.d(19): config file: not found
---
*/
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=24485
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail24485.d(25): Error: cannot implicitly convert expression `*a` of type `A` to `B`
+fail_compilation/fail24485.d(31): Error: cannot implicitly convert expression `this.a` of type `A` to `B`
+
+---
+*/
+
+struct A
+{
+ int i = 43;
+ this(ref A rhs) {}
+}
+
+struct B
+{
+ int i = 42;
+}
+
+ref B foo()
+{
+ auto a = new A;
+ return *a;
+}
+
+struct C
+{
+ A a;
+ @property ref B b() { return a; }
+}
--- /dev/null
+/*
+REQUIRED_ARGS: -de -m64
+TEST_OUTPUT:
+---
+fail_compilation/foreach_index_overflow.d(19): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
+fail_compilation/foreach_index_overflow.d(21): Deprecation: foreach: loop index implicitly converted from `size_t` to `ushort`
+fail_compilation/foreach_index_overflow.d(24): Deprecation: foreach: loop index implicitly converted from `size_t` to `ubyte`
+fail_compilation/foreach_index_overflow.d(26): Deprecation: foreach: loop index implicitly converted from `size_t` to `byte`
+---
+*/
+
+void main()
+{
+ enum { red, green, blue }
+ foreach (int i, color; [red, green, blue]) {} // OK
+
+ int[] arr;
+ foreach (int index, element; arr[0 .. 0x8000_0000]) {} // OK
+ foreach (int index, element; arr[0 .. 0x8000_0001]) {} // error
+ foreach (ushort index, element; arr[0 .. 0x1_0000]) {} // OK
+ foreach (ushort index, element; arr[0 .. 0x1_0001]) {} // error
+
+ int[257] data;
+ foreach (ubyte i, x; data[]) {} // error
+ foreach (ubyte i, x; data[0..256]) {} // OK
+ foreach (byte i, x; data[0..0x81]) {} // error
+ foreach (byte i, x; data[0..0x80]) {} // OK
+}
/*
TEST_OUTPUT:
---
-fail_compilation/ice12539.d(15): Error: array index `[0]` is outside array bounds `[0 .. 0]`
+fail_compilation/ice12539.d(15): Error: sequence index `[0]` is outside bounds `[0 .. 0]`
---
*/
--- /dev/null
+/*
+TEST_OUTPUT:
+---
+fail_compilation/issue24534.d(12): Error: `goto` skips declaration of variable `issue24534.f1.y1`
+fail_compilation/issue24534.d(13): declared here
+fail_compilation/issue24534.d(20): Error: `goto` skips declaration of variable `issue24534.f2.y2`
+fail_compilation/issue24534.d(22): declared here
+---
+*/
+void f1(){ //always failed with error about skipping a declaration
+ int x1;
+ goto Label1;
+ int y1;
+ Label1:
+ int z1;
+}
+
+void f2(){ //compiled fine before this bug was fixed
+ int x2;
+ goto Label2;
+ Dummy2:
+ int y2;
+ Label2:
+ int z2;
+}
/*
TEST_OUTPUT:
---
-fail_compilation/lexer23465.d(19): Error: char 0x1f37a not allowed in identifier
+fail_compilation/lexer23465.d(19): Error: character 0x1f37a is not allowed as a continue character in an identifier
fail_compilation/lexer23465.d(19): Error: character 0x1f37a is not a valid token
fail_compilation/lexer23465.d(20): Error: character '\' is not a valid token
fail_compilation/lexer23465.d(21): Error: unterminated /+ +/ comment
--- /dev/null
+/* REQUIRED_ARGS: -preview=dip1021
+TEST_OUTPUT:
+---
+fail_compilation/ob1.d(23): Error: variable `ob1.mars.t` has undefined state and cannot be read
+---
+ https://issues.dlang.org/show_bug.cgi?id=21923
+*/
+
+@live:
+
+struct Handle
+{
+ private void* _handle;
+
+ this(int n);
+ ~this();
+ scope void bar();
+ static void fido(ref Handle);
+}
+
+void mars()
+{
+ auto t = Handle(10);
+ t.bar();
+ Handle.fido(t); // moves t to fido(), then destructor runs, causing error
+
+ scope u = Handle(10);
+}
--- /dev/null
+/*
+TEST_OUTPUT:
+---
+fail_compilation/obsolete_body.d(11): Error: usage of identifer `body` as a keyword is obsolete. Use `do` instead.
+---
+*/
+@__edition_latest_do_not_use
+module m;
+
+void test()
+in { } body { }
--- /dev/null
+/*
+TEST_OUTPUT:
+---
+fail_compilation/onemember_overloads.d(29): Error: none of the overloads of `skipOver` are callable using argument types `()`
+fail_compilation/onemember_overloads.d(25): Candidates are: `onemember_overloads.skipOver(string)`
+fail_compilation/onemember_overloads.d(18): `skipOver(alias pred = (a, b) => a == b)`
+fail_compilation/onemember_overloads.d(20): - Containing: `skipOver(Haystack, Needles...)(ref Haystack haystack, Needles needles)`
+fail_compilation/onemember_overloads.d(21): - Containing: `skipOver(R)(ref R r1)`
+fail_compilation/onemember_overloads.d(22): - Containing: `skipOver(R, Es...)(ref R r, Es es)`
+fail_compilation/onemember_overloads.d(30): Error: template `t2` is not callable using argument types `!()()`
+fail_compilation/onemember_overloads.d(33): Candidate is: `t2(T)`
+fail_compilation/onemember_overloads.d(35): - Containing: `t2(string)`
+fail_compilation/onemember_overloads.d(36): - Containing: `t2(int[])`
+fail_compilation/onemember_overloads.d(37): - Containing: `t2(R)(R)`
+---
+*/
+
+template skipOver(alias pred = (a, b) => a == b)
+{
+ bool skipOver(Haystack, Needles...)(ref Haystack haystack, Needles needles) => true;
+ bool skipOver(R)(ref R r1) => true;
+ bool skipOver(R, Es...)(ref R r, Es es) => true;
+}
+
+void skipOver(string);
+
+void main()
+{
+ skipOver();
+ t2();
+}
+
+template t2(T)
+{
+ bool t2(string);
+ bool t2(int[]);
+ bool t2(R)(R);
+}
--- /dev/null
+/*
+REQUIRED_ARGS: -de
+TEST_OUTPUT:
+---
+fail_compilation/systemvariables_bool_union.d(21): Deprecation: cannot access overlapped field `Box.b` with unsafe bit patterns in `@safe` code
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=24477
+
+bool schrodingersCat() @safe
+{
+ union Box
+ {
+ bool b;
+ ubyte y;
+ }
+
+ Box u;
+ u.y = 2;
+ return u.b;
+}
REQUIRED_ARGS: -preview=systemVariables
TEST_OUTPUT:
---
-fail_compilation/systemvariables_void_init.d(29): Error: `void` initializers for `@system` variables not allowed in safe functions
-fail_compilation/systemvariables_void_init.d(30): Error: `void` initializers for `@system` variables not allowed in safe functions
-fail_compilation/systemvariables_void_init.d(31): Error: `void` initializers for `@system` variables not allowed in safe functions
+fail_compilation/systemvariables_void_init.d(48): Error: `void` initializers for types with unsafe bit patterns are not allowed in safe functions
+fail_compilation/systemvariables_void_init.d(49): Error: `void` initializers for types with unsafe bit patterns are not allowed in safe functions
+fail_compilation/systemvariables_void_init.d(50): Error: `void` initializers for types with unsafe bit patterns are not allowed in safe functions
+fail_compilation/systemvariables_void_init.d(51): Error: a `bool` must be 0 or 1, so void intializing it is not allowed in safe functions
+fail_compilation/systemvariables_void_init.d(52): Error: a `bool` must be 0 or 1, so void intializing it is not allowed in safe functions
+fail_compilation/systemvariables_void_init.d(53): Error: `void` initializers for types with unsafe bit patterns are not allowed in safe functions
+fail_compilation/systemvariables_void_init.d(54): Error: `void` initializers for types with unsafe bit patterns are not allowed in safe functions
---
*/
x = C.init,
}
+enum B : bool
+{
+ x,
+}
+
+struct SB
+{
+ bool x;
+}
+
+struct SSB
+{
+ SB sb;
+}
+
void main() @safe
{
S s = void;
C c = void;
E e = void;
+ const bool b = void;
+ B bb = void;
+ SB sb = void;
+ SSB ssb = void;
+}
+
+// The following test is reduced from Phobos. The compiler generates this `opAssign`:
+// (CopyPreventer __swap2 = void;) , __swap2 = this , (this = p , __swap2.~this());
+// The compiler would give an error about void initialization a struct with a bool,
+// but it can be trusted in this case because it's a compiler generated temporary.
+auto staticArray(T)(T a) @safe
+{
+ T c;
+ c = a;
+}
+
+void assignmentTest() @safe
+{
+ static struct CopyPreventer
+ {
+ bool on;
+ this(this) @safe {}
+ ~this() { }
+ }
+
+ staticArray(CopyPreventer());
}
--- /dev/null
+/*
+REQUIRED_ARGS: -preview=dip1000
+TEST_OUTPUT:
+---
+fail_compilation/test22977.d(16): Error: escaping local variable through nested function `scfunc`
+fail_compilation/test22977.d(22): Error: escaping reference to stack allocated value returned by `scfunc2()`
+---
+*/
+
+// Issue 22977 - [dip1000] can escape scope pointer returned by nested function
+// https://issues.dlang.org/show_bug.cgi?id=22977
+
+auto p0(scope string s) @safe
+{
+ string scfunc() { return s; }
+ return scfunc();
+}
+
+auto p1(scope string s) @safe
+{
+ ref string scfunc2() { return s; }
+ return scfunc2();
+}
+
+// Reduced from Mir
+struct Tuple(T...)
+{
+ T expand;
+}
+
+auto autoExpandAndForward(alias value)()
+{
+ return value.expand[0];
+}
+
+struct MapIterator
+{
+ int* p;
+ int* foo() scope
+ {
+ auto t = Tuple!(int*)(p);
+ return autoExpandAndForward!t;
+ }
+}
+
+// Reduced from Phobos
+float partial(alias fun)()
+{
+ return fun();
+}
+
+auto partialFunction() @safe
+{
+ int function() f = () => 0;
+ return &partial!(f);
+}
T!().auf() = 2; assert(T!().x == 2);
}
+// https://issues.dlang.org/show_bug.cgi?id=24525
+void test24525()
+{
+ int a;
+ auto ref () {return a;}() = 1;
+ assert(a == 1);
+
+ ref () {return a;}() = 2;
+ assert(a == 2);
+}
+
/***************************************************/
int main()
test14745();
test15794();
test16271();
+ test24525();
printf("Success\n");
return 0;
/* PERMUTE_ARGS:
TEST_OUTPUT:
---
-runnable/future.d(15): Deprecation: `@__future` base class method `future.A.msg` is being overridden by `future.B.msg`; rename the latter
+runnable/future.d(16): Deprecation: method `future.B.msg` implicitly overrides `@__future` base class method; rename the former
+runnable/future.d(11): base method `future.A.msg` defined here
---
*/
printf(" %s", arg);
printf("\n");
}
+
+// https://issues.dlang.org/show_bug.cgi?id=24519
+void func13(string file = __FILE__[])
+{
+ printf("%s: %s\n", __FUNCTION__.ptr, file.ptr);
+}
imports.issue18919b.func10: expr1=imports.issue18919b, expr2=imports.issue18919b
imports.issue18919b.func11: issue18919b.d:233 imports.issue18919b
imports.issue18919b.func12: issue18919.d issue18919.main void issue18919.main() issue18919
+imports.issue18919b.func13: runnable/issue18919.d
---
*/
import imports.issue18919b;
+#line 26
+
void main()
{
func1();
func10();
func11();
func12();
+ func13();
}
/************************************/
// https://issues.dlang.org/show_bug.cgi?id=19968
-@safe void test19968()
+void test19968()
{
int[2] array = [16, 678];
union U { int i; bool b; }
// COMDAT folding increases runtime by > 80x
// REQUIRED_ARGS(windows): -L/OPT:NOICF
-// Apparently omf or optlink does not support more than 32767 symbols.
-// DISABLED: win32
-
// Generate \sum_{i=0}^{14} 2^i = 32767 template instantiations
// (each with 3 sections) to use more than 64Ki sections in total.
+++ /dev/null
-// https://issues.dlang.org/show_bug.cgi?id=24029
-
-int x = 0;
-int y = 0;
-
-void a()
-{
- (__extension__ ({ x += 2; })); // test.a.__dgliteral1
-}
-
-void b()
-{
- (__extension__ ({ y += 1; })); // test.b.__dgliteral1
-}
-
-int main(void)
-{
- a();
- b();
- __check(x == 2);
- __check(y == 1);
- return 0;
-}
--- /dev/null
+import core.memory;
+
+void main()
+{
+ {
+ int[][] a = new int[][](2, 2);
+ assert(!(GC.getAttr(a.ptr) & GC.BlkAttr.NO_SCAN));
+ assert(GC.getAttr(a[0].ptr) & GC.BlkAttr.NO_SCAN);
+ }
+ {
+ void*[][] a = new void*[][](2, 2);
+ assert(!(GC.getAttr(a.ptr) & GC.BlkAttr.NO_SCAN));
+ assert(!(GC.getAttr(a[0].ptr) & GC.BlkAttr.NO_SCAN));
+ }
+ {
+ int[][][] a = new int[][][](2, 2);
+ assert(!(GC.getAttr(a.ptr) & GC.BlkAttr.NO_SCAN));
+ assert(!(GC.getAttr(a[0].ptr) & GC.BlkAttr.NO_SCAN));
+ assert(a[0][0].ptr is null);
+ }
+}
import core.stdc.stdio;
import core.thread;
-version (CRuntime_DigitalMars)
-{
- extern (C)
- {
- extern int _tlsstart;
- extern int _tlsend;
- }
-}
-
int tlsx;
class Foo
tlsx = 5;
Thread t = Thread.getThis();
- version (CRuntime_DigitalMars)
- printf("thread ptr=%p, %p &tlsx = %p %p\n", t, &_tlsstart, &tlsx, &_tlsend);
x = 3;
printf("-bar()\n");
}
foreach(byte val; values!byte()) check(val);
foreach(ubyte val; values!ubyte()) check(val);
foreach(char val; values!char()) check(val);
-version(CppRuntime_DigitalMars){} else
version(CppRuntime_Microsoft)
{
// TODO: figure out how to detect VS2013 which doesn't support char16_t/char32_t
// N.B MSVC doesn't have a C++11 switch, but it defaults to the latest fully-supported standard
-// Broken for unknown reasons since the OMF => MsCOFF switch
-// DISABLED: win32omf
-
import core.stdc.stdio;
import core.stdc.stdarg;
import core.stdc.config;
}
////////
-version(CppRuntime_DigitalMars)
- enum UNICODE = false;
-else version(CppRuntime_Microsoft)
+version(CppRuntime_Microsoft)
enum UNICODE = false; //VS2013 doesn't support them
else
enum UNICODE = true;
extern(C++, "foo", "bar", "baz") int doStuff(int);
-version(CppRuntime_DigitalMars) // DMC doesn't support c++11
-{
- void test40() {}
- void test41() {}
-}
-else
-{
- void test40();
+void test40();
- void foovargs(T...)(T args)
+void foovargs(T...)(T args)
+{
+ static if (is(T[0] == char*))
{
- static if (is(T[0] == char*))
- {
- assert(*args[0] == 'a');
- }
- else
- {
- float ret = args[0] + args[1];
- assert(ret == 3.0f);
- }
+ assert(*args[0] == 'a');
}
-
- alias FooVargs = foovargs!(int, float);
- alias FooVargs2 = foovargs!(char*);
-
- void test41();
- void make_shared_poc(T, Args...)(ref Args args)
+ else
{
- assert(args[0] + args[1] == 3);
+ float ret = args[0] + args[1];
+ assert(ret == 3.0f);
}
- alias Make_Shared_Poc = make_shared_poc!(int, int, int);
}
+alias FooVargs = foovargs!(int, float);
+alias FooVargs2 = foovargs!(char*);
+
+void test41();
+void make_shared_poc(T, Args...)(ref Args args)
+{
+ assert(args[0] + args[1] == 3);
+}
+alias Make_Shared_Poc = make_shared_poc!(int, int, int);
+
void main()
{
test1(Foo!int());
int (C2::*fp1)(int) = &C2::f1;
int (C2::*fp2)(int, int) = &C2::f2;
int (C2::*fp3)(int, int) = &C2::f3;
-#ifndef __DMC__
int (C2::*fp4)(int, ...) = &C2::f4;
-#endif
assert((c2->*(fp0))() == 100);
assert((c2->*(fp1))(1) == 101);
assert((c2->*(fp2))(20, 3) == 123);
assert((c2->*(fp3))(20, 3) == 123);
-#ifndef __DMC__
assert((c2->*(fp4))(20, 3, 0) == 123);
-#endif
}
struct test19248 {int a;};
};
-#ifdef __DMC__
-// DMC doesn't support c++11
-#elif defined (_MSC_VER) && _MSC_VER <= 1800
+#if defined (_MSC_VER) && _MSC_VER <= 1800
// MSVC2013 doesn't support char16_t/char32_t
#else
#define TEST_UNICODE
S18784::S18784(int n) : i(n) {}
-#ifdef __DMC__ // DMC doesn't support c++11
-template <class>
-#else
template <class...>
-#endif
struct SPack
{
int i;
return ch;
}
}
-#ifdef __DMC__
-// DMC doesn't support c++11
-#elif defined (_MSC_VER) //&& _MSC_VER <= 1800
+#if defined (_MSC_VER) //&& _MSC_VER <= 1800
// MSVC2013 doesn't support char16_t/char32_t
#else
#define TEST_UNICODE
}
}
-#ifndef __DMC__ // DMC doesn't support c++11
template<typename ...T> void foovargs(T... args);
void test40()
make_shared_poc<int, int, int>(a, b);
}
-#endif
-#if defined(__DMC__) // DMC doesn't support immintrin.h
-#else
-
#include <assert.h>
// Inline the typedef of __m128 instead of including immintrin.h.
assert(b.array[2] == 1);
assert(b.array[3] == 1);
}
-
-#endif
import core.simd;
-version (CRuntime_DigitalMars) // DMC doesn't support immintrin.h
-{
- void main() {}
-}
-else static if (!__traits(compiles, float4)) // No __vector support
+static if (!__traits(compiles, float4)) // No __vector support
{
void main() {}
}
-c11e1d1708646c9ac81ac2aafb57fa1ef5d289ad
+07bc5b9b3c81cc0d4314e0040de981124b363ea5
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
* This module contains UDA's (User Defined Attributes) either used in
* the runtime or special UDA's recognized by compiler.
*
+ * $(SCRIPT inhibitQuickIndex = 1;)
+ * $(BOOKTABLE Cheat Sheet,
+ * $(THEAD Attribute Name, Linkage, Description)
+ * $(TROW $(LREF gnuAbiTag), C++,
+ * Declares an ABI tag on a C++ symbol.)
+ * $(TROW $(LREF mustuse),,
+ * Ensures that values of a struct or union type are not discarded.)
+ * $(TROW $(LREF optional), Objective-C,
+ * Makes an Objective-C interface method optional.)
+ * $(TROW $(LREF selector), Objective-C,
+ * Attaches an Objective-C selector to a method.)
+ * $(TROW $(LREF weak),,
+ * Specifies that a global symbol should be emitted with weak linkage.)
+ * )
+ *
* Copyright: Copyright Jacob Carlborg 2015.
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Authors: Jacob Carlborg
assert(demangle(aggr.mangleof) == "pure nothrow @nogc @safe void " ~ parent ~ "().aggr(" ~ parent ~ "().S!(noreturn).S)");
}
-/*
- * Expand an OMF, DMD-generated compressed identifier into its full form
- *
- * This function only has a visible effect for OMF binaries (Win32),
- * as compression is otherwise not used.
- *
- * See_Also: `compiler/src/dmd/backend/compress.d`
- */
-string decodeDmdString( const(char)[] ln, ref size_t p ) nothrow pure @safe
-{
- string s;
- uint zlen, zpos;
-
- // decompress symbol
- while ( p < ln.length )
- {
- int ch = cast(ubyte) ln[p++];
- if ( (ch & 0xc0) == 0xc0 )
- {
- zlen = (ch & 0x7) + 1;
- zpos = ((ch >> 3) & 7) + 1; // + zlen;
- if ( zpos > s.length )
- break;
- s ~= s[$ - zpos .. $ - zpos + zlen];
- }
- else if ( ch >= 0x80 )
- {
- if ( p >= ln.length )
- break;
- int ch2 = cast(ubyte) ln[p++];
- zlen = (ch2 & 0x7f) | ((ch & 0x38) << 4);
- if ( p >= ln.length )
- break;
- int ch3 = cast(ubyte) ln[p++];
- zpos = (ch3 & 0x7f) | ((ch & 7) << 7);
- if ( zpos > s.length )
- break;
- s ~= s[$ - zpos .. $ - zpos + zlen];
- }
- else if ( Demangle!().isAlpha(cast(char)ch) || Demangle!().isDigit(cast(char)ch) || ch == '_' )
- s ~= cast(char) ch;
- else
- {
- p--;
- break;
- }
- }
- return s;
-}
-
// locally purified for internal use here only
extern (C) private
{
assert(n > 4 && n < fmt.length);
int nscanned;
- version (CRuntime_DigitalMars)
- {
- /* Older sscanf's in snn.lib can write to its first argument, causing a crash
- * if the string is in readonly memory. Recent updates to DMD
- * https://github.com/dlang/dmd/pull/6546
- * put string literals in readonly memory.
- * Although sscanf has been fixed,
- * http://ftp.digitalmars.com/snn.lib
- * this workaround is here so it still works with the older snn.lib.
- */
- // Create mutable copy of str
- const length = str.length;
- char* mptr = cast(char*)malloc(length + 1);
- assert(mptr);
- memcpy(mptr, str.ptr, length);
- mptr[length] = 0;
- const result = sscanf(mptr, fmt.ptr, &res, &nscanned);
- free(mptr);
- if (result < 1)
- return parseError("a float", optname, str, errName);
- }
- else
- {
- if (sscanf(str.ptr, fmt.ptr, &res, &nscanned) < 1)
- return parseError("a float", optname, str, errName);
- }
+ if (sscanf(str.ptr, fmt.ptr, &res, &nscanned) < 1)
+ return parseError("a float", optname, str, errName);
str = str[nscanned .. $];
return true;
}
nothrow:
@nogc:
-version (CRuntime_DigitalMars)
-{
- /***
- * Assert failure function in the Digital Mars C library.
- */
- noreturn _assert(const(void)* exp, const(void)* file, uint line);
-}
-else version (CRuntime_Microsoft)
+version (CRuntime_Microsoft)
{
/***
* Assert failure function in the Microsoft C library.
nothrow:
@nogc:
-version (CRuntime_DigitalMars)
-{
- extern (C)
- {
- ref int _errno();
- alias errno = _errno;
- }
-}
-else version (CRuntime_Microsoft)
+version (CRuntime_Microsoft)
{
extern (C)
{
extern (C):
-version (CRuntime_DigitalMars)
-{
- enum EPERM = 1; /// Operation not permitted
- enum ENOENT = 2; /// No such file or directory
- enum ESRCH = 3; /// No such process
- enum EINTR = 4; /// Interrupted system call
- enum EIO = 5; /// I/O error
- enum ENXIO = 6; /// No such device or address
- enum E2BIG = 7; /// Argument list too long
- enum ENOEXEC = 8; /// Exec format error
- enum EBADF = 9; /// Bad file number
- enum ECHILD = 10; /// No child processes
- enum EAGAIN = 11; /// Try again
- enum ENOMEM = 12; /// Out of memory
- enum EACCES = 13; /// Permission denied
- enum EFAULT = 14; /// Bad address
- enum EBUSY = 16; /// Device or resource busy
- enum EEXIST = 17; /// File exists
- enum EXDEV = 18; /// Cross-device link
- enum ENODEV = 19; /// No such device
- enum ENOTDIR = 20; /// Not a directory
- enum EISDIR = 21; /// Is a directory
- enum EINVAL = 22; /// Invalid argument
- enum ENFILE = 23; /// File table overflow
- enum EMFILE = 24; /// Too many open files
- enum ENOTTY = 25; /// Not a typewriter
- enum EFBIG = 27; /// File too large
- enum ENOSPC = 28; /// No space left on device
- enum ESPIPE = 29; /// Illegal seek
- enum EROFS = 30; /// Read-only file system
- enum EMLINK = 31; /// Too many links
- enum EPIPE = 32; /// Broken pipe
- enum EDOM = 33; /// Math argument out of domain of func
- enum ERANGE = 34; /// Math result not representable
- enum EDEADLK = 36; /// Resource deadlock would occur
- enum ENAMETOOLONG = 38; /// File name too long
- enum ENOLCK = 39; /// No record locks available
- enum ENOSYS = 40; /// Function not implemented
- enum ENOTEMPTY = 41; /// Directory not empty
- enum EILSEQ = 42; /// Illegal byte sequence
- enum EDEADLOCK = EDEADLK; /// Resource deadlock would occur
-
- // POSIX compatibility
- // See_Also: https://docs.microsoft.com/en-us/cpp/c-runtime-library/errno-constants
- enum EADDRINUSE = 100;
- enum EADDRNOTAVAIL = 101;
- enum EAFNOSUPPORT = 102;
- enum EALREADY = 103;
- enum EBADMSG = 104;
- enum ECANCELED = 105;
- enum ECONNABORTED = 106;
- enum ECONNREFUSED = 107;
- enum ECONNRESET = 108;
- enum EDESTADDRREQ = 109;
- enum EHOSTUNREACH = 110;
- enum EIDRM = 111;
- enum EINPROGRESS = 112;
- enum EISCONN = 113;
- enum ELOOP = 114;
- enum EMSGSIZE = 115;
- enum ENETDOWN = 116;
- enum ENETRESET = 117;
- enum ENETUNREACH = 118;
- enum ENOBUFS = 119;
- enum ENODATA = 120;
- enum ENOLINK = 121;
- enum ENOMSG = 122;
- enum ENOPROTOOPT = 123;
- enum ENOSR = 124;
- enum ENOSTR = 125;
- enum ENOTCONN = 126;
- enum ENOTRECOVERABLE = 127;
- enum ENOTSOCK = 128;
- enum ENOTSUP = 129;
- enum EOPNOTSUPP = 130;
- enum EOTHER = 131;
- enum EOVERFLOW = 132;
- enum EOWNERDEAD = 133;
- enum EPROTO = 134;
- enum EPROTONOSUPPORT = 135;
- enum EPROTOTYPE = 136;
- enum ETIME = 137;
- enum ETIMEDOUT = 138;
- enum ETXTBSY = 139;
- enum EWOULDBLOCK = 140;
-}
-else version (CRuntime_Microsoft)
+version (CRuntime_Microsoft)
{
enum EPERM = 1; /// Operation not permitted
enum ENOENT = 2; /// No such file or directory
static assert(0, "Unimplemented architecture");
}
}
-else version (CRuntime_DigitalMars)
-{
- struct fenv_t
- {
- ushort status;
- ushort control;
- ushort round;
- ushort[2] reserved;
- }
- alias fexcept_t = int;
-}
else version (CRuntime_Microsoft)
{
struct fenv_t
///
enum FE_DFL_ENV = cast(fenv_t*)(-1);
}
-else version (CRuntime_DigitalMars)
-{
- private extern __gshared fenv_t _FE_DFL_ENV;
- ///
- enum fenv_t* FE_DFL_ENV = &_FE_DFL_ENV;
-}
else version (CRuntime_Microsoft)
{
private extern __gshared fenv_t _Fenv0;
pure int isunordered(real x, real y);
}
-version (CRuntime_DigitalMars)
-{
- enum
- {
- ///
- FP_NANS = 0,
- ///
- FP_NANQ = 1,
- ///
- FP_INFINITE = 2,
- ///
- FP_NORMAL = 3,
- ///
- FP_SUBNORMAL = 4,
- ///
- FP_ZERO = 5,
- ///
- FP_NAN = FP_NANQ,
- ///
- FP_EMPTY = 6,
- ///
- FP_UNSUPPORTED = 7,
- }
-
- enum
- {
- ///
- FP_FAST_FMA = 0,
- ///
- FP_FAST_FMAF = 0,
- ///
- FP_FAST_FMAL = 0,
- }
-
- pure uint __fpclassify_f(float x);
- pure uint __fpclassify_d(double x);
- pure uint __fpclassify_ld(real x);
-
- //int fpclassify(real-floating x);
- ///
- pragma(mangle, "__fpclassify_f") pure int fpclassify(float x);
- ///
- pragma(mangle, "__fpclassify_d") pure int fpclassify(double x);
- ///
- pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify_d" : "__fpclassify_ld")
- pure int fpclassify(real x);
-
- extern (D)
- {
- //int isfinite(real-floating x);
- ///
- pure int isfinite(float x) { return fpclassify(x) >= FP_NORMAL; }
- ///
- pure int isfinite(double x) { return fpclassify(x) >= FP_NORMAL; }
- ///
- pure int isfinite(real x) { return fpclassify(x) >= FP_NORMAL; }
-
- //int isinf(real-floating x);
- ///
- pure int isinf(float x) { return fpclassify(x) == FP_INFINITE; }
- ///
- pure int isinf(double x) { return fpclassify(x) == FP_INFINITE; }
- ///
- pure int isinf(real x) { return fpclassify(x) == FP_INFINITE; }
-
- //int isnan(real-floating x);
- ///
- pure int isnan(float x) { return fpclassify(x) <= FP_NANQ; }
- ///
- pure int isnan(double x) { return fpclassify(x) <= FP_NANQ; }
- ///
- pure int isnan(real x) { return fpclassify(x) <= FP_NANQ; }
-
- //int isnormal(real-floating x);
- ///
- pure int isnormal(float x) { return fpclassify(x) == FP_NORMAL; }
- ///
- pure int isnormal(double x) { return fpclassify(x) == FP_NORMAL; }
- ///
- pure int isnormal(real x) { return fpclassify(x) == FP_NORMAL; }
-
- //int signbit(real-floating x);
- ///
- pure int signbit(float x) { return (cast(short*)&(x))[1] & 0x8000; }
- ///
- pure int signbit(double x) { return (cast(short*)&(x))[3] & 0x8000; }
- ///
- pure int signbit(real x)
- {
- return (real.sizeof == double.sizeof)
- ? (cast(short*)&(x))[3] & 0x8000
- : (cast(short*)&(x))[4] & 0x8000;
- }
- }
-}
-else version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) only
+version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) only
{
version (all) // legacy stuff to be removed in the future
{
alias int16_t = short; ///
alias uint8_t = ubyte; ///
alias uint16_t = ushort; ///
- version (CRuntime_DigitalMars)
- {
- alias int32_t = cpp_long; ///
- alias uint32_t = cpp_ulong; ///
- }
- else
- {
- alias int32_t = int; ///
- alias uint32_t = uint; ///
- }
+ alias int32_t = int; ///
+ alias uint32_t = uint; ///
alias int64_t = long; ///
alias uint64_t = ulong; ///
nothrow:
@nogc:
-version (CRuntime_DigitalMars)
-{
- enum
- {
- ///
- BUFSIZ = 0x4000,
- ///
- EOF = -1,
- ///
- FOPEN_MAX = 20,
- ///
- FILENAME_MAX = 256, // 255 plus NULL
- ///
- TMP_MAX = 32767,
- ///
- SYS_OPEN = 20, // non-standard
- }
-
- ///
- enum int _NFILE = 60; // non-standard
- ///
- enum string _P_tmpdir = "\\"; // non-standard
- ///
- enum wstring _wP_tmpdir = "\\"; // non-standard
- ///
- enum int L_tmpnam = _P_tmpdir.length + 12;
-}
-else version (CRuntime_Microsoft)
+version (CRuntime_Microsoft)
{
enum
{
SEEK_END
}
-version (CRuntime_DigitalMars)
-{
- ///
- alias c_long fpos_t;
-
- ///
- struct _iobuf
- {
- char* _ptr;
- int _cnt;
- char* _base;
- int _flag;
- int _file;
- int _charbuf;
- int _bufsiz;
- char* __tmpnum;
- }
-
- ///
- alias shared(_iobuf) FILE;
-}
-else version (CRuntime_Microsoft)
+version (CRuntime_Microsoft)
{
///
alias long fpos_t;
_F_TERM = 0x0200, // non-standard
}
-version (CRuntime_DigitalMars)
-{
- enum
- {
- ///
- _IOFBF = 0,
- ///
- _IOLBF = 0x40,
- ///
- _IONBF = 4,
- ///
- _IOREAD = 1, // non-standard
- ///
- _IOWRT = 2, // non-standard
- ///
- _IOMYBUF = 8, // non-standard
- ///
- _IOEOF = 0x10, // non-standard
- ///
- _IOERR = 0x20, // non-standard
- ///
- _IOSTRG = 0x40, // non-standard
- ///
- _IORW = 0x80, // non-standard
- ///
- _IOTRAN = 0x100, // non-standard
- ///
- _IOAPP = 0x200, // non-standard
- }
-
- extern shared void function() _fcloseallp;
-
- private extern shared FILE[_NFILE] _iob;
-
- ///
- enum stdin = &_iob[0];
- ///
- enum stdout = &_iob[1];
- ///
- enum stderr = &_iob[2];
- ///
- enum stdaux = &_iob[3];
- ///
- enum stdprn = &_iob[4];
-}
-else version (CRuntime_Microsoft)
+version (CRuntime_Microsoft)
{
enum
{
c_long ftell(FILE* stream);
}
-version (CRuntime_DigitalMars)
-{
- // No unsafe pointer manipulation.
- extern (D) @trusted
- {
- ///
- void rewind()(FILE* stream) { fseek(stream,0L,SEEK_SET); stream._flag= stream._flag & ~_IOERR; }
- ///
- pure void clearerr()(FILE* stream) { stream._flag = stream._flag & ~(_IOERR|_IOEOF); }
- ///
- pure int feof()(FILE* stream) { return stream._flag&_IOEOF; }
- ///
- pure int ferror()(FILE* stream) { return stream._flag&_IOERR; }
- ///
- pure int fileno()(FILE* stream) { return stream._file; }
- }
- ///
- pragma(printf)
- int _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...);
- ///
- alias _snprintf snprintf;
-
- ///
- pragma(printf)
- int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
- ///
- alias _vsnprintf vsnprintf;
-
- //
- // Digital Mars under-the-hood C I/O functions. Uses _iobuf* for the
- // unshared version of FILE*, usable when the FILE is locked.
- //
-
- ///
- int _fputc_nlock(int c, _iobuf* fp);
- ///
- int _fputwc_nlock(int c, _iobuf* fp);
- ///
- int _fgetc_nlock(_iobuf* fp);
- ///
- int _fgetwc_nlock(_iobuf* fp);
- ///
- int __fp_lock(FILE* fp);
- ///
- void __fp_unlock(FILE* fp);
- ///
- int setmode(int fd, int mode);
-}
-else version (CRuntime_Microsoft)
+version (CRuntime_Microsoft)
{
// No unsafe pointer manipulation.
@trusted
///
void perror(scope const char* s);
-version (CRuntime_DigitalMars)
-{
- version (none)
- import core.sys.windows.windows : HANDLE, _WaitSemaphore, _ReleaseSemaphore;
- else
- {
- // too slow to import windows
- private alias void* HANDLE;
- private void _WaitSemaphore(int iSemaphore);
- private void _ReleaseSemaphore(int iSemaphore);
- }
-
- enum
- {
- ///
- FHND_APPEND = 0x04,
- ///
- FHND_DEVICE = 0x08,
- ///
- FHND_TEXT = 0x10,
- ///
- FHND_BYTE = 0x20,
- ///
- FHND_WCHAR = 0x40,
- }
-
- private enum _MAX_SEMAPHORES = 10 + _NFILE;
- private enum _semIO = 3;
-
- private extern __gshared short[_MAX_SEMAPHORES] _iSemLockCtrs;
- private extern __gshared int[_MAX_SEMAPHORES] _iSemThreadIds;
- private extern __gshared int[_MAX_SEMAPHORES] _iSemNestCount;
- private extern __gshared HANDLE[_NFILE] _osfhnd;
- extern shared ubyte[_NFILE] __fhnd_info;
-
- // this is copied from semlock.h in DMC's runtime.
- private void LockSemaphore()(uint num)
- {
- asm nothrow @nogc
- {
- mov EDX, num;
- lock;
- inc _iSemLockCtrs[EDX * 2];
- jz lsDone;
- push EDX;
- call _WaitSemaphore;
- add ESP, 4;
- }
-
- lsDone: {}
- }
-
- // this is copied from semlock.h in DMC's runtime.
- private void UnlockSemaphore()(uint num)
- {
- asm nothrow @nogc
- {
- mov EDX, num;
- lock;
- dec _iSemLockCtrs[EDX * 2];
- js usDone;
- push EDX;
- call _ReleaseSemaphore;
- add ESP, 4;
- }
-
- usDone: {}
- }
-
- // This converts a HANDLE to a file descriptor in DMC's runtime
- ///
- int _handleToFD()(HANDLE h, int flags)
- {
- LockSemaphore(_semIO);
- scope(exit) UnlockSemaphore(_semIO);
-
- foreach (fd; 0 .. _NFILE)
- {
- if (!_osfhnd[fd])
- {
- _osfhnd[fd] = h;
- __fhnd_info[fd] = cast(ubyte)flags;
- return fd;
- }
- }
-
- return -1;
- }
-
- ///
- HANDLE _fdToHandle()(int fd)
- {
- // no semaphore is required, once inserted, a file descriptor
- // doesn't change.
- if (fd < 0 || fd >= _NFILE)
- return null;
-
- return _osfhnd[fd];
- }
-
- enum
- {
- ///
- STDIN_FILENO = 0,
- ///
- STDOUT_FILENO = 1,
- ///
- STDERR_FILENO = 2,
- }
-
- int open(scope const(char)* filename, int flags, ...); ///
- alias _open = open; ///
- int _wopen(scope const wchar* filename, int oflag, ...); ///
- int sopen(scope const char* filename, int oflag, int shflag, ...); ///
- alias _sopen = sopen; ///
- int _wsopen(scope const wchar* filename, int oflag, int shflag, ...); ///
- int close(int fd); ///
- alias _close = close; ///
- FILE *fdopen(int fd, scope const(char)* flags); ///
- alias _fdopen = fdopen; ///
- FILE *_wfdopen(int fd, scope const(wchar)* flags); ///
-
-}
-else version (CRuntime_Microsoft)
+version (CRuntime_Microsoft)
{
int _open(scope const char* filename, int oflag, ...); ///
int _wopen(scope const wchar* filename, int oflag, ...); ///
import core.stdcpp.xutility : StdNamespace;
-// hacks to support DMD on Win32
-version (CppRuntime_Microsoft)
-{
- version = CppRuntime_Windows; // use the MS runtime ABI for win32
-}
-else version (CppRuntime_DigitalMars)
-{
- version = CppRuntime_Windows; // use the MS runtime ABI for win32
- pragma(msg, "std::array not supported by DMC");
-}
-
extern(C++, (StdNamespace)):
/**
///
ref inout(T) back() inout @safe { static if (N > 0) { return this[N-1]; } else { return as_array()[][0]; /* HACK: force OOB */ } }
- version (CppRuntime_Windows)
+ version (CppRuntime_Microsoft)
{
///
inout(T)* data() inout @safe { return &_Elems[0]; }
extern(D) this(const(char)*, int = 1) nothrow { this(); } // compat with MS derived classes
}
}
-else version (CppRuntime_DigitalMars)
-{
- ///
- class exception
- {
- @nogc:
- ///
- extern(D) this() nothrow {}
- //virtual ~this();
- void dtor() { } // reserve slot in vtbl[]
-
- ///
- const(char)* what() const nothrow;
-
- protected:
- this(const(char)*, int = 1) nothrow { this(); } // compat with MS derived classes
- }
-}
else version (CppRuntime_Microsoft)
{
///
import core.stdc.stddef : wchar_t;
import core.stdcpp.xutility : StdNamespace;
-// hacks to support DMD on Win32
-version (CppRuntime_Microsoft)
-{
- version = CppRuntime_Windows; // use the MS runtime ABI for win32
-}
-else version (CppRuntime_DigitalMars)
-{
- version = CppRuntime_Windows; // use the MS runtime ABI for win32
- pragma(msg, "std::basic_string_view not supported by DMC");
-}
-
extern(C++, (StdNamespace)):
@nogc:
private:
// use the proper field names from C++ so debugging doesn't get weird
- version (CppRuntime_Windows)
+ version (CppRuntime_Microsoft)
{
const_pointer _Mydata;
size_type _Mysize;
import core.attribute : weak;
-version (CppRuntime_DigitalMars)
-{
- import core.stdcpp.exception;
-
- extern (C++, "std"):
-
- class type_info
- {
- @nogc:
- void* pdata;
-
- public:
- //virtual ~this();
- void dtor() { } // reserve slot in vtbl[]
-
- //bool operator==(const type_info rhs) const;
- //bool operator!=(const type_info rhs) const;
- final bool before(const type_info rhs) const nothrow;
- final const(char)* name() const nothrow;
- protected:
- //type_info();
- private:
- //this(const type_info rhs);
- //type_info operator=(const type_info rhs);
- }
-
- class bad_cast : exception
- {
- @nogc:
- extern(D) this() nothrow { }
- extern(D) this(const bad_cast) nothrow { }
- //bad_cast operator=(const bad_cast) nothrow { return this; }
- //virtual ~this() nothrow;
- override const(char)* what() const nothrow;
- }
-
- class bad_typeid : exception
- {
- @nogc:
- extern(D) this() nothrow { }
- extern(D) this(const bad_typeid) nothrow { }
- //bad_typeid operator=(const bad_typeid) nothrow { return this; }
- //virtual ~this() nothrow;
- override const (char)* what() const nothrow;
- }
-}
-else version (CppRuntime_Microsoft)
+version (CppRuntime_Microsoft)
{
import core.stdcpp.exception;
{
version (Win32)
{
- version (CRuntime_DigitalMars)
- {
- extern __gshared byte _tlsstart;
- extern __gshared byte _tlsend;
- extern __gshared void* _tls_callbacks_a;
- }
- else version (CRuntime_Microsoft)
+ version (CRuntime_Microsoft)
{
extern __gshared byte _tls_start;
extern __gshared byte _tls_end;
auto res = formatStackFrame(pc);
res ~= " in ";
const(char)[] tempSymName = symName[0 .. strlen(symName)];
- // Deal with dmd mangling of long names for OMF 32 bits builds
- // Note that `target.d` only defines `CRuntime_DigitalMars` for OMF builds
- version (CRuntime_DigitalMars)
- {
- size_t decodeIndex = 0;
- tempSymName = decodeDmdString(tempSymName, decodeIndex);
- }
res ~= demangle(tempSymName, demangleBuf);
return res;
}
}
-// Workaround OPTLINK bug (Bugzilla 8263)
-extern(Windows) BOOL FixupDebugHeader(HANDLE hProcess, ULONG ActionCode,
- ulong CallbackContext, ulong UserContext)
-{
- if (ActionCode == CBA_READ_MEMORY)
- {
- auto p = cast(IMAGEHLP_CBA_READ_MEMORY*)CallbackContext;
- if (!(p.addr & 0xFF) && p.bytes == 0x1C &&
- // IMAGE_DEBUG_DIRECTORY.PointerToRawData
- (*cast(DWORD*)(p.addr + 24) & 0xFF) == 0x20)
- {
- immutable base = DbgHelp.get().SymGetModuleBase64(hProcess, p.addr);
- // IMAGE_DEBUG_DIRECTORY.AddressOfRawData
- if (base + *cast(DWORD*)(p.addr + 20) == p.addr + 0x1C &&
- *cast(DWORD*)(p.addr + 0x1C) == 0 &&
- *cast(DWORD*)(p.addr + 0x20) == ('N'|'B'<<8|'0'<<16|'9'<<24))
- {
- debug(PRINTF) printf("fixup IMAGE_DEBUG_DIRECTORY.AddressOfRawData\n");
- memcpy(p.buf, cast(void*)p.addr, 0x1C);
- *cast(DWORD*)(p.buf + 20) = cast(DWORD)(p.addr - base) + 0x20;
- *p.bytesread = 0x1C;
- return TRUE;
- }
- }
- }
- return FALSE;
-}
-
private string generateSearchPath()
{
__gshared string[3] defaultPathList = ["_NT_SYMBOL_PATH",
if (!dbghelp.SymInitialize(hProcess, generateSearchPath().ptr, TRUE))
return;
- dbghelp.SymRegisterCallback64(hProcess, &FixupDebugHeader, 0);
-
InitializeCriticalSection(&mutex);
initialized = true;
}
int S_ISCHR(int m) { return (m & S_IFMT) == S_IFCHR; }
}
-version (CRuntime_DigitalMars)
-{
- struct struct_stat
- {
- short st_dev;
- ushort st_ino;
- ushort st_mode;
- short st_nlink;
- ushort st_uid;
- ushort st_gid;
- short st_rdev;
- short dummy;
- int st_size;
- time_t st_atime;
- time_t st_mtime;
- time_t st_ctime;
- }
-
- int stat(const(char)*, struct_stat *);
- int fstat(int, struct_stat *) @trusted;
- int _wstat(const(wchar)*, struct_stat *);
-}
-else version (CRuntime_Microsoft)
+version (CRuntime_Microsoft)
{
struct struct_stat
{
version (Windows)
{
- version (CRuntime_DigitalMars)
- {
- pragma(lib, "snn.lib");
- }
import core.sys.windows.winbase /+: CRITICAL_SECTION, DeleteCriticalSection,
EnterCriticalSection, InitializeCriticalSection, LeaveCriticalSection+/;
else
static assert(0, "unimplemented");
}
-else version (CRuntime_DigitalMars)
- public import rt.sections_win32;
else version (CRuntime_Microsoft)
public import rt.sections_win64;
else version (CRuntime_Bionic)
-303b9c9f7c6457a4f31e7444d5ff0315ba97c704
+de1dea109f40fe4a551578369c474e48845daec1
The first line of this file holds the git revision number of the last
merge done from the dlang/phobos repository.
assert([BigInt(2), BigInt(3)].maxElement == BigInt(3));
}
+// https://issues.dlang.org/show_bug.cgi?id=24596
+@safe unittest
+{
+ static class A {
+ int i;
+ int getI() @safe => i;
+ this(int i) @safe { this.i = i; }
+ }
+ auto arr = [new A(2), new A(3)];
+
+ arr.maxElement!(a => a.getI);
+
+ assert(arr[0].getI == 2);
+}
+
// minPos
/**
Computes a subrange of `range` starting at the first occurrence of `range`'s
Allows manipulating the fraction, exponent, and sign parts of a
`float` separately. The definition is:
+$(RUNNABLE_EXAMPLE
----
struct FloatRep
{
enum uint bias = 127, fractionBits = 23, exponentBits = 8, signBits = 1;
}
----
+)
*/
alias FloatRep = FloatingPointRepresentation!float;
Allows manipulating the fraction, exponent, and sign parts of a
`double` separately. The definition is:
+$(RUNNABLE_EXAMPLE
----
struct DoubleRep
{
enum uint bias = 1023, signBits = 1, fractionBits = 52, exponentBits = 11;
}
----
+)
*/
alias DoubleRep = FloatingPointRepresentation!double;
of a type different than `size_t`, firstly because its length should
be a multiple of `size_t.sizeof`, and secondly because how the bits
are mapped:
+
+ $(RUNNABLE_EXAMPLE
---
size_t[] source = [1, 2, 3, 3424234, 724398, 230947, 389492];
enum sbits = size_t.sizeof * 8;
assert(ba[n] == nth_bit);
}
---
+ )
The least significant bit in any `size_t` unit is the starting bit of this
unit, and the most significant bit is the last bit of this unit. Therefore,
passing e.g. an array of `int`s may result in a different `BitArray`
test!Mallocator();
}
-version (Windows)
+version (CRuntime_Microsoft)
{
- // DMD Win 32 bit, DigitalMars C standard library misses the _aligned_xxx
- // functions family (snn.lib)
- version (CRuntime_DigitalMars)
- {
- // Helper to cast the infos written before the aligned pointer
- // this header keeps track of the size (required to realloc) and of
- // the base ptr (required to free).
- private struct AlignInfo
- {
- void* basePtr;
- size_t size;
-
- @nogc nothrow
- static AlignInfo* opCall(void* ptr)
- {
- return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
- }
- }
-
- @nogc nothrow
- private void* _aligned_malloc(size_t size, size_t alignment)
- {
- import core.stdc.stdlib : malloc;
- size_t offset = alignment + size_t.sizeof * 2 - 1;
-
- // unaligned chunk
- void* basePtr = malloc(size + offset);
- if (!basePtr) return null;
-
- // get aligned location within the chunk
- void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
- & ~(alignment - 1));
-
- // write the header before the aligned pointer
- AlignInfo* head = AlignInfo(alignedPtr);
- head.basePtr = basePtr;
- head.size = size;
-
- return alignedPtr;
- }
-
- @nogc nothrow
- private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
- {
- import core.stdc.stdlib : free;
- import core.stdc.string : memcpy;
-
- if (!ptr) return _aligned_malloc(size, alignment);
-
- // gets the header from the exising pointer
- AlignInfo* head = AlignInfo(ptr);
-
- // gets a new aligned pointer
- void* alignedPtr = _aligned_malloc(size, alignment);
- if (!alignedPtr)
- {
- //to https://msdn.microsoft.com/en-us/library/ms235462.aspx
- //see Return value: in this case the original block is unchanged
- return null;
- }
-
- // copy exising data
- memcpy(alignedPtr, ptr, head.size);
- free(head.basePtr);
-
- return alignedPtr;
- }
-
- @nogc nothrow
- private void _aligned_free(void *ptr)
- {
- import core.stdc.stdlib : free;
- if (!ptr) return;
- AlignInfo* head = AlignInfo(ptr);
- free(head.basePtr);
- }
-
- }
- // DMD Win 64 bit, uses microsoft standard C library which implements them
- else
- {
- @nogc nothrow private extern(C) void* _aligned_malloc(size_t, size_t);
- @nogc nothrow private extern(C) void _aligned_free(void *memblock);
- @nogc nothrow private extern(C) void* _aligned_realloc(void *, size_t, size_t);
- }
+ @nogc nothrow private extern(C) void* _aligned_malloc(size_t, size_t);
+ @nogc nothrow private extern(C) void _aligned_free(void *memblock);
+ @nogc nothrow private extern(C) void* _aligned_realloc(void *, size_t, size_t);
}
/**
assert(!AlignedMallocator.instance.alignedReallocate(c, size_t.max, 4096));
AlignedMallocator.instance.deallocate(c);
}
-
-version (CRuntime_DigitalMars)
-@nogc @system nothrow unittest
-{
- void* m;
-
- size_t m_addr() { return cast(size_t) m; }
-
- m = _aligned_malloc(16, 0x10);
- if (m)
- {
- assert((m_addr & 0xF) == 0);
- _aligned_free(m);
- }
-
- m = _aligned_malloc(16, 0x100);
- if (m)
- {
- assert((m_addr & 0xFF) == 0);
- _aligned_free(m);
- }
-
- m = _aligned_malloc(16, 0x1000);
- if (m)
- {
- assert((m_addr & 0xFFF) == 0);
- _aligned_free(m);
- }
-
- m = _aligned_malloc(16, 0x10);
- if (m)
- {
- assert((cast(size_t) m & 0xF) == 0);
- m = _aligned_realloc(m, 32, 0x10000);
- if (m) assert((m_addr & 0xFFFF) == 0);
- _aligned_free(m);
- }
-
- m = _aligned_malloc(8, 0x10);
- if (m)
- {
- *cast(ulong*) m = 0X01234567_89ABCDEF;
- m = _aligned_realloc(m, 0x800, 0x1000);
- if (m) assert(*cast(ulong*) m == 0X01234567_89ABCDEF);
- _aligned_free(m);
- }
-}
+/
void _ensureStatDone() @trusted scope
{
- import std.exception : enforce;
-
if (_didStat)
return;
- enforce(stat(_name.tempCString(), &_statBuf) == 0,
+ cenforce(stat(_name.tempCString(), &_statBuf) == 0,
"Failed to stat file `" ~ _name ~ "'");
_didStat = true;
+/
void _ensureLStatDone() @trusted scope
{
- import std.exception : enforce;
-
if (_didLStat)
return;
stat_t statbuf = void;
- enforce(lstat(_name.tempCString(), &statbuf) == 0,
+ cenforce(lstat(_name.tempCString(), &statbuf) == 0,
"Failed to stat file `" ~ _name ~ "'");
_lstatMode = statbuf.st_mode;
assert(!de.isFile);
assert(!de.isDir);
assert(de.isSymlink);
- assertThrown(de.size);
- assertThrown(de.timeStatusChanged);
- assertThrown(de.timeLastAccessed);
- assertThrown(de.timeLastModified);
- assertThrown(de.attributes);
- assertThrown(de.statBuf);
+ assertThrown!FileException(de.size);
+ assertThrown!FileException(de.timeStatusChanged);
+ assertThrown!FileException(de.timeLastAccessed);
+ assertThrown!FileException(de.timeLastModified);
+ assertThrown!FileException(de.attributes);
+ assertThrown!FileException(de.statBuf);
assert(symfile.exists);
symfile.remove();
}
uint result = void;
asm pure nothrow @nogc
{
- "movfcsr2gr %0,$r2" : "=r" (result);
+ "movfcsr2gr %0, $fcsr2" : "=r" (result);
}
return result & EXCEPTIONS_MASK;
}
ControlState cont;
asm pure nothrow @nogc
{
- "movfcsr2gr %0,$r0" : "=r" (cont);
+ "movfcsr2gr %0, $fcsr0" : "=r" (cont);
}
cont &= (roundingMask | allExceptions);
return cont;
*
* If the fractional part of x is exactly 0.5, the return value is rounded
* away from zero.
- *
- * $(BLUE This function is not implemented for Digital Mars C runtime.)
*/
long lround(real x) @trusted nothrow @nogc
{
- version (CRuntime_DigitalMars)
- assert(0, "lround not implemented");
- else
- return core.stdc.math.llroundl(x);
+ return core.stdc.math.llroundl(x);
}
///
@safe nothrow @nogc unittest
{
- version (CRuntime_DigitalMars) {}
- else
- {
- assert(lround(0.49) == 0);
- assert(lround(0.5) == 1);
- assert(lround(1.5) == 2);
- }
+ assert(lround(0.49) == 0);
+ assert(lround(0.5) == 1);
+ assert(lround(1.5) == 2);
}
/**
version = iOSDerived;
}
-// When the DMC runtime is used, we have to use some custom functions
-// to convert between Windows file handles and FILE*s.
-version (Win32) version (CRuntime_DigitalMars) version = DMC_RUNTIME;
-
// Some of the following should be moved to druntime.
private
{
// Microsoft Visual C Runtime (MSVCRT) declarations.
- version (Windows)
+ version (CRuntime_Microsoft)
{
- version (DMC_RUNTIME) { } else
+ import core.stdc.stdint;
+ enum
{
- import core.stdc.stdint;
- enum
- {
- STDIN_FILENO = 0,
- STDOUT_FILENO = 1,
- STDERR_FILENO = 2,
- }
+ STDIN_FILENO = 0,
+ STDOUT_FILENO = 1,
+ STDERR_FILENO = 2,
}
}
*/
bool opBinaryRight(string op : "in")(scope const(char)[] name) @trusted
{
+ if (name is null)
+ return false;
version (Posix)
return core.sys.posix.stdlib.getenv(name.tempCString()) !is null;
else version (Windows)
// doesn't exist.
void getImpl(scope const(char)[] name, scope void delegate(const(OSChar)[]) @safe sink) @trusted
{
+ // fix issue https://issues.dlang.org/show_bug.cgi?id=24549
+ if (name is null)
+ return sink(null);
+
version (Windows)
{
// first we ask windows how long the environment variable is,
assert("std_process" !in environment);
}
+// https://issues.dlang.org/show_bug.cgi?id=24549
+@safe unittest
+{
+ import std.exception : assertThrown;
+ assert(environment.get(null) is null);
+ assertThrown(environment[null]);
+ assert(!(null in environment));
+}
+
// =============================================================================
// Functions and classes for process management.
// =============================================================================
@property bool backreference() const
{
assert(code == IR.GroupStart || code == IR.GroupEnd);
- return cast(bool)(raw & 1 << 23);
+ return (raw & 1 << 23) != 0;
}
//mark as local reference (for backrefs in lookarounds)
@property bool localRef() const
{
assert(code == IR.Backref);
- return cast(bool)(raw & 1 << 23);
+ return (raw & 1 << 23) != 0;
}
//human readable name of instruction
version (CRuntime_Microsoft)
{
}
-else version (CRuntime_DigitalMars)
-{
-}
else version (CRuntime_Glibc)
{
}
static import core.sys.posix.stdio; // getdelim, flockfile
}
-version (CRuntime_DigitalMars)
-{
- private alias _FPUTC = _fputc_nlock;
- private alias _FPUTWC = _fputwc_nlock;
- private alias _FGETC = _fgetc_nlock;
- private alias _FGETWC = _fgetwc_nlock;
- private alias _FLOCK = __fp_lock;
- private alias _FUNLOCK = __fp_unlock;
-
- // Alias for CRuntime_Microsoft compatibility.
- // @@@DEPRECATED_2.107@@@
- // Rename this back to _setmode once the deprecation phase has ended.
- private alias __setmode = setmode;
-
- // @@@DEPRECATED_2.107@@@
- deprecated("internal alias FPUTC was unintentionally available from "
- ~ "std.stdio and will be removed afer 2.107")
- alias FPUTC = _fputc_nlock;
- // @@@DEPRECATED_2.107@@@
- deprecated("internal alias FPUTWC was unintentionally available from "
- ~ "std.stdio and will be removed afer 2.107")
- alias FPUTWC = _fputwc_nlock;
- // @@@DEPRECATED_2.107@@@
- deprecated("internal alias FGETC was unintentionally available from "
- ~ "std.stdio and will be removed afer 2.107")
- alias FGETC = _fgetc_nlock;
- // @@@DEPRECATED_2.107@@@
- deprecated("internal alias FGETWC was unintentionally available from "
- ~ "std.stdio and will be removed afer 2.107")
- alias FGETWC = _fgetwc_nlock;
- // @@@DEPRECATED_2.107@@@
- deprecated("internal alias FLOCK was unintentionally available from "
- ~ "std.stdio and will be removed afer 2.107")
- alias FLOCK = __fp_lock;
- // @@@DEPRECATED_2.107@@@
- deprecated("internal alias FUNLOCK was unintentionally available from "
- ~ "std.stdio and will be removed afer 2.107")
- alias FUNLOCK = __fp_unlock;
- // @@@DEPRECATED_2.107@@@
- deprecated("internal alias _setmode was unintentionally available from "
- ~ "std.stdio and will be removed afer 2.107")
- alias _setmode = setmode;
- // @@@DEPRECATED_2.107@@@
- deprecated("internal function _fileno was unintentionally available from "
- ~ "std.stdio and will be removed afer 2.107")
- fileno_t _fileno(FILE* f) { return f._file; }
-}
-else version (CRuntime_Microsoft)
+version (CRuntime_Microsoft)
{
private alias _FPUTC = _fputc_nolock;
private alias _FPUTWC = _fputwc_nolock;
private alias _FLOCK = _lock_file;
private alias _FUNLOCK = _unlock_file;
- // @@@DEPRECATED_2.107@@@
- // Remove this once the deprecation phase for CRuntime_DigitalMars has ended.
- private alias __setmode = _setmode;
-
// @@@DEPRECATED_2.107@@@
deprecated("internal alias FPUTC was unintentionally available from "
~ "std.stdio and will be removed afer 2.107")
private extern (C) @nogc nothrow
{
pragma(mangle, _FPUTC.mangleof) int trustedFPUTC(int ch, _iobuf* h) @trusted;
-
- version (CRuntime_DigitalMars)
- pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(int ch, _iobuf* h) @trusted;
- else
- pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(wchar_t ch, _iobuf* h) @trusted;
+ pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(wchar_t ch, _iobuf* h) @trusted;
}
//------------------------------------------------------------------------------
f.close();
}
- version (CRuntime_DigitalMars) {} else // Not implemented
version (CRuntime_Microsoft) {} else // Not implemented
@safe unittest // Test changing mode
{
auto modez = stdioOpenmode.tempCString();
detach();
- version (CRuntime_DigitalMars)
- {
- // This is a re-implementation of DMC's fdopen, but without the
- // mucking with the file descriptor. POSIX standard requires the
- // new fdopen'd file to retain the given file descriptor's
- // position.
- auto fp = fopen("NUL", modez);
- errnoEnforce(fp, "Cannot open placeholder NUL stream");
- _FLOCK(fp);
- auto iob = cast(_iobuf*) fp;
- .close(iob._file);
- iob._file = fd;
- iob._flag &= ~_IOTRAN;
- _FUNLOCK(fp);
- }
- else version (CRuntime_Microsoft)
+ version (CRuntime_Microsoft)
{
auto fp = _fdopen(fd, modez);
errnoEnforce(fp);
import std.format : format;
// Create file descriptors from the handles
- version (CRuntime_DigitalMars)
- auto fd = _handleToFD(handle, FHND_DEVICE);
- else // MSVCRT
- {
- int mode;
- modeLoop:
- foreach (c; stdioOpenmode)
- switch (c)
- {
- case 'r': mode |= _O_RDONLY; break;
- case '+': mode &=~_O_RDONLY; break;
- case 'a': mode |= _O_APPEND; break;
- case 'b': mode |= _O_BINARY; break;
- case 't': mode |= _O_TEXT; break;
- case ',': break modeLoop;
- default: break;
- }
+ int mode;
+ modeLoop:
+ foreach (c; stdioOpenmode)
+ switch (c)
+ {
+ case 'r': mode |= _O_RDONLY; break;
+ case '+': mode &=~_O_RDONLY; break;
+ case 'a': mode |= _O_APPEND; break;
+ case 'b': mode |= _O_BINARY; break;
+ case 't': mode |= _O_TEXT; break;
+ case ',': break modeLoop;
+ default: break;
+ }
- auto fd = _open_osfhandle(cast(intptr_t) handle, mode);
- }
+ auto fd = _open_osfhandle(cast(intptr_t) handle, mode);
errnoEnforce(fd >= 0, "Cannot open Windows HANDLE");
fdopen(fd, stdioOpenmode, "HANDLE(%s)".format(handle));
version (Windows)
{
immutable fileno_t fd = .fileno(_p.handle);
- immutable mode = .__setmode(fd, _O_BINARY);
- scope(exit) .__setmode(fd, mode);
- version (CRuntime_DigitalMars)
- {
- import core.atomic : atomicOp;
-
- // https://issues.dlang.org/show_bug.cgi?id=4243
- immutable info = __fhnd_info[fd];
- atomicOp!"&="(__fhnd_info[fd], ~FHND_TEXT);
- scope(exit) __fhnd_info[fd] = info;
- }
+ immutable mode = ._setmode(fd, _O_BINARY);
+ scope(exit) ._setmode(fd, mode);
}
immutable freadResult = trustedFread(_p.handle, buffer);
assert(freadResult <= buffer.length); // fread return guarantee
version (Windows)
{
immutable fileno_t fd = .fileno(_p.handle);
- immutable oldMode = .__setmode(fd, _O_BINARY);
+ immutable oldMode = ._setmode(fd, _O_BINARY);
if (oldMode != _O_BINARY)
{
// need to flush the data that was written with the original mode
- .__setmode(fd, oldMode);
- flush(); // before changing translation mode .__setmode(fd, _O_BINARY);
- .__setmode(fd, _O_BINARY);
- }
-
- version (CRuntime_DigitalMars)
- {
- import core.atomic : atomicOp;
-
- // https://issues.dlang.org/show_bug.cgi?id=4243
- immutable info = __fhnd_info[fd];
- atomicOp!"&="(__fhnd_info[fd], ~FHND_TEXT);
- scope (exit) __fhnd_info[fd] = info;
+ ._setmode(fd, oldMode);
+ flush(); // before changing translation mode ._setmode(fd, _O_BINARY);
+ ._setmode(fd, _O_BINARY);
}
scope (exit)
if (oldMode != _O_BINARY)
{
flush();
- .__setmode(fd, oldMode);
+ ._setmode(fd, oldMode);
}
}
}
f.seek(7);
assert(f.readln() == "hijklmnopqrstuvwxyz");
- version (CRuntime_DigitalMars)
- auto bigOffset = int.max - 100;
- else
version (CRuntime_Bionic)
auto bigOffset = int.max - 100;
else
version (Windows)
@property HANDLE windowsHandle()
{
- version (CRuntime_DigitalMars)
- return _fdToHandle(fileno);
- else
- return cast(HANDLE)_get_osfhandle(fileno);
+ return cast(HANDLE)_get_osfhandle(fileno);
}
// concept of ANSI/UNICODE mode. fputc doesn't work in UNICODE
// mode; fputwc has to be used. So that essentially means
// "wide-oriented" for us.
- immutable int mode = __setmode(f.fileno, _O_TEXT);
+ immutable int mode = _setmode(f.fileno, _O_TEXT);
// Set some arbitrary mode to obtain the previous one.
- if (mode != -1) // __setmode() succeeded
+ if (mode != -1) // _setmode() succeeded
{
- __setmode(f.fileno, mode); // Restore previous mode.
+ _setmode(f.fileno, mode); // Restore previous mode.
if (mode & (_O_WTEXT | _O_U16TEXT | _O_U8TEXT))
{
orientation_ = 1; // wide
{
fileno_t fd;
int oldMode;
- version (CRuntime_DigitalMars)
- ubyte oldInfo;
}
public:
{
.fflush(fps); // before changing translation mode
fd = .fileno(fps);
- oldMode = .__setmode(fd, _O_BINARY);
- version (CRuntime_DigitalMars)
- {
- import core.atomic : atomicOp;
-
- // https://issues.dlang.org/show_bug.cgi?id=4243
- oldInfo = __fhnd_info[fd];
- atomicOp!"&="(__fhnd_info[fd], ~FHND_TEXT);
- }
+ oldMode = ._setmode(fd, _O_BINARY);
}
}
version (Windows)
{
.fflush(fps); // before restoring translation mode
- version (CRuntime_DigitalMars)
- {
- // https://issues.dlang.org/show_bug.cgi?id=4243
- __fhnd_info[fd] = oldInfo;
- }
- .__setmode(fd, oldMode);
+ ._setmode(fd, oldMode);
}
_FUNLOCK(fps);
return setlocale(LC_CTYPE, loc.ptr).fromStringz.endsWith(loc);
});
scope(exit) () @trusted { setlocale(LC_CTYPE, oldCt); } ();
- version (CRuntime_DigitalMars) // DM can't handle Unicode above U+07FF.
- {
- alias strs = AliasSeq!("xä\u07FE", "yö\u07FF"w);
- }
- else
- {
- alias strs = AliasSeq!("xä\U0001F607", "yö\U0001F608"w);
- }
+ alias strs = AliasSeq!("xä\U0001F607", "yö\U0001F608"w);
{
auto f = File(deleteme, "w");
version (CRuntime_Microsoft)
{
- () @trusted { __setmode(fileno(f.getFP()), _O_U8TEXT); } ();
+ () @trusted { _setmode(fileno(f.getFP()), _O_U8TEXT); } ();
}
else
{
// Private implementation of readln
private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation) @safe
{
- version (CRuntime_DigitalMars)
- return () @trusted {
- auto lf = LockedFile(fps);
- ReadlnAppender app;
- app.initialize(buf);
-
- if (__fhnd_info[lf.fp._file] & FHND_WCHAR)
- { /* Stream is in wide characters.
- * Read them and convert to chars.
- */
- static assert(wchar_t.sizeof == 2);
- for (int c = void; (c = lf.fgetwc()) != -1; )
- {
- if ((c & ~0x7F) == 0)
- {
- app.putchar(cast(char) c);
- if (c == terminator)
- break;
- }
- else
- {
- if (c >= 0xD800 && c <= 0xDBFF)
- {
- int c2 = void;
- if ((c2 = lf.fgetwc()) != -1 ||
- c2 < 0xDC00 && c2 > 0xDFFF)
- {
- StdioException("unpaired UTF-16 surrogate");
- }
- c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
- }
- app.putdchar(cast(dchar) c);
- }
- }
- if (ferror(fps))
- StdioException();
- }
- else if (lf.fp._flag & _IONBF)
- {
- /* Use this for unbuffered I/O, when running
- * across buffer boundaries, or for any but the common
- * cases.
- */
- L1:
- int c;
- while ((c = lf.fgetc()) != -1)
- {
- app.putchar(cast(char) c);
- if (c == terminator)
- {
- buf = app.data;
- return buf.length;
- }
-
- }
-
- if (ferror(fps))
- StdioException();
- }
- else
- {
- int u = lf.fp._cnt;
- char* p = lf.fp._ptr;
- int i;
- if (lf.fp._flag & _IOTRAN)
- { /* Translated mode ignores \r and treats ^Z as end-of-file
- */
- char c;
- while (1)
- {
- if (i == u) // if end of buffer
- goto L1; // give up
- c = p[i];
- i++;
- if (c != '\r')
- {
- if (c == terminator)
- break;
- if (c != 0x1A)
- continue;
- goto L1;
- }
- else
- { if (i != u && p[i] == terminator)
- break;
- goto L1;
- }
- }
- app.putonly(p[0 .. i]);
- app.buf[i - 1] = cast(char) terminator;
- if (terminator == '\n' && c == '\r')
- i++;
- }
- else
- {
- while (1)
- {
- if (i == u) // if end of buffer
- goto L1; // give up
- auto c = p[i];
- i++;
- if (c == terminator)
- break;
- }
- app.putonly(p[0 .. i]);
- }
- lf.fp._cnt -= i;
- lf.fp._ptr += i;
- }
-
- buf = app.data;
- return buf.length;
- }();
- else version (CRuntime_Microsoft)
+ version (CRuntime_Microsoft)
{
auto lf = LockedFile(fps);
n = 0; // consider it 'found' at position 0
Lfound:
-
- // Find the nth character in to[]
- dchar nextt;
- for (size_t i = 0; i < to.length; )
- {
- immutable t = decode(to, i);
- if (t == '-' && lastt != dchar.init && i < to.length)
+ { // create a new scope so that gotos don't skip of declaration of nextt
+ // Find the nth character in to[]
+ dchar nextt;
+ for (size_t i = 0; i < to.length; )
{
- nextt = decode(to, i);
- n -= nextt - lastt;
- if (n < 0)
+ immutable t = decode(to, i);
+ if (t == '-' && lastt != dchar.init && i < to.length)
{
- newc = nextt + n + 1;
+ nextt = decode(to, i);
+ n -= nextt - lastt;
+ if (n < 0)
+ {
+ newc = nextt + n + 1;
+ goto Lnewc;
+ }
+ lastt = dchar.init;
+ continue;
+ }
+ if (n == 0)
+ { newc = t;
goto Lnewc;
}
- lastt = dchar.init;
- continue;
- }
- if (n == 0)
- { newc = t;
- goto Lnewc;
+ lastt = t;
+ nextt = t;
+ n--;
}
- lastt = t;
- nextt = t;
- n--;
+ if (mod_d)
+ continue;
+ newc = nextt;
}
- if (mod_d)
- continue;
- newc = nextt;
-
Lnewc:
if (mod_s && modified && newc == lastc)
continue;
}
// call possible struct destructors
- .destroy!(No.initialize)(*cast(T*) &this.data);
+ static if (is(T == struct))
+ {
+ .destroy!(No.initialize)(*cast(T*) &this.data);
+ }
}
}