d: Merge upstream dmd 93108bb9e, druntime 6364e010, phobos 575b67a9b.
D front-end changes: - Import dmd v2.098.1-beta.1. - Default extern(C++) compatibility to C++17. Druntime changes: - Import druntime v2.098.1-beta.1. - Fix definition of stat_t on MIPS64 (PR103604) Phobos changes: - Import phobos v2.098.1-beta.1. gcc/d/ChangeLog: * d-lang.cc (d_init_options): Set default -fextern-std= to C++17. * dmd/MERGE: Merge upstream dmd 93108bb9e. * gdc.texi (Runtime Options): Document the default for -fextern-std=. libphobos/ChangeLog: PR d/103604 * configure: Regenerate. * configure.ac (libtool_VERSION): Update to 3:0:0. * libdruntime/MERGE: Merge upstream druntime 6364e010. * src/MERGE: Merge upstream phobos 575b67a9b. * testsuite/libphobos.traits/all_satisfy.d: New test. * testsuite/libphobos.traits/traits.exp: New test.
This commit is contained in:
parent
639ece7abf
commit
fd43568cc5
@ -297,8 +297,8 @@ d_init_options (unsigned int, cl_decoded_option *decoded_options)
|
||||
global.params.argv0 = xstrdup (decoded_options[0].arg);
|
||||
global.params.errorLimit = flag_max_errors;
|
||||
|
||||
/* Default extern(C++) mangling to C++14. */
|
||||
global.params.cplusplus = CppStdRevisionCpp14;
|
||||
/* Default extern(C++) mangling to C++17. */
|
||||
global.params.cplusplus = CppStdRevisionCpp17;
|
||||
|
||||
/* Warnings and deprecations are disabled by default. */
|
||||
global.params.useDeprecated = DIAGNOSTICinform;
|
||||
|
@ -1,4 +1,4 @@
|
||||
3982604c54e8770585985a33577fbf19b9b5c9ce
|
||||
93108bb9ea6216d67fa97bb4842fb59f26f6bfc7
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/dmd repository.
|
||||
|
@ -1 +1 @@
|
||||
v2.098.0
|
||||
v2.098.1-beta.1
|
||||
|
@ -1054,6 +1054,12 @@ UnionExp Cast(const ref Loc loc, Type type, Type to, Expression e1)
|
||||
emplaceExp!(UnionExp)(&ue, ex);
|
||||
return ue;
|
||||
}
|
||||
if (e1.type.toBasetype.equals(type) && type.equals(to))
|
||||
{
|
||||
emplaceExp!(UnionExp)(&ue, e1);
|
||||
ue.exp().type = type;
|
||||
return ue;
|
||||
}
|
||||
if (e1.type.implicitConvTo(to) >= MATCH.constant || to.implicitConvTo(e1.type) >= MATCH.constant)
|
||||
{
|
||||
goto L1;
|
||||
@ -1087,7 +1093,19 @@ UnionExp Cast(const ref Loc loc, Type type, Type to, Expression e1)
|
||||
}
|
||||
else if (tb.ty == Tbool)
|
||||
{
|
||||
emplaceExp!(IntegerExp)(&ue, loc, e1.toInteger() != 0, type);
|
||||
bool val = void;
|
||||
const opt = e1.toBool();
|
||||
if (opt.hasValue(true))
|
||||
val = true;
|
||||
else if (opt.hasValue(false))
|
||||
val = false;
|
||||
else
|
||||
{
|
||||
cantExp(ue);
|
||||
return ue;
|
||||
}
|
||||
|
||||
emplaceExp!(IntegerExp)(&ue, loc, val, type);
|
||||
}
|
||||
else if (type.isintegral())
|
||||
{
|
||||
|
@ -975,12 +975,17 @@ final class CParser(AST) : Parser!AST
|
||||
token.value == TOK.leftParenthesis &&
|
||||
!isCastExpression(pt))
|
||||
{
|
||||
/* this might actually be a function
|
||||
* call that looks like `(a)(b)` or even `(a)(b,c)`
|
||||
/* (t)(...)... might be a cast expression or a function call,
|
||||
* with different grammars: a cast would be cparseCastExp(),
|
||||
* a function call would be cparsePostfixExp(CallExp(cparseArguments())).
|
||||
* We can't know until t is known. So, parse it as a function call
|
||||
* and let semantic() rewrite the AST as a CastExp if it turns out
|
||||
* to be a type.
|
||||
*/
|
||||
auto ie = new AST.IdentifierExp(loc, t.isTypeIdentifier().ident);
|
||||
ie.parens = true; // disambiguate it from being a declaration
|
||||
return new AST.CallExp(loc, ie, cparseArguments());
|
||||
ie.parens = true; // let semantic know it might be a CastExp
|
||||
AST.Expression e = new AST.CallExp(loc, ie, cparseArguments());
|
||||
return cparsePostfixOperators(e);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1483,9 +1488,12 @@ final class CParser(AST) : Parser!AST
|
||||
|
||||
/* If a declarator does not follow, it is unnamed
|
||||
*/
|
||||
if (token.value == TOK.semicolon && tspec)
|
||||
if (token.value == TOK.semicolon)
|
||||
{
|
||||
nextToken();
|
||||
if (!tspec)
|
||||
return; // accept empty declaration as an extension
|
||||
|
||||
auto tt = tspec.isTypeTag();
|
||||
if (!tt ||
|
||||
!tt.id && (tt.tok == TOK.struct_ || tt.tok == TOK.union_))
|
||||
@ -1662,7 +1670,8 @@ final class CParser(AST) : Parser!AST
|
||||
{
|
||||
// Give non-extern variables an implicit void initializer
|
||||
// if one has not been explicitly set.
|
||||
if (!hasInitializer && !(specifier.scw & SCW.xextern))
|
||||
if (!hasInitializer &&
|
||||
!(specifier.scw & (SCW.xextern | SCW.xstatic | SCW.x_Thread_local) || level == LVL.global))
|
||||
initializer = new AST.VoidInitializer(token.loc);
|
||||
s = new AST.VarDeclaration(token.loc, dt, id, initializer, specifiersToSTC(level, specifier));
|
||||
}
|
||||
@ -2492,7 +2501,18 @@ final class CParser(AST) : Parser!AST
|
||||
return t;
|
||||
}
|
||||
|
||||
t = constApply(t);
|
||||
if (declarator == DTR.xparameter &&
|
||||
t.isTypePointer())
|
||||
{
|
||||
/* Because there are instances in .h files of "const pointer to mutable",
|
||||
* skip applying transitive `const`
|
||||
* https://issues.dlang.org/show_bug.cgi?id=22534
|
||||
*/
|
||||
auto tn = cast(AST.TypeNext)t;
|
||||
tn.next = constApply(tn.next);
|
||||
}
|
||||
else
|
||||
t = constApply(t);
|
||||
}
|
||||
|
||||
//printf("result: %s\n", t.toChars());
|
||||
@ -2610,6 +2630,8 @@ final class CParser(AST) : Parser!AST
|
||||
|
||||
Identifier id;
|
||||
auto t = cparseDeclarator(DTR.xparameter, tspec, id, specifier);
|
||||
if (token.value == TOK.__attribute__)
|
||||
cparseGnuAttributes(specifier);
|
||||
if (specifier.mod & MOD.xconst)
|
||||
t = toConst(t);
|
||||
auto param = new AST.Parameter(STC.parameter, t, id, null, null);
|
||||
|
@ -1574,7 +1574,7 @@ Expression ctfeIndex(UnionExp* pue, const ref Loc loc, Type type, Expression e1,
|
||||
assert(0);
|
||||
}
|
||||
|
||||
Expression ctfeCast(UnionExp* pue, const ref Loc loc, Type type, Type to, Expression e)
|
||||
Expression ctfeCast(UnionExp* pue, const ref Loc loc, Type type, Type to, Expression e, bool explicitCast = false)
|
||||
{
|
||||
Expression paint()
|
||||
{
|
||||
@ -1587,9 +1587,12 @@ Expression ctfeCast(UnionExp* pue, const ref Loc loc, Type type, Type to, Expres
|
||||
if (e.op == EXP.classReference)
|
||||
{
|
||||
// Disallow reinterpreting class casts. Do this by ensuring that
|
||||
// the original class can implicitly convert to the target class
|
||||
ClassDeclaration originalClass = (cast(ClassReferenceExp)e).originalClass();
|
||||
if (originalClass.type.implicitConvTo(to.mutableOf()))
|
||||
// the original class can implicitly convert to the target class.
|
||||
// Also do not check 'alias this' for explicit cast expressions.
|
||||
auto tclass = (cast(ClassReferenceExp)e).originalClass().type.isTypeClass();
|
||||
auto match = explicitCast ? tclass.implicitConvToWithoutAliasThis(to.mutableOf())
|
||||
: tclass.implicitConvTo(to.mutableOf());
|
||||
if (match)
|
||||
return paint();
|
||||
else
|
||||
{
|
||||
|
@ -6068,7 +6068,7 @@ public:
|
||||
result = pue.exp();
|
||||
return;
|
||||
}
|
||||
result = ctfeCast(pue, e.loc, e.type, e.to, e1);
|
||||
result = ctfeCast(pue, e.loc, e.type, e.to, e1, true);
|
||||
}
|
||||
|
||||
override void visit(AssertExp e)
|
||||
|
@ -462,6 +462,21 @@ extern (C++) class Dsymbol : ASTNode
|
||||
return null;
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* Does this Dsymbol come from a C file?
|
||||
* Returns:
|
||||
* true if it does
|
||||
*/
|
||||
final bool isCsymbol()
|
||||
{
|
||||
if (Module m = getModule())
|
||||
{
|
||||
if (m.isCFile)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**********************************
|
||||
* Determine which Module a Dsymbol is in, as far as access rights go.
|
||||
*/
|
||||
@ -1783,7 +1798,7 @@ extern (C++) final class WithScopeSymbol : ScopeDsymbol
|
||||
// Acts as proxy to the with class declaration
|
||||
Dsymbol s = null;
|
||||
Expression eold = null;
|
||||
for (Expression e = withstate.exp; e != eold; e = resolveAliasThis(_scope, e))
|
||||
for (Expression e = withstate.exp; e && e != eold; e = resolveAliasThis(_scope, e, true))
|
||||
{
|
||||
if (e.op == EXP.scope_)
|
||||
{
|
||||
@ -2426,7 +2441,9 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy
|
||||
auto vd2 = s2.isVarDeclaration(); // existing declaration
|
||||
if (vd && vd2)
|
||||
{
|
||||
// if one is `static` and the other isn't
|
||||
/* if one is `static` and the other isn't, the result is undefined
|
||||
* behavior, C11 6.2.2.7
|
||||
*/
|
||||
if ((vd.storage_class ^ vd2.storage_class) & STC.static_)
|
||||
return collision();
|
||||
|
||||
@ -2437,7 +2454,10 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy
|
||||
return collision(); // can't both have initializers
|
||||
|
||||
if (i1)
|
||||
return vd;
|
||||
{
|
||||
vd2._init = vd._init;
|
||||
vd._init = null;
|
||||
}
|
||||
|
||||
/* BUG: the types should match, which needs semantic() to be run on it
|
||||
* extern int x;
|
||||
@ -2454,15 +2474,38 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy
|
||||
auto fd2 = s2.isFuncDeclaration(); // existing declaration
|
||||
if (fd && fd2)
|
||||
{
|
||||
// if one is `static` and the other isn't
|
||||
if ((fd.storage_class ^ fd2.storage_class) & STC.static_)
|
||||
/* if one is `static` and the other isn't, the result is undefined
|
||||
* behavior, C11 6.2.2.7
|
||||
* However, match what gcc allows:
|
||||
* static int sun1(); int sun1() { return 0; }
|
||||
* and:
|
||||
* static int sun2() { return 0; } int sun2();
|
||||
* Both produce a static function.
|
||||
*
|
||||
* Both of these should fail:
|
||||
* int sun3(); static int sun3() { return 0; }
|
||||
* and:
|
||||
* int sun4() { return 0; } static int sun4();
|
||||
*/
|
||||
// if adding `static`
|
||||
if ( fd.storage_class & STC.static_ &&
|
||||
!(fd2.storage_class & STC.static_))
|
||||
{
|
||||
return collision();
|
||||
}
|
||||
|
||||
if (fd.fbody && fd2.fbody)
|
||||
return collision(); // can't both have bodies
|
||||
|
||||
if (fd.fbody)
|
||||
return fd;
|
||||
{
|
||||
fd2.fbody = fd.fbody; // transfer body to existing declaration
|
||||
fd.fbody = null;
|
||||
|
||||
auto tf = fd.type.toTypeFunction();
|
||||
auto tf2 = fd2.type.toTypeFunction();
|
||||
tf2.parameterList = tf.parameterList; // transfer parameter list.
|
||||
}
|
||||
|
||||
/* BUG: just like with VarDeclaration, the types should match, which needs semantic() to be run on it.
|
||||
* FuncDeclaration::semantic2() can detect this, but it relies overnext being set.
|
||||
|
@ -199,6 +199,7 @@ public:
|
||||
void deprecation(const char *format, ...);
|
||||
bool checkDeprecated(const Loc &loc, Scope *sc);
|
||||
Module *getModule();
|
||||
bool isCsymbol();
|
||||
Module *getAccessModule();
|
||||
Dsymbol *pastMixin();
|
||||
Dsymbol *toParent();
|
||||
|
@ -46,6 +46,7 @@ import dmd.func;
|
||||
import dmd.globals;
|
||||
import dmd.id;
|
||||
import dmd.identifier;
|
||||
import dmd.importc;
|
||||
import dmd.init;
|
||||
import dmd.initsem;
|
||||
import dmd.hdrgen;
|
||||
@ -891,6 +892,10 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
||||
|
||||
bool isBlit = false;
|
||||
d_uns64 sz;
|
||||
if (sc.flags & SCOPE.Cfile && !dsym._init)
|
||||
{
|
||||
addDefaultCInitializer(dsym);
|
||||
}
|
||||
if (!dsym._init &&
|
||||
!(dsym.storage_class & (STC.static_ | STC.gshared | STC.extern_)) &&
|
||||
fd &&
|
||||
@ -900,7 +905,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
||||
{
|
||||
// Provide a default initializer
|
||||
|
||||
//printf("Providing default initializer for '%s'\n", toChars());
|
||||
//printf("Providing default initializer for '%s'\n", dsym.toChars());
|
||||
if (sz == SIZE_INVALID && dsym.type.ty != Terror)
|
||||
dsym.error("size of type `%s` is invalid", dsym.type.toChars());
|
||||
|
||||
|
@ -5529,6 +5529,20 @@ extern (C++) final class TemplateValueParameter : TemplateParameter
|
||||
|
||||
override bool declareParameter(Scope* sc)
|
||||
{
|
||||
/*
|
||||
Do type semantic earlier.
|
||||
|
||||
This means for certain erroneous value parameters
|
||||
their "type" can be known earlier and thus a better
|
||||
error message given.
|
||||
|
||||
For example:
|
||||
`template test(x* x) {}`
|
||||
now yields "undefined identifier" rather than the opaque
|
||||
"variable `x` is used as a type".
|
||||
*/
|
||||
if (valType)
|
||||
valType = valType.typeSemantic(loc, sc);
|
||||
auto v = new VarDeclaration(loc, valType, ident, null);
|
||||
v.storage_class = STC.templateparameter;
|
||||
return sc.insert(v) !is null;
|
||||
|
@ -3985,7 +3985,7 @@ extern (C++) final class FuncExp : Expression
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(tok == TOK.function_ || tok == TOK.reserved && type.ty == Tpointer);
|
||||
assert(tok == TOK.function_ || tok == TOK.reserved && type.ty == Tpointer || fd.errors);
|
||||
tx = tfx.pointerTo();
|
||||
}
|
||||
//printf("\ttx = %s, to = %s\n", tx.toChars(), to.toChars());
|
||||
|
@ -316,6 +316,9 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, Expression* p
|
||||
ie.lwr = sem(ie.lwr);
|
||||
ie.upr = sem(ie.upr);
|
||||
|
||||
if (ie.lwr.isErrorExp() || ie.upr.isErrorExp())
|
||||
errors = true;
|
||||
|
||||
if (lengthVar != ae.lengthVar && sc.func)
|
||||
{
|
||||
// If $ was used, declare it now
|
||||
@ -536,16 +539,16 @@ private Expression resolveUFCS(Scope* sc, CallExp ce)
|
||||
ce.e1 = ey;
|
||||
if (isDotOpDispatch(ey))
|
||||
{
|
||||
uint errors = global.startGagging();
|
||||
e = ce.syntaxCopy().expressionSemantic(sc);
|
||||
if (!global.endGagging(errors))
|
||||
return e;
|
||||
|
||||
// even opDispatch and UFCS must have valid arguments,
|
||||
// so now that we've seen indication of a problem,
|
||||
// check them for issues.
|
||||
Expressions* originalArguments = Expression.arraySyntaxCopy(ce.arguments);
|
||||
|
||||
uint errors = global.startGagging();
|
||||
e = ce.expressionSemantic(sc);
|
||||
if (!global.endGagging(errors))
|
||||
return e;
|
||||
|
||||
if (arrayExpressionSemantic(originalArguments, sc))
|
||||
return ErrorExp.get();
|
||||
|
||||
@ -2792,6 +2795,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||
exp.error("undefined identifier `%s`, did you mean %s `%s`?", exp.ident.toChars(), s2.kind(), s2.toChars());
|
||||
else if (const p = Scope.search_correct_C(exp.ident))
|
||||
exp.error("undefined identifier `%s`, did you mean `%s`?", exp.ident.toChars(), p);
|
||||
else if (exp.ident == Id.dollar)
|
||||
exp.error("undefined identifier `$`");
|
||||
else
|
||||
exp.error("undefined identifier `%s`", exp.ident.toChars());
|
||||
|
||||
@ -4244,6 +4249,16 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (sc.flags & SCOPE.Cfile)
|
||||
{
|
||||
/* See if need to rewrite the AST because of cast/call ambiguity
|
||||
*/
|
||||
if (auto e = castCallAmbiguity(exp, sc))
|
||||
{
|
||||
result = expressionSemantic(e, sc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Expression ex = resolveUFCS(sc, exp))
|
||||
{
|
||||
@ -4425,24 +4440,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||
else if (exp.e1.op == EXP.type && (sc && sc.flags & SCOPE.Cfile))
|
||||
{
|
||||
const numArgs = exp.arguments ? exp.arguments.length : 0;
|
||||
if (e1org.parens && numArgs >= 1)
|
||||
{
|
||||
/* Ambiguous cases arise from CParser where there is not enough
|
||||
* information to determine if we have a function call or a cast.
|
||||
* ( type-name ) ( identifier ) ;
|
||||
* ( identifier ) ( identifier ) ;
|
||||
* If exp.e1 is a type-name, then this is a cast.
|
||||
*/
|
||||
Expression arg;
|
||||
foreach (a; (*exp.arguments)[])
|
||||
{
|
||||
arg = arg ? new CommaExp(a.loc, arg, a) : a;
|
||||
}
|
||||
auto t = exp.e1.isTypeExp().type;
|
||||
auto e = new CastExp(exp.loc, arg, t);
|
||||
result = e.expressionSemantic(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ambiguous cases arise from CParser where there is not enough
|
||||
* information to determine if we have a function call or declaration.
|
||||
@ -6406,6 +6403,18 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||
printf("DotIdExp::semantic(this = %p, '%s')\n", exp, exp.toChars());
|
||||
//printf("e1.op = %d, '%s'\n", e1.op, Token::toChars(e1.op));
|
||||
}
|
||||
|
||||
if (sc.flags & SCOPE.Cfile)
|
||||
{
|
||||
/* See if need to rewrite the AST because of cast/call ambiguity
|
||||
*/
|
||||
if (auto e = castCallAmbiguity(exp, sc))
|
||||
{
|
||||
result = expressionSemantic(e, sc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (exp.arrow) // ImportC only
|
||||
exp.e1 = exp.e1.expressionSemantic(sc).arrayFuncConv(sc);
|
||||
|
||||
@ -8059,6 +8068,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||
}
|
||||
assert(!exp.type);
|
||||
|
||||
if (sc.flags & SCOPE.Cfile)
|
||||
{
|
||||
/* See if need to rewrite the AST because of cast/call ambiguity
|
||||
*/
|
||||
if (auto e = castCallAmbiguity(exp, sc))
|
||||
{
|
||||
result = expressionSemantic(e, sc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
result = exp.carraySemantic(sc); // C semantics
|
||||
if (result)
|
||||
return;
|
||||
@ -8452,6 +8472,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||
return;
|
||||
}
|
||||
|
||||
if (sc.flags & SCOPE.Cfile)
|
||||
{
|
||||
/* See if need to rewrite the AST because of cast/call ambiguity
|
||||
*/
|
||||
if (auto e = castCallAmbiguity(exp, sc))
|
||||
{
|
||||
result = expressionSemantic(e, sc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Expression ex = binSemantic(exp, sc))
|
||||
{
|
||||
result = ex;
|
||||
@ -13050,7 +13081,7 @@ private bool fit(StructDeclaration sd, const ref Loc loc, Scope* sc, Expressions
|
||||
e = resolveProperties(sc, e);
|
||||
if (i >= nfields)
|
||||
{
|
||||
if (i <= sd.fields.dim && e.op == EXP.null_)
|
||||
if (i < sd.fields.dim && e.op == EXP.null_)
|
||||
{
|
||||
// CTFE sometimes creates null as hidden pointer; we'll allow this.
|
||||
continue;
|
||||
|
@ -15,13 +15,18 @@ module dmd.importc;
|
||||
|
||||
import core.stdc.stdio;
|
||||
|
||||
import dmd.astenums;
|
||||
import dmd.dcast;
|
||||
import dmd.declaration;
|
||||
import dmd.dscope;
|
||||
import dmd.dsymbol;
|
||||
import dmd.expression;
|
||||
import dmd.expressionsem;
|
||||
import dmd.identifier;
|
||||
import dmd.init;
|
||||
import dmd.mtype;
|
||||
import dmd.tokens;
|
||||
import dmd.typesem;
|
||||
|
||||
/**************************************
|
||||
* C11 does not allow array or function parameters.
|
||||
@ -84,7 +89,7 @@ Expression arrayFuncConv(Expression e, Scope* sc)
|
||||
}
|
||||
else if (t.isTypeFunction())
|
||||
{
|
||||
e = e.addressOf();
|
||||
e = new AddrExp(e.loc, e);
|
||||
}
|
||||
else
|
||||
return e;
|
||||
@ -169,3 +174,89 @@ Expression carraySemantic(ArrayExp ae, Scope* sc)
|
||||
auto ep = new PtrExp(ae.loc, new AddExp(ae.loc, e1, e2));
|
||||
return ep.expressionSemantic(sc);
|
||||
}
|
||||
|
||||
/******************************************
|
||||
* Determine default initializer for const global symbol.
|
||||
*/
|
||||
void addDefaultCInitializer(VarDeclaration dsym)
|
||||
{
|
||||
//printf("addDefaultCInitializer() %s\n", dsym.toChars());
|
||||
if (!(dsym.storage_class & (STC.static_ | STC.gshared)))
|
||||
return;
|
||||
if (dsym.storage_class & (STC.extern_ | STC.field | STC.in_ | STC.foreach_ | STC.parameter | STC.result))
|
||||
return;
|
||||
|
||||
Type t = dsym.type;
|
||||
if (t.isTypeSArray() && t.isTypeSArray().isIncomplete())
|
||||
{
|
||||
dsym._init = new VoidInitializer(dsym.loc);
|
||||
return; // incomplete arrays will be diagnosed later
|
||||
}
|
||||
|
||||
if (t.isMutable())
|
||||
return;
|
||||
|
||||
auto e = dsym.type.defaultInit(dsym.loc, true);
|
||||
dsym._init = new ExpInitializer(dsym.loc, e);
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* Resolve cast/call grammar ambiguity.
|
||||
* Params:
|
||||
* e = expression that might be a cast, might be a call
|
||||
* sc = context
|
||||
* Returns:
|
||||
* null means leave as is, !=null means rewritten AST
|
||||
*/
|
||||
Expression castCallAmbiguity(Expression e, Scope* sc)
|
||||
{
|
||||
Expression* pe = &e;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Walk down the postfix expressions till we find a CallExp or something else
|
||||
switch ((*pe).op)
|
||||
{
|
||||
case EXP.dotIdentifier:
|
||||
pe = &(*pe).isDotIdExp().e1;
|
||||
continue;
|
||||
|
||||
case EXP.plusPlus:
|
||||
case EXP.minusMinus:
|
||||
pe = &(*pe).isPostExp().e1;
|
||||
continue;
|
||||
|
||||
case EXP.array:
|
||||
pe = &(*pe).isArrayExp().e1;
|
||||
continue;
|
||||
|
||||
case EXP.call:
|
||||
auto ce = (*pe).isCallExp();
|
||||
if (ce.e1.parens)
|
||||
{
|
||||
ce.e1 = expressionSemantic(ce.e1, sc);
|
||||
if (ce.e1.op == EXP.type)
|
||||
{
|
||||
const numArgs = ce.arguments ? ce.arguments.length : 0;
|
||||
if (numArgs >= 1)
|
||||
{
|
||||
ce.e1.parens = false;
|
||||
Expression arg;
|
||||
foreach (a; (*ce.arguments)[])
|
||||
{
|
||||
arg = arg ? new CommaExp(a.loc, arg, a) : a;
|
||||
}
|
||||
auto t = ce.e1.isTypeExp().type;
|
||||
*pe = arg;
|
||||
return new CastExp(ce.loc, e, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -434,11 +434,22 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
|
||||
return i;
|
||||
}
|
||||
if (sc.flags & SCOPE.Cfile)
|
||||
{
|
||||
/* the interpreter turns (char*)"string" into &"string"[0] which then
|
||||
* it cannot interpret. Resolve that case by doing optimize() first
|
||||
*/
|
||||
i.exp = i.exp.optimize(WANTvalue);
|
||||
i.exp = i.exp.ctfeInterpret();
|
||||
if (i.exp.isSymOffExp())
|
||||
{
|
||||
/* `static variable cannot be read at compile time`
|
||||
* https://issues.dlang.org/show_bug.cgi?id=22513
|
||||
* Maybe this would be better addressed in ctfeInterpret()?
|
||||
*/
|
||||
needInterpret = NeedInterpret.INITnointerpret;
|
||||
}
|
||||
}
|
||||
if (needInterpret)
|
||||
i.exp = i.exp.ctfeInterpret();
|
||||
if (i.exp.op == EXP.voidExpression)
|
||||
error(i.loc, "variables cannot be initialized with an expression of type `void`. Use `void` initialization instead.");
|
||||
}
|
||||
|
@ -2073,6 +2073,7 @@ class Lexer
|
||||
bool overflow = false;
|
||||
bool anyBinaryDigitsNoSingleUS = false;
|
||||
bool anyHexDigitsNoSingleUS = false;
|
||||
char errorDigit = 0;
|
||||
dchar c = *p;
|
||||
if (c == '0')
|
||||
{
|
||||
@ -2093,8 +2094,7 @@ class Lexer
|
||||
|
||||
case '8':
|
||||
case '9':
|
||||
if (Ccompile)
|
||||
error("octal digit expected, not `%c`", c);
|
||||
errorDigit = cast(char) c;
|
||||
base = 8;
|
||||
break;
|
||||
case 'x':
|
||||
@ -2205,12 +2205,9 @@ class Lexer
|
||||
// got a digit here, set any necessary flags, check for errors
|
||||
anyHexDigitsNoSingleUS = true;
|
||||
anyBinaryDigitsNoSingleUS = true;
|
||||
if (!err && d >= base)
|
||||
if (!errorDigit && d >= base)
|
||||
{
|
||||
error("%s digit expected, not `%c`", base == 2 ? "binary".ptr :
|
||||
base == 8 ? "octal".ptr :
|
||||
"decimal".ptr, c);
|
||||
err = true;
|
||||
errorDigit = cast(char) c;
|
||||
}
|
||||
// Avoid expensive overflow check if we aren't at risk of overflow
|
||||
if (n <= 0x0FFF_FFFF_FFFF_FFFFUL)
|
||||
@ -2224,6 +2221,13 @@ class Lexer
|
||||
}
|
||||
}
|
||||
Ldone:
|
||||
if (errorDigit)
|
||||
{
|
||||
error("%s digit expected, not `%c`", base == 2 ? "binary".ptr :
|
||||
base == 8 ? "octal".ptr :
|
||||
"decimal".ptr, errorDigit);
|
||||
err = true;
|
||||
}
|
||||
if (overflow && !err)
|
||||
{
|
||||
error("integer overflow");
|
||||
|
@ -523,8 +523,14 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
|
||||
{
|
||||
// Deal with $
|
||||
result = resolveOpDollar(sc, ae, ie, &e0);
|
||||
|
||||
if (result.op == EXP.error)
|
||||
{
|
||||
if (!e0 && !search_function(ad, Id.dollar)) {
|
||||
ae.loc.errorSupplemental("Aggregate declaration '%s' does not define 'opDollar'", ae.e1.toChars());
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Rewrite a[i..j] as:
|
||||
* a.opSlice(i, j)
|
||||
*/
|
||||
@ -597,11 +603,13 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
|
||||
/* Rewrite op(e1) as:
|
||||
* op(e1.aliasthis)
|
||||
*/
|
||||
Expression e1 = resolveAliasThis(sc, e.e1);
|
||||
result = e.copy();
|
||||
(cast(UnaExp)result).e1 = e1;
|
||||
result = result.op_overload(sc);
|
||||
return;
|
||||
if (auto e1 = resolveAliasThis(sc, e.e1, true))
|
||||
{
|
||||
result = e.copy();
|
||||
(cast(UnaExp)result).e1 = e1;
|
||||
result = result.op_overload(sc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import dmd.expressionsem;
|
||||
import dmd.globals;
|
||||
import dmd.init;
|
||||
import dmd.mtype;
|
||||
import dmd.printast;
|
||||
import dmd.root.ctfloat;
|
||||
import dmd.sideeffect;
|
||||
import dmd.tokens;
|
||||
@ -270,6 +271,7 @@ package void setLengthVarIfKnown(VarDeclaration lengthVar, Type type)
|
||||
*/
|
||||
Expression Expression_optimize(Expression e, int result, bool keepLvalue)
|
||||
{
|
||||
//printf("Expression_optimize() %s\n", e.toChars());
|
||||
Expression ret = e;
|
||||
|
||||
void error()
|
||||
@ -459,6 +461,59 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (e.e1.isDotVarExp())
|
||||
{
|
||||
/******************************
|
||||
* Run down the left side of the a.b.c expression to determine the
|
||||
* leftmost variable being addressed (`a`), and accumulate the offsets of the `.b` and `.c`.
|
||||
* Params:
|
||||
* e = the DotVarExp or VarExp
|
||||
* var = set to the VarExp at the end, or null if doesn't end in VarExp
|
||||
* offset = accumulation of all the .var offsets encountered
|
||||
* Returns: true on error
|
||||
*/
|
||||
static bool getVarAndOffset(Expression e, ref VarDeclaration var, ref uint offset)
|
||||
{
|
||||
if (e.type.size() == SIZE_INVALID) // trigger computation of v.offset
|
||||
return true;
|
||||
|
||||
if (auto dve = e.isDotVarExp())
|
||||
{
|
||||
auto v = dve.var.isVarDeclaration();
|
||||
if (!v || !v.isField() || v.isBitFieldDeclaration())
|
||||
return false;
|
||||
|
||||
if (getVarAndOffset(dve.e1, var, offset))
|
||||
return true;
|
||||
offset += v.offset;
|
||||
}
|
||||
else if (auto ve = e.isVarExp())
|
||||
{
|
||||
if (!ve.var.isReference() &&
|
||||
!ve.var.isImportedSymbol() &&
|
||||
ve.var.isDataseg() &&
|
||||
ve.var.isCsymbol())
|
||||
{
|
||||
var = ve.var.isVarDeclaration();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint offset;
|
||||
VarDeclaration var;
|
||||
if (getVarAndOffset(e.e1, var, offset))
|
||||
{
|
||||
ret = ErrorExp.get();
|
||||
return;
|
||||
}
|
||||
if (var)
|
||||
{
|
||||
ret = new SymOffExp(e.loc, var, offset, false);
|
||||
ret.type = e.type;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (auto ae = e.e1.isIndexExp())
|
||||
{
|
||||
// Convert &array[n] to &array+n
|
||||
|
@ -5758,7 +5758,26 @@ LagainStc:
|
||||
nextToken();
|
||||
}
|
||||
else
|
||||
check(TOK.semicolon, "statement");
|
||||
{
|
||||
/*
|
||||
* https://issues.dlang.org/show_bug.cgi?id=22529
|
||||
* Avoid empty declaration error in case of missing semicolon
|
||||
* followed by another token and another semicolon. E.g.:
|
||||
*
|
||||
* foo()
|
||||
* return;
|
||||
*
|
||||
* When the missing `;` error is emitted, token is sitting on return.
|
||||
* If we simply use `check` to emit the error, the token is advanced
|
||||
* to `;` and the empty statement error would follow. To avoid that,
|
||||
* we check if the next token is a semicolon and simply output the error,
|
||||
* otherwise we fall back on the old path (advancing the token).
|
||||
*/
|
||||
if (token.value != TOK.semicolon && peek(&token).value == TOK.semicolon)
|
||||
error("found `%s` when expecting `;` following statement", token.toChars());
|
||||
else
|
||||
check(TOK.semicolon, "statement");
|
||||
}
|
||||
s = new AST.ExpStatement(loc, exp);
|
||||
break;
|
||||
}
|
||||
|
@ -82,6 +82,24 @@ extern (C++) final class PrintASTVisitor : Visitor
|
||||
printf(".var: %s\n", e.var ? e.var.toChars() : "");
|
||||
}
|
||||
|
||||
override void visit(SymOffExp e)
|
||||
{
|
||||
printIndent(indent);
|
||||
printf("SymOff %s\n", e.type ? e.type.toChars() : "");
|
||||
printIndent(indent + 2);
|
||||
printf(".var: %s\n", e.var ? e.var.toChars() : "");
|
||||
printIndent(indent + 2);
|
||||
printf(".offset: %llx\n", e.offset);
|
||||
}
|
||||
|
||||
override void visit(VarExp e)
|
||||
{
|
||||
printIndent(indent);
|
||||
printf("Var %s\n", e.type ? e.type.toChars() : "");
|
||||
printIndent(indent + 2);
|
||||
printf(".var: %s\n", e.var ? e.var.toChars() : "");
|
||||
}
|
||||
|
||||
override void visit(DsymbolExp e)
|
||||
{
|
||||
visit(cast(Expression)e);
|
||||
@ -120,6 +138,15 @@ extern (C++) final class PrintASTVisitor : Visitor
|
||||
printAST(e.e1, indent + 2);
|
||||
}
|
||||
|
||||
override void visit(DotVarExp e)
|
||||
{
|
||||
printIndent(indent);
|
||||
printf("DotVar %s\n", e.type ? e.type.toChars() : "");
|
||||
printIndent(indent + 2);
|
||||
printf(".var: %s\n", e.var.toChars());
|
||||
printAST(e.e1, indent + 2);
|
||||
}
|
||||
|
||||
override void visit(BinExp e)
|
||||
{
|
||||
visit(cast(Expression)e);
|
||||
|
@ -235,6 +235,18 @@ private extern(C++) final class Semantic3Visitor : Visitor
|
||||
if (funcdecl.errors || isError(funcdecl.parent))
|
||||
{
|
||||
funcdecl.errors = true;
|
||||
|
||||
// Mark that the return type could not be inferred
|
||||
if (funcdecl.inferRetType)
|
||||
{
|
||||
assert(funcdecl.type);
|
||||
auto tf = funcdecl.type.isTypeFunction();
|
||||
|
||||
// Only change the return type s.t. other analysis is
|
||||
// still possible e.g. missmatched parameter types
|
||||
if (tf && !tf.next)
|
||||
tf.next = Type.terror;
|
||||
}
|
||||
return;
|
||||
}
|
||||
//printf("FuncDeclaration::semantic3('%s.%s', %p, sc = %p, loc = %s)\n", funcdecl.parent.toChars(), funcdecl.toChars(), funcdecl, sc, funcdecl.loc.toChars());
|
||||
|
@ -2471,64 +2471,69 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
|
||||
{
|
||||
Expression initialExp = cs.exp;
|
||||
|
||||
cs.exp = cs.exp.implicitCastTo(sc, sw.condition.type);
|
||||
cs.exp = cs.exp.optimize(WANTvalue | WANTexpand);
|
||||
|
||||
Expression e = cs.exp;
|
||||
// Remove all the casts the user and/or implicitCastTo may introduce
|
||||
// otherwise we'd sometimes fail the check below.
|
||||
while (e.op == EXP.cast_)
|
||||
e = (cast(CastExp)e).e1;
|
||||
|
||||
/* This is where variables are allowed as case expressions.
|
||||
*/
|
||||
if (e.op == EXP.variable)
|
||||
// The switch'ed value has errors and doesn't provide the actual type
|
||||
// Don't touch the case to not replace it with an `ErrorExp` even if it is valid
|
||||
if (sw.condition.type && !sw.condition.type.isTypeError())
|
||||
{
|
||||
VarExp ve = cast(VarExp)e;
|
||||
VarDeclaration v = ve.var.isVarDeclaration();
|
||||
Type t = cs.exp.type.toBasetype();
|
||||
if (v && (t.isintegral() || t.ty == Tclass))
|
||||
cs.exp = cs.exp.implicitCastTo(sc, sw.condition.type);
|
||||
cs.exp = cs.exp.optimize(WANTvalue | WANTexpand);
|
||||
|
||||
Expression e = cs.exp;
|
||||
// Remove all the casts the user and/or implicitCastTo may introduce
|
||||
// otherwise we'd sometimes fail the check below.
|
||||
while (e.op == EXP.cast_)
|
||||
e = (cast(CastExp)e).e1;
|
||||
|
||||
/* This is where variables are allowed as case expressions.
|
||||
*/
|
||||
if (e.op == EXP.variable)
|
||||
{
|
||||
/* Flag that we need to do special code generation
|
||||
* for this, i.e. generate a sequence of if-then-else
|
||||
*/
|
||||
sw.hasVars = 1;
|
||||
|
||||
/* TODO check if v can be uninitialized at that point.
|
||||
*/
|
||||
if (!v.isConst() && !v.isImmutable())
|
||||
VarExp ve = cast(VarExp)e;
|
||||
VarDeclaration v = ve.var.isVarDeclaration();
|
||||
Type t = cs.exp.type.toBasetype();
|
||||
if (v && (t.isintegral() || t.ty == Tclass))
|
||||
{
|
||||
cs.error("`case` variables have to be `const` or `immutable`");
|
||||
}
|
||||
/* Flag that we need to do special code generation
|
||||
* for this, i.e. generate a sequence of if-then-else
|
||||
*/
|
||||
sw.hasVars = 1;
|
||||
|
||||
if (sw.isFinal)
|
||||
{
|
||||
cs.error("`case` variables not allowed in `final switch` statements");
|
||||
errors = true;
|
||||
}
|
||||
|
||||
/* Find the outermost scope `scx` that set `sw`.
|
||||
* Then search scope `scx` for a declaration of `v`.
|
||||
*/
|
||||
for (Scope* scx = sc; scx; scx = scx.enclosing)
|
||||
{
|
||||
if (scx.enclosing && scx.enclosing.sw == sw)
|
||||
continue;
|
||||
assert(scx.sw == sw);
|
||||
|
||||
if (!scx.search(cs.exp.loc, v.ident, null))
|
||||
/* TODO check if v can be uninitialized at that point.
|
||||
*/
|
||||
if (!v.isConst() && !v.isImmutable())
|
||||
{
|
||||
cs.error("`case` variable `%s` declared at %s cannot be declared in `switch` body",
|
||||
v.toChars(), v.loc.toChars());
|
||||
cs.error("`case` variables have to be `const` or `immutable`");
|
||||
}
|
||||
|
||||
if (sw.isFinal)
|
||||
{
|
||||
cs.error("`case` variables not allowed in `final switch` statements");
|
||||
errors = true;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Find the outermost scope `scx` that set `sw`.
|
||||
* Then search scope `scx` for a declaration of `v`.
|
||||
*/
|
||||
for (Scope* scx = sc; scx; scx = scx.enclosing)
|
||||
{
|
||||
if (scx.enclosing && scx.enclosing.sw == sw)
|
||||
continue;
|
||||
assert(scx.sw == sw);
|
||||
|
||||
if (!scx.search(cs.exp.loc, v.ident, null))
|
||||
{
|
||||
cs.error("`case` variable `%s` declared at %s cannot be declared in `switch` body",
|
||||
v.toChars(), v.loc.toChars());
|
||||
errors = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
goto L1;
|
||||
}
|
||||
goto L1;
|
||||
}
|
||||
else
|
||||
cs.exp = cs.exp.ctfeInterpret();
|
||||
}
|
||||
else
|
||||
cs.exp = cs.exp.ctfeInterpret();
|
||||
|
||||
if (StringExp se = cs.exp.toStringExp())
|
||||
cs.exp = se;
|
||||
@ -2539,6 +2544,8 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
|
||||
}
|
||||
|
||||
L1:
|
||||
// // Don't check other cases if this has errors
|
||||
if (!cs.exp.isErrorExp())
|
||||
foreach (cs2; *sw.cases)
|
||||
{
|
||||
//printf("comparing '%s' with '%s'\n", exp.toChars(), cs.exp.toChars());
|
||||
@ -2877,9 +2884,6 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
|
||||
if (rs.exp.op == EXP.call)
|
||||
rs.exp = valueNoDtor(rs.exp);
|
||||
|
||||
if (e0)
|
||||
e0 = e0.optimize(WANTvalue);
|
||||
|
||||
/* Void-return function can have void / noreturn typed expression
|
||||
* on return statement.
|
||||
*/
|
||||
@ -2904,7 +2908,10 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
|
||||
rs.exp = null;
|
||||
}
|
||||
if (e0)
|
||||
{
|
||||
e0 = e0.optimize(WANTvalue);
|
||||
e0 = checkGC(sc, e0);
|
||||
}
|
||||
}
|
||||
|
||||
if (rs.exp)
|
||||
|
@ -323,7 +323,7 @@ struct TargetC
|
||||
/// https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160
|
||||
Gcc_Clang, /// gcc and clang
|
||||
}
|
||||
|
||||
bool crtDestructorsSupported = true; /// Not all platforms support crt_destructor
|
||||
ubyte longsize; /// size of a C `long` or `unsigned long` type
|
||||
ubyte long_doublesize; /// size of a C `long double`
|
||||
ubyte wchar_tsize; /// size of a C `wchar_t` type
|
||||
|
@ -70,6 +70,7 @@ struct TargetC
|
||||
Gcc_Clang, // gcc and clang
|
||||
};
|
||||
|
||||
uint8_t crtDestructorsSupported; // Not all platforms support crt_destructor
|
||||
uint8_t longsize; // size of a C 'long' or 'unsigned long' type
|
||||
uint8_t long_doublesize; // size of a C 'long double'
|
||||
uint8_t wchar_tsize; // size of a C 'wchar_t' type
|
||||
|
@ -52,38 +52,22 @@ enum TOK : ushort
|
||||
new_,
|
||||
delete_,
|
||||
star,
|
||||
symbolOffset,
|
||||
variable,
|
||||
dotVariable,
|
||||
dotIdentifier,
|
||||
dotTemplateInstance,
|
||||
dotType,
|
||||
slice,
|
||||
arrayLength,
|
||||
version_,
|
||||
module_,
|
||||
dollar,
|
||||
template_,
|
||||
dotTemplateDeclaration,
|
||||
declaration,
|
||||
typeof_,
|
||||
pragma_,
|
||||
dSymbol,
|
||||
typeid_,
|
||||
uadd,
|
||||
remove,
|
||||
newAnonymousClass,
|
||||
comment,
|
||||
arrayLiteral,
|
||||
assocArrayLiteral,
|
||||
structLiteral,
|
||||
classReference,
|
||||
thrownException,
|
||||
delegatePointer,
|
||||
delegateFunctionPointer,
|
||||
|
||||
// Operators
|
||||
lessThan = 54,
|
||||
lessThan,
|
||||
greaterThan,
|
||||
lessOrEqual,
|
||||
greaterOrEqual,
|
||||
@ -94,7 +78,7 @@ enum TOK : ushort
|
||||
index,
|
||||
is_,
|
||||
|
||||
leftShift = 64,
|
||||
leftShift,
|
||||
rightShift,
|
||||
leftShiftAssign,
|
||||
rightShiftAssign,
|
||||
@ -136,7 +120,7 @@ enum TOK : ushort
|
||||
preMinusMinus,
|
||||
|
||||
// Numeric literals
|
||||
int32Literal = 104,
|
||||
int32Literal,
|
||||
uns32Literal,
|
||||
int64Literal,
|
||||
uns64Literal,
|
||||
@ -150,22 +134,21 @@ enum TOK : ushort
|
||||
imaginary80Literal,
|
||||
|
||||
// Char constants
|
||||
charLiteral = 116,
|
||||
charLiteral,
|
||||
wcharLiteral,
|
||||
dcharLiteral,
|
||||
|
||||
// Leaf operators
|
||||
identifier = 119,
|
||||
identifier,
|
||||
string_,
|
||||
hexadecimalString,
|
||||
this_,
|
||||
super_,
|
||||
halt,
|
||||
tuple,
|
||||
error,
|
||||
|
||||
// Basic types
|
||||
void_ = 127,
|
||||
void_,
|
||||
int8,
|
||||
uns8,
|
||||
int16,
|
||||
@ -191,7 +174,7 @@ enum TOK : ushort
|
||||
bool_,
|
||||
|
||||
// Aggregates
|
||||
struct_ = 151,
|
||||
struct_,
|
||||
class_,
|
||||
interface_,
|
||||
union_,
|
||||
@ -223,7 +206,7 @@ enum TOK : ushort
|
||||
immutable_,
|
||||
|
||||
// Statements
|
||||
if_ = 181,
|
||||
if_,
|
||||
else_,
|
||||
while_,
|
||||
for_,
|
||||
@ -249,7 +232,7 @@ enum TOK : ushort
|
||||
onScopeSuccess,
|
||||
|
||||
// Contracts
|
||||
invariant_ = 205,
|
||||
invariant_,
|
||||
|
||||
// Testing
|
||||
unittest_,
|
||||
@ -259,7 +242,7 @@ enum TOK : ushort
|
||||
ref_,
|
||||
macro_,
|
||||
|
||||
parameters = 210,
|
||||
parameters,
|
||||
traits,
|
||||
overloadSet,
|
||||
pure_,
|
||||
@ -279,18 +262,9 @@ enum TOK : ushort
|
||||
vector,
|
||||
pound,
|
||||
|
||||
interval = 229,
|
||||
voidExpression,
|
||||
cantExpression,
|
||||
showCtfeContext,
|
||||
|
||||
objcClassReference,
|
||||
vectorArray,
|
||||
|
||||
arrow, // ->
|
||||
colonColon, // ::
|
||||
wchar_tLiteral,
|
||||
compoundLiteral, // ( type-name ) { initializer-list }
|
||||
|
||||
// C only keywords
|
||||
inline,
|
||||
@ -885,33 +859,17 @@ extern (C++) struct Token
|
||||
|
||||
// For debugging
|
||||
TOK.error: "error",
|
||||
TOK.dotIdentifier: "dotid",
|
||||
TOK.dotTemplateDeclaration: "dottd",
|
||||
TOK.dotTemplateInstance: "dotti",
|
||||
TOK.dotVariable: "dotvar",
|
||||
TOK.dotType: "dottype",
|
||||
TOK.symbolOffset: "symoff",
|
||||
TOK.arrayLength: "arraylength",
|
||||
TOK.arrayLiteral: "arrayliteral",
|
||||
TOK.assocArrayLiteral: "assocarrayliteral",
|
||||
TOK.structLiteral: "structliteral",
|
||||
TOK.string_: "string",
|
||||
TOK.dSymbol: "symbol",
|
||||
TOK.tuple: "tuple",
|
||||
TOK.declaration: "declaration",
|
||||
TOK.onScopeExit: "scope(exit)",
|
||||
TOK.onScopeSuccess: "scope(success)",
|
||||
TOK.onScopeFailure: "scope(failure)",
|
||||
TOK.delegatePointer: "delegateptr",
|
||||
|
||||
// Finish up
|
||||
TOK.reserved: "reserved",
|
||||
TOK.remove: "remove",
|
||||
TOK.newAnonymousClass: "newanonclass",
|
||||
TOK.comment: "comment",
|
||||
TOK.classReference: "classreference",
|
||||
TOK.thrownException: "thrownexception",
|
||||
TOK.delegateFunctionPointer: "delegatefuncptr",
|
||||
TOK.int32Literal: "int32v",
|
||||
TOK.uns32Literal: "uns32v",
|
||||
TOK.int64Literal: "int64v",
|
||||
@ -928,19 +886,9 @@ extern (C++) struct Token
|
||||
TOK.wcharLiteral: "wcharv",
|
||||
TOK.dcharLiteral: "dcharv",
|
||||
TOK.wchar_tLiteral: "wchar_tv",
|
||||
TOK.compoundLiteral: "compoundliteral",
|
||||
|
||||
TOK.halt: "halt",
|
||||
TOK.hexadecimalString: "xstring",
|
||||
|
||||
TOK.interval: "interval",
|
||||
TOK.voidExpression: "voidexp",
|
||||
TOK.cantExpression: "cantexp",
|
||||
TOK.showCtfeContext : "showCtfeContext",
|
||||
|
||||
TOK.objcClassReference: "class",
|
||||
TOK.vectorArray: "vectorarray",
|
||||
|
||||
// C only keywords
|
||||
TOK.inline : "inline",
|
||||
TOK.register : "register",
|
||||
|
@ -61,35 +61,19 @@ enum class TOK : unsigned short
|
||||
new_,
|
||||
delete_,
|
||||
star,
|
||||
symbolOffset,
|
||||
variable,
|
||||
dotVariable,
|
||||
dotIdentifier,
|
||||
dotTemplateInstance,
|
||||
dotType,
|
||||
slice,
|
||||
arrayLength,
|
||||
version_,
|
||||
module_,
|
||||
dollar,
|
||||
template_,
|
||||
dotTemplateDeclaration,
|
||||
declaration,
|
||||
typeof_,
|
||||
pragma_,
|
||||
dSymbol,
|
||||
typeid_,
|
||||
uadd,
|
||||
remove,
|
||||
newAnonymousClass,
|
||||
comment,
|
||||
arrayLiteral,
|
||||
assocArrayLiteral,
|
||||
structLiteral,
|
||||
classReference,
|
||||
thrownException,
|
||||
delegatePointer,
|
||||
delegateFunctionPointer,
|
||||
|
||||
// Operators
|
||||
lessThan, // 54
|
||||
@ -169,7 +153,6 @@ enum class TOK : unsigned short
|
||||
hexadecimalString,
|
||||
this_,
|
||||
super_,
|
||||
halt,
|
||||
tuple,
|
||||
error,
|
||||
|
||||
@ -288,18 +271,9 @@ enum class TOK : unsigned short
|
||||
vector,
|
||||
pound,
|
||||
|
||||
interval, // 229
|
||||
voidExpression,
|
||||
cantExpression,
|
||||
showCtfeContext,
|
||||
|
||||
objcClassReference,
|
||||
vectorArray,
|
||||
|
||||
arrow, // ->
|
||||
colonColon, // ::
|
||||
wchar_tLiteral,
|
||||
compoundLiteral, // ( type-name ) { initializer-list }
|
||||
|
||||
// C only keywords
|
||||
inline_,
|
||||
|
@ -1709,13 +1709,22 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
|
||||
}
|
||||
else if (e.op == EXP.variable) // special case: variable is used as a type
|
||||
{
|
||||
/*
|
||||
N.B. This branch currently triggers for the following code
|
||||
template test(x* x)
|
||||
{
|
||||
|
||||
}
|
||||
i.e. the compiler prints "variable x is used as a type"
|
||||
which isn't a particularly good error message (x is a variable?).
|
||||
*/
|
||||
Dsymbol varDecl = mtype.toDsymbol(sc);
|
||||
const(Loc) varDeclLoc = varDecl.getLoc();
|
||||
Module varDeclModule = varDecl.getModule();
|
||||
Module varDeclModule = varDecl.getModule(); //This can be null
|
||||
|
||||
.error(loc, "variable `%s` is used as a type", mtype.toChars());
|
||||
|
||||
if (varDeclModule != sc._module) // variable is imported
|
||||
//Check for null to avoid https://issues.dlang.org/show_bug.cgi?id=22574
|
||||
if ((varDeclModule !is null) && varDeclModule != sc._module) // variable is imported
|
||||
{
|
||||
const(Loc) varDeclModuleImportLoc = varDeclModule.getLoc();
|
||||
.errorSupplemental(
|
||||
@ -4630,11 +4639,12 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)
|
||||
* Params:
|
||||
* mt = the type for which the init expression is returned
|
||||
* loc = the location where the expression needs to be evaluated
|
||||
* isCfile = default initializers are different with C
|
||||
*
|
||||
* Returns:
|
||||
* The initialization expression for the type.
|
||||
*/
|
||||
extern (C++) Expression defaultInit(Type mt, const ref Loc loc)
|
||||
extern (C++) Expression defaultInit(Type mt, const ref Loc loc, const bool isCfile = false)
|
||||
{
|
||||
Expression visitBasic(TypeBasic mt)
|
||||
{
|
||||
@ -4647,12 +4657,12 @@ extern (C++) Expression defaultInit(Type mt, const ref Loc loc)
|
||||
switch (mt.ty)
|
||||
{
|
||||
case Tchar:
|
||||
value = 0xFF;
|
||||
value = isCfile ? 0 : 0xFF;
|
||||
break;
|
||||
|
||||
case Twchar:
|
||||
case Tdchar:
|
||||
value = 0xFFFF;
|
||||
value = isCfile ? 0 : 0xFFFF;
|
||||
break;
|
||||
|
||||
case Timaginary32:
|
||||
@ -4661,14 +4671,15 @@ extern (C++) Expression defaultInit(Type mt, const ref Loc loc)
|
||||
case Tfloat32:
|
||||
case Tfloat64:
|
||||
case Tfloat80:
|
||||
return new RealExp(loc, target.RealProperties.nan, mt);
|
||||
return new RealExp(loc, isCfile ? CTFloat.zero : target.RealProperties.nan, mt);
|
||||
|
||||
case Tcomplex32:
|
||||
case Tcomplex64:
|
||||
case Tcomplex80:
|
||||
{
|
||||
// Can't use fvalue + I*fvalue (the im part becomes a quiet NaN).
|
||||
const cvalue = complex_t(target.RealProperties.nan, target.RealProperties.nan);
|
||||
const cvalue = isCfile ? complex_t(CTFloat.zero, CTFloat.zero)
|
||||
: complex_t(target.RealProperties.nan, target.RealProperties.nan);
|
||||
return new ComplexExp(loc, cvalue, mt);
|
||||
}
|
||||
|
||||
@ -4686,7 +4697,7 @@ extern (C++) Expression defaultInit(Type mt, const ref Loc loc)
|
||||
{
|
||||
//printf("TypeVector::defaultInit()\n");
|
||||
assert(mt.basetype.ty == Tsarray);
|
||||
Expression e = mt.basetype.defaultInit(loc);
|
||||
Expression e = mt.basetype.defaultInit(loc, isCfile);
|
||||
auto ve = new VectorExp(loc, e, mt);
|
||||
ve.type = mt;
|
||||
ve.dim = cast(int)(mt.basetype.size(loc) / mt.elementType().size(loc));
|
||||
@ -4700,9 +4711,9 @@ extern (C++) Expression defaultInit(Type mt, const ref Loc loc)
|
||||
printf("TypeSArray::defaultInit() '%s'\n", mt.toChars());
|
||||
}
|
||||
if (mt.next.ty == Tvoid)
|
||||
return mt.tuns8.defaultInit(loc);
|
||||
return mt.tuns8.defaultInit(loc, isCfile);
|
||||
else
|
||||
return mt.next.defaultInit(loc);
|
||||
return mt.next.defaultInit(loc, isCfile);
|
||||
}
|
||||
|
||||
Expression visitFunction(TypeFunction mt)
|
||||
|
@ -267,15 +267,16 @@ Sets the C++ name mangling compatibility to the version identified by
|
||||
@table @samp
|
||||
@item c++98
|
||||
@item c++03
|
||||
Sets @code{__traits(getTargetInfo "cppStd")} to @code{199711}.
|
||||
Sets @code{__traits(getTargetInfo, "cppStd")} to @code{199711}.
|
||||
@item c++11
|
||||
Sets @code{__traits(getTargetInfo "cppStd")} to @code{201103}.
|
||||
Sets @code{__traits(getTargetInfo, "cppStd")} to @code{201103}.
|
||||
@item c++14
|
||||
Sets @code{__traits(getTargetInfo "cppStd")} to @code{201402}.
|
||||
Sets @code{__traits(getTargetInfo, "cppStd")} to @code{201402}.
|
||||
@item c++17
|
||||
Sets @code{__traits(getTargetInfo "cppStd")} to @code{201703}.
|
||||
Sets @code{__traits(getTargetInfo, "cppStd")} to @code{201703}.
|
||||
This is the default.
|
||||
@item c++20
|
||||
Sets @code{__traits(getTargetInfo "cppStd")} to @code{202002}.
|
||||
Sets @code{__traits(getTargetInfo, "cppStd")} to @code{202002}.
|
||||
@end table
|
||||
|
||||
@item -fno-invariants
|
||||
|
@ -7,6 +7,12 @@
|
||||
|
||||
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;
|
||||
|
||||
extern (C++) int foob(int i, int j, int k);
|
||||
|
||||
class C
|
||||
@ -45,23 +51,26 @@ void test1()
|
||||
c.bar(4, 5, 6);
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(foo.mangleof == "_Z3fooiii");
|
||||
static assert(foob.mangleof == "_Z4foobiii");
|
||||
static assert(C.bar.mangleof == "_ZN1C3barEiii");
|
||||
}
|
||||
version (Win32)
|
||||
version (CppMangle_MSVC)
|
||||
{
|
||||
static assert(foo.mangleof == "?foo@@YAHHHH@Z");
|
||||
static assert(foob.mangleof == "?foob@@YAHHHH@Z");
|
||||
static assert(C.bar.mangleof == "?bar@C@@UAEHHHH@Z");
|
||||
}
|
||||
version (Win64)
|
||||
{
|
||||
static assert(foo.mangleof == "?foo@@YAHHHH@Z");
|
||||
static assert(foob.mangleof == "?foob@@YAHHHH@Z");
|
||||
static assert(C.bar.mangleof == "?bar@C@@UEAAHHHH@Z");
|
||||
version (Win32)
|
||||
{
|
||||
static assert(foo.mangleof == "?foo@@YAHHHH@Z");
|
||||
static assert(foob.mangleof == "?foob@@YAHHHH@Z");
|
||||
static assert(C.bar.mangleof == "?bar@C@@UAEHHHH@Z");
|
||||
}
|
||||
version (Win64)
|
||||
{
|
||||
static assert(foo.mangleof == "?foo@@YAHHHH@Z");
|
||||
static assert(foob.mangleof == "?foob@@YAHHHH@Z");
|
||||
static assert(C.bar.mangleof == "?bar@C@@UEAAHHHH@Z");
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
@ -81,7 +90,7 @@ void test2()
|
||||
assert(i == 8);
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert (getD.mangleof == "_Z4getDv");
|
||||
static assert (D.bar.mangleof == "_ZN1D3barEiii");
|
||||
@ -118,7 +127,7 @@ void test3()
|
||||
assert(i == 8);
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert (callE.mangleof == "_Z5callEP1E");
|
||||
static assert (E.bar.mangleof == "_ZN1E3barEiii");
|
||||
@ -134,7 +143,7 @@ void test4()
|
||||
foo4(null);
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(foo4.mangleof == "_Z4foo4Pc");
|
||||
}
|
||||
@ -160,7 +169,7 @@ void test5()
|
||||
assert(f.p == cast(void*)b);
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(bar5.getFoo.mangleof == "_ZN4bar56getFooEi");
|
||||
static assert (newBar.mangleof == "_Z6newBarv");
|
||||
@ -190,7 +199,7 @@ void test6()
|
||||
assert(f.d == 2.5);
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert (foo6.mangleof == "_Z4foo6v");
|
||||
}
|
||||
@ -221,7 +230,7 @@ void test8()
|
||||
foo8(&c);
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(foo8.mangleof == "_Z4foo8PKc");
|
||||
}
|
||||
@ -239,7 +248,7 @@ void test9()
|
||||
foobar9(a, a);
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(foobar9.mangleof == "_Z7foobar9P5elem9S0_");
|
||||
}
|
||||
@ -298,7 +307,7 @@ extern (C++)
|
||||
void test10058l(void* function(void*), void* function(const (void)*), const(void)* function(void*)) { }
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(test10058a.mangleof == "_Z10test10058aPv");
|
||||
static assert(test10058b.mangleof == "_Z10test10058bPFvPvE");
|
||||
@ -329,7 +338,7 @@ class CallExp
|
||||
static void test11696d(Loc, Expression*, Expression*);
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(CallExp.test11696a.mangleof == "_ZN7CallExp10test11696aE3LocP10ExpressionS2_");
|
||||
static assert(CallExp.test11696b.mangleof == "_ZN7CallExp10test11696bE3LocP10ExpressionPS2_");
|
||||
@ -353,7 +362,7 @@ extern(C++, `N13337a`, `N13337b`, `N13337c`)
|
||||
void foo13337_3(S13337_2 s);
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(foo13337.mangleof == "_ZN7N13337a7N13337b7N13337c8foo13337ENS1_6S13337E");
|
||||
static assert(foo13337_2.mangleof == "_ZN7N13337a7N13337b7N13337c10foo13337_2ENS1_6S13337E");
|
||||
@ -383,7 +392,7 @@ extern(C++)
|
||||
}
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(Struct7030.foo.mangleof == "_ZNK10Struct70303fooEi");
|
||||
static assert(Struct7030.bar.mangleof == "_ZN10Struct70303barEi");
|
||||
@ -494,7 +503,7 @@ extern (C++)
|
||||
void func_20413(pair!(int, float), pair!(float, int));
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
// https://issues.dlang.org/show_bug.cgi?id=17947
|
||||
static assert(std.pair!(void*, void*).swap.mangleof == "_ZNSt4pairIPvS0_E4swapERS1_");
|
||||
@ -531,7 +540,7 @@ alias T36 = int ********** ********** ********** **********;
|
||||
|
||||
extern (C++) void test36(T36, T36*) { }
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(test36.mangleof == "_Z6test36PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPiPS12_");
|
||||
}
|
||||
@ -545,7 +554,7 @@ int test37(T)(){ return 0;}
|
||||
extern(C++, `SPACE`)
|
||||
int test37(T)(){ return 0;}
|
||||
|
||||
version (Posix) // all non-Windows machines
|
||||
version (CppMangle_Itanium) // all non-Windows machines
|
||||
{
|
||||
static assert(SPACE.test37!int.mangleof == "_ZN5SPACE6test37IiEEiv");
|
||||
static assert(test37!int.mangleof == "_ZN5SPACE6test37IiEEiv");
|
||||
@ -556,11 +565,11 @@ version (Posix) // all non-Windows machines
|
||||
|
||||
extern (C++) void test15388(typeof(null));
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(test15388.mangleof == "_Z9test15388Dn");
|
||||
}
|
||||
version (Windows)
|
||||
version (CppMangle_MSVC)
|
||||
{
|
||||
static assert(test15388.mangleof == "?test15388@@YAX$$T@Z");
|
||||
}
|
||||
@ -583,7 +592,7 @@ extern (C++) struct Test14086_S
|
||||
~this();
|
||||
}
|
||||
|
||||
version(Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(Test14086.__ctor.mangleof == "_ZN9Test14086C1Ev");
|
||||
static assert(Test14086.__dtor.mangleof == "_ZN9Test14086D1Ev");
|
||||
@ -591,21 +600,24 @@ version(Posix)
|
||||
static assert(Test14086_S.__ctor.mangleof == "_ZN11Test14086_SC1Ei");
|
||||
static assert(Test14086_S.__dtor.mangleof == "_ZN11Test14086_SD1Ev");
|
||||
}
|
||||
version(Win32)
|
||||
version (CppMangle_MSVC)
|
||||
{
|
||||
static assert(Test14086.__ctor.mangleof == "??0Test14086@@QAE@XZ");
|
||||
static assert(Test14086.__dtor.mangleof == "??1Test14086@@UAE@XZ");
|
||||
static assert(Test14086_2.__dtor.mangleof == "??1Test14086_2@@QAE@XZ");
|
||||
static assert(Test14086_S.__ctor.mangleof == "??0Test14086_S@@QAE@H@Z");
|
||||
static assert(Test14086_S.__dtor.mangleof == "??1Test14086_S@@QAE@XZ");
|
||||
}
|
||||
version(Win64)
|
||||
{
|
||||
static assert(Test14086.__ctor.mangleof == "??0Test14086@@QEAA@XZ");
|
||||
static assert(Test14086.__dtor.mangleof == "??1Test14086@@UEAA@XZ");
|
||||
static assert(Test14086_2.__dtor.mangleof == "??1Test14086_2@@QEAA@XZ");
|
||||
static assert(Test14086_S.__ctor.mangleof == "??0Test14086_S@@QEAA@H@Z");
|
||||
static assert(Test14086_S.__dtor.mangleof == "??1Test14086_S@@QEAA@XZ");
|
||||
version (Win32)
|
||||
{
|
||||
static assert(Test14086.__ctor.mangleof == "??0Test14086@@QAE@XZ");
|
||||
static assert(Test14086.__dtor.mangleof == "??1Test14086@@UAE@XZ");
|
||||
static assert(Test14086_2.__dtor.mangleof == "??1Test14086_2@@QAE@XZ");
|
||||
static assert(Test14086_S.__ctor.mangleof == "??0Test14086_S@@QAE@H@Z");
|
||||
static assert(Test14086_S.__dtor.mangleof == "??1Test14086_S@@QAE@XZ");
|
||||
}
|
||||
version (Win64)
|
||||
{
|
||||
static assert(Test14086.__ctor.mangleof == "??0Test14086@@QEAA@XZ");
|
||||
static assert(Test14086.__dtor.mangleof == "??1Test14086@@UEAA@XZ");
|
||||
static assert(Test14086_2.__dtor.mangleof == "??1Test14086_2@@QEAA@XZ");
|
||||
static assert(Test14086_S.__ctor.mangleof == "??0Test14086_S@@QEAA@H@Z");
|
||||
static assert(Test14086_S.__dtor.mangleof == "??1Test14086_S@@QEAA@XZ");
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
@ -623,17 +635,20 @@ struct S18888(alias arg = T18888)
|
||||
alias I = T18888!(arg!int);
|
||||
}
|
||||
|
||||
version(Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(S18888!().I.fun.mangleof == "_ZN6T18888IS_IiEE3funEv");
|
||||
}
|
||||
version(Win32)
|
||||
version (CppMangle_MSVC)
|
||||
{
|
||||
static assert(S18888!().I.fun.mangleof == "?fun@?$T18888@U?$T18888@H@@@@QAEXXZ");
|
||||
}
|
||||
version(Win64)
|
||||
{
|
||||
static assert(S18888!().I.fun.mangleof == "?fun@?$T18888@U?$T18888@H@@@@QEAAXXZ");
|
||||
version (Win32)
|
||||
{
|
||||
static assert(S18888!().I.fun.mangleof == "?fun@?$T18888@U?$T18888@H@@@@QAEXXZ");
|
||||
}
|
||||
version (Win64)
|
||||
{
|
||||
static assert(S18888!().I.fun.mangleof == "?fun@?$T18888@U?$T18888@H@@@@QEAAXXZ");
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
@ -653,26 +668,29 @@ extern (C++) class C18890_2
|
||||
Agg s;
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(C18890.__dtor.mangleof == "_ZN6C18890D1Ev");
|
||||
static assert(C18890.__xdtor.mangleof == "_ZN6C18890D1Ev");
|
||||
static assert(C18890_2.__dtor.mangleof == "_ZN8C18890_26__dtorEv");
|
||||
static assert(C18890_2.__xdtor.mangleof == "_ZN8C18890_2D1Ev");
|
||||
}
|
||||
version (Win32)
|
||||
version (CppMangle_MSVC)
|
||||
{
|
||||
static assert(C18890.__dtor.mangleof == "??1C18890@@UAE@XZ");
|
||||
static assert(C18890.__xdtor.mangleof == "??_GC18890@@UAEPAXI@Z");
|
||||
static assert(C18890_2.__dtor.mangleof == "?__dtor@C18890_2@@UAEXXZ");
|
||||
static assert(C18890_2.__xdtor.mangleof == "??_GC18890_2@@UAEPAXI@Z");
|
||||
}
|
||||
version (Win64)
|
||||
{
|
||||
static assert(C18890.__dtor.mangleof == "??1C18890@@UEAA@XZ");
|
||||
static assert(C18890.__xdtor.mangleof == "??_GC18890@@UEAAPEAXI@Z");
|
||||
static assert(C18890_2.__dtor.mangleof == "?__dtor@C18890_2@@UEAAXXZ");
|
||||
static assert(C18890_2.__xdtor.mangleof == "??_GC18890_2@@UEAAPEAXI@Z");
|
||||
version (Win32)
|
||||
{
|
||||
static assert(C18890.__dtor.mangleof == "??1C18890@@UAE@XZ");
|
||||
static assert(C18890.__xdtor.mangleof == "??_GC18890@@UAEPAXI@Z");
|
||||
static assert(C18890_2.__dtor.mangleof == "?__dtor@C18890_2@@UAEXXZ");
|
||||
static assert(C18890_2.__xdtor.mangleof == "??_GC18890_2@@UAEPAXI@Z");
|
||||
}
|
||||
version (Win64)
|
||||
{
|
||||
static assert(C18890.__dtor.mangleof == "??1C18890@@UEAA@XZ");
|
||||
static assert(C18890.__xdtor.mangleof == "??_GC18890@@UEAAPEAXI@Z");
|
||||
static assert(C18890_2.__dtor.mangleof == "?__dtor@C18890_2@@UEAAXXZ");
|
||||
static assert(C18890_2.__xdtor.mangleof == "??_GC18890_2@@UEAAPEAXI@Z");
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
@ -688,20 +706,23 @@ extern (C++) class C18891
|
||||
Agg s;
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(C18891.__dtor.mangleof == "_ZN6C18891D1Ev");
|
||||
static assert(C18891.__xdtor.mangleof == "_ZN6C18891D1Ev");
|
||||
}
|
||||
version (Win32)
|
||||
version (CppMangle_MSVC)
|
||||
{
|
||||
static assert(C18891.__dtor.mangleof == "??1C18891@@UAE@XZ");
|
||||
static assert(C18891.__xdtor.mangleof == "??_GC18891@@UAEPAXI@Z");
|
||||
}
|
||||
version (Win64)
|
||||
{
|
||||
static assert(C18891.__dtor.mangleof == "??1C18891@@UEAA@XZ");
|
||||
static assert(C18891.__xdtor.mangleof == "??_GC18891@@UEAAPEAXI@Z");
|
||||
version (Win32)
|
||||
{
|
||||
static assert(C18891.__dtor.mangleof == "??1C18891@@UAE@XZ");
|
||||
static assert(C18891.__xdtor.mangleof == "??_GC18891@@UAEPAXI@Z");
|
||||
}
|
||||
version (Win64)
|
||||
{
|
||||
static assert(C18891.__dtor.mangleof == "??1C18891@@UEAA@XZ");
|
||||
static assert(C18891.__xdtor.mangleof == "??_GC18891@@UEAAPEAXI@Z");
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
@ -719,7 +740,7 @@ extern (C++) struct TestOperators
|
||||
int opAssign(int);
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(TestOperators.opUnary!"*".mangleof == "_ZN13TestOperatorsdeEv");
|
||||
static assert(TestOperators.opUnary!"++".mangleof == "_ZN13TestOperatorsppEv");
|
||||
@ -753,73 +774,76 @@ version (Posix)
|
||||
static assert(TestOperators.opIndex.mangleof == "_ZN13TestOperatorsixEi");
|
||||
static assert(TestOperators.opCall.mangleof == "_ZN13TestOperatorsclEif");
|
||||
}
|
||||
version (Win32)
|
||||
version (CppMangle_MSVC)
|
||||
{
|
||||
static assert(TestOperators.opUnary!"*".mangleof == "??DTestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opUnary!"++".mangleof == "??ETestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opUnary!"--".mangleof == "??FTestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opUnary!"-".mangleof == "??GTestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opUnary!"+".mangleof == "??HTestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opUnary!"~".mangleof == "??STestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opBinary!">>".mangleof == "??5TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"<<".mangleof == "??6TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"*".mangleof == "??DTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"-".mangleof == "??GTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"+".mangleof == "??HTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"&".mangleof == "??ITestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"/".mangleof == "??KTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"%".mangleof == "??LTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"^".mangleof == "??TTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"|".mangleof == "??UTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"*".mangleof == "??XTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"+".mangleof == "??YTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"-".mangleof == "??ZTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"/".mangleof == "??_0TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"%".mangleof == "??_1TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!">>".mangleof == "??_2TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"<<".mangleof == "??_3TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"&".mangleof == "??_4TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"|".mangleof == "??_5TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"^".mangleof == "??_6TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opCast!int.mangleof == "??BTestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opAssign.mangleof == "??4TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opEquals.mangleof == "??8TestOperators@@QAE_NH@Z");
|
||||
static assert(TestOperators.opIndex.mangleof == "??ATestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opCall.mangleof == "??RTestOperators@@QAEHHM@Z");
|
||||
}
|
||||
version (Win64)
|
||||
{
|
||||
static assert(TestOperators.opUnary!"*".mangleof == "??DTestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opUnary!"++".mangleof == "??ETestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opUnary!"--".mangleof == "??FTestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opUnary!"-".mangleof == "??GTestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opUnary!"+".mangleof == "??HTestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opUnary!"~".mangleof == "??STestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opBinary!">>".mangleof == "??5TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"<<".mangleof == "??6TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"*".mangleof == "??DTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"-".mangleof == "??GTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"+".mangleof == "??HTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"&".mangleof == "??ITestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"/".mangleof == "??KTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"%".mangleof == "??LTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"^".mangleof == "??TTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"|".mangleof == "??UTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"*".mangleof == "??XTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"+".mangleof == "??YTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"-".mangleof == "??ZTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"/".mangleof == "??_0TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"%".mangleof == "??_1TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!">>".mangleof == "??_2TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"<<".mangleof == "??_3TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"&".mangleof == "??_4TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"|".mangleof == "??_5TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"^".mangleof == "??_6TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opCast!int.mangleof == "??BTestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opAssign.mangleof == "??4TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opEquals.mangleof == "??8TestOperators@@QEAA_NH@Z");
|
||||
static assert(TestOperators.opIndex.mangleof == "??ATestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opCall.mangleof == "??RTestOperators@@QEAAHHM@Z");
|
||||
version (Win32)
|
||||
{
|
||||
static assert(TestOperators.opUnary!"*".mangleof == "??DTestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opUnary!"++".mangleof == "??ETestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opUnary!"--".mangleof == "??FTestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opUnary!"-".mangleof == "??GTestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opUnary!"+".mangleof == "??HTestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opUnary!"~".mangleof == "??STestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opBinary!">>".mangleof == "??5TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"<<".mangleof == "??6TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"*".mangleof == "??DTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"-".mangleof == "??GTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"+".mangleof == "??HTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"&".mangleof == "??ITestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"/".mangleof == "??KTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"%".mangleof == "??LTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"^".mangleof == "??TTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opBinary!"|".mangleof == "??UTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"*".mangleof == "??XTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"+".mangleof == "??YTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"-".mangleof == "??ZTestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"/".mangleof == "??_0TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"%".mangleof == "??_1TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!">>".mangleof == "??_2TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"<<".mangleof == "??_3TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"&".mangleof == "??_4TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"|".mangleof == "??_5TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"^".mangleof == "??_6TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opCast!int.mangleof == "??BTestOperators@@QAEHXZ");
|
||||
static assert(TestOperators.opAssign.mangleof == "??4TestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opEquals.mangleof == "??8TestOperators@@QAE_NH@Z");
|
||||
static assert(TestOperators.opIndex.mangleof == "??ATestOperators@@QAEHH@Z");
|
||||
static assert(TestOperators.opCall.mangleof == "??RTestOperators@@QAEHHM@Z");
|
||||
}
|
||||
version (Win64)
|
||||
{
|
||||
static assert(TestOperators.opUnary!"*".mangleof == "??DTestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opUnary!"++".mangleof == "??ETestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opUnary!"--".mangleof == "??FTestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opUnary!"-".mangleof == "??GTestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opUnary!"+".mangleof == "??HTestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opUnary!"~".mangleof == "??STestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opBinary!">>".mangleof == "??5TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"<<".mangleof == "??6TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"*".mangleof == "??DTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"-".mangleof == "??GTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"+".mangleof == "??HTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"&".mangleof == "??ITestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"/".mangleof == "??KTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"%".mangleof == "??LTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"^".mangleof == "??TTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opBinary!"|".mangleof == "??UTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"*".mangleof == "??XTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"+".mangleof == "??YTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"-".mangleof == "??ZTestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"/".mangleof == "??_0TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"%".mangleof == "??_1TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!">>".mangleof == "??_2TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"<<".mangleof == "??_3TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"&".mangleof == "??_4TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"|".mangleof == "??_5TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opOpAssign!"^".mangleof == "??_6TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opCast!int.mangleof == "??BTestOperators@@QEAAHXZ");
|
||||
static assert(TestOperators.opAssign.mangleof == "??4TestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opEquals.mangleof == "??8TestOperators@@QEAA_NH@Z");
|
||||
static assert(TestOperators.opIndex.mangleof == "??ATestOperators@@QEAAHH@Z");
|
||||
static assert(TestOperators.opCall.mangleof == "??RTestOperators@@QEAAHHM@Z");
|
||||
}
|
||||
}
|
||||
|
||||
import cppmangle2;
|
||||
@ -839,14 +863,14 @@ extern(C++, `Namespace18922`)
|
||||
void func18922_3(Struct18922) {}
|
||||
}
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(func18922.mangleof == "_ZN14Namespace189229func18922ENS_11Struct18922E");
|
||||
static assert(func18922_1.mangleof == "_ZN14Namespace1892211func18922_1ENS_11Struct18922E");
|
||||
static assert(func18922_2.mangleof == "_ZN14Namespace1892211func18922_2ENS_11Struct18922E");
|
||||
static assert(func18922_3.mangleof == "_ZN14Namespace1892211func18922_3ENS_11Struct18922E");
|
||||
}
|
||||
else version(Windows)
|
||||
else version (CppMangle_MSVC)
|
||||
{
|
||||
static assert(func18922.mangleof == "?func18922@Namespace18922@@YAXUStruct18922@1@@Z");
|
||||
static assert(func18922_1.mangleof == "?func18922_1@Namespace18922@@YAXUStruct18922@1@@Z");
|
||||
@ -858,7 +882,7 @@ else version(Windows)
|
||||
// https://issues.dlang.org/show_bug.cgi?id=18957
|
||||
// extern(C++) doesn't mangle 'std' correctly on posix systems
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
// https://godbolt.org/z/C5T2LQ
|
||||
/+
|
||||
@ -881,7 +905,7 @@ extern(C++) struct test19043(T) {}
|
||||
|
||||
extern(C++) void test19043a(test19043!(const(char)) a) {}
|
||||
extern(C++) void test19043b(T)(T a) {}
|
||||
version(Windows)
|
||||
version (CppMangle_MSVC)
|
||||
{
|
||||
static assert(test19043a.mangleof == "?test19043a@@YAXU?$test19043@$$CBD@@@Z");
|
||||
static assert(test19043b!(test19043!(const(char))).mangleof ==
|
||||
@ -890,7 +914,7 @@ version(Windows)
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=16479
|
||||
// Missing substitution while mangling C++ template parameter for functions
|
||||
version (Posix) extern (C++)
|
||||
version (CppMangle_Itanium) extern (C++)
|
||||
{
|
||||
// Make sure aliases are still resolved
|
||||
alias Alias16479 = int;
|
||||
@ -1084,15 +1108,18 @@ extern(C++, (AliasSeq!(Tup, "yay")))
|
||||
{
|
||||
void test19278_4();
|
||||
}
|
||||
version(Win64)
|
||||
version (CppMangle_MSVC)
|
||||
{
|
||||
static assert(test19278.mangleof == "?test19278@helloworld@@YAXXZ");
|
||||
static assert(test19278_2.mangleof == "?test19278_2@lookup@@YAXXZ");
|
||||
static assert(test19278_3.mangleof == "?test19278_3@world@hello@@YAXXZ");
|
||||
static assert(test19278_4.mangleof == "?test19278_4@yay@world@hello@@YAXXZ");
|
||||
static assert(test19278_var.mangleof == "?test19278_var@world@hello@@3_KA");
|
||||
version (Win64)
|
||||
{
|
||||
static assert(test19278.mangleof == "?test19278@helloworld@@YAXXZ");
|
||||
static assert(test19278_2.mangleof == "?test19278_2@lookup@@YAXXZ");
|
||||
static assert(test19278_3.mangleof == "?test19278_3@world@hello@@YAXXZ");
|
||||
static assert(test19278_4.mangleof == "?test19278_4@yay@world@hello@@YAXXZ");
|
||||
static assert(test19278_var.mangleof == "?test19278_var@world@hello@@3_KA");
|
||||
}
|
||||
}
|
||||
else version(Posix)
|
||||
else version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(test19278.mangleof == "_ZN10helloworld9test19278Ev");
|
||||
static assert(test19278_2.mangleof == "_ZN6lookup11test19278_2Ev");
|
||||
@ -1105,23 +1132,26 @@ else version(Posix)
|
||||
// https://issues.dlang.org/show_bug.cgi?id=18958
|
||||
// Issue 18958 - extern(C++) wchar, dchar mangling not correct
|
||||
|
||||
version(Posix)
|
||||
version (Posix)
|
||||
enum __c_wchar_t : dchar;
|
||||
else version(Windows)
|
||||
else version (Windows)
|
||||
enum __c_wchar_t : wchar;
|
||||
alias wchar_t = __c_wchar_t;
|
||||
extern (C++) void test_char_mangling(char, wchar, dchar, wchar_t);
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(test_char_mangling.mangleof == "_Z18test_char_manglingcDsDiw");
|
||||
}
|
||||
version (Win64)
|
||||
version (CppMangle_MSVC)
|
||||
{
|
||||
static assert(test_char_mangling.mangleof == "?test_char_mangling@@YAXD_S_U_W@Z");
|
||||
version (Win64)
|
||||
{
|
||||
static assert(test_char_mangling.mangleof == "?test_char_mangling@@YAXD_S_U_W@Z");
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/dlang/dmd/pull/10021/files#r294055424
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
extern(C++, PR10021_NS) struct PR10021_Struct(T){}
|
||||
extern(C++) void PR10021_fun(int i)(PR10021_Struct!int);
|
||||
@ -1129,7 +1159,7 @@ version (Posix)
|
||||
}
|
||||
|
||||
// https://github.com/dlang/dmd/pull/10021#discussion_r294095749
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
extern(C++, "a", "b")
|
||||
struct PR10021_Struct2
|
||||
@ -1142,7 +1172,7 @@ version (Posix)
|
||||
}
|
||||
|
||||
/// https://issues.dlang.org/show_bug.cgi?id=20022
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
extern(C++, `ns20022`) enum Enum20022_1 { A = 1, }
|
||||
extern(C++) void fun20022_1(Enum20022_1);
|
||||
@ -1167,7 +1197,7 @@ version (Posix)
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=20094
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
extern(C++, "ns20094")
|
||||
{
|
||||
@ -1180,7 +1210,7 @@ version (Posix)
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=20223
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
extern(C++)
|
||||
{
|
||||
@ -1206,7 +1236,7 @@ version (Posix)
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=20224
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
extern(C++) public int test20224_1(T)(set20224!T set); // ok
|
||||
extern(C++) public int test20224_2(T)(ref set20224!T set); // segfault
|
||||
@ -1228,7 +1258,7 @@ version (Posix)
|
||||
|
||||
/**************************************/
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
extern (C++) struct Loc2 {};
|
||||
extern (C++) class FuncDeclaration
|
||||
@ -1251,7 +1281,7 @@ extern(C++, `bar`)
|
||||
// https://issues.dlang.org/show_bug.cgi?id=20700
|
||||
// Only testing on WIn64 because the mangling includes 'E',
|
||||
// and the bug can be tested on either platform
|
||||
version (Win64) extern(C++)
|
||||
version (CppMangle_MSVC) version (Win64) extern(C++)
|
||||
{
|
||||
void test20700_1(Struct20700);
|
||||
extern(C++, class) struct Struct20700 {}
|
||||
@ -1285,12 +1315,15 @@ extern (C++)
|
||||
alias fpcpp = noreturn function();
|
||||
int funccpp(fpcpp);
|
||||
|
||||
version (Posix)
|
||||
version (CppMangle_Itanium)
|
||||
static assert(funccpp.mangleof == "_Z7funccppPFvvE");
|
||||
|
||||
version (Win32)
|
||||
static assert(funccpp.mangleof == "?funccpp@@YAHP6AXXZ@Z");
|
||||
version (CppMangle_MSVC)
|
||||
{
|
||||
version (Win32)
|
||||
static assert(funccpp.mangleof == "?funccpp@@YAHP6AXXZ@Z");
|
||||
|
||||
version (Win64)
|
||||
static assert(funccpp.mangleof == "?funccpp@@YAHP6AXXZ@Z");
|
||||
version (Win64)
|
||||
static assert(funccpp.mangleof == "?funccpp@@YAHP6AXXZ@Z");
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,11 @@
|
||||
// https://issues.dlang.org/show_bug.cgi?id=19920
|
||||
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;
|
||||
|
||||
extern(C++, "true")
|
||||
{
|
||||
@ -23,8 +28,8 @@ extern(C++, "std", "chrono")
|
||||
void func();
|
||||
}
|
||||
|
||||
version(Windows) static assert(func.mangleof == "?func@chrono@std@@YAXXZ");
|
||||
else static assert(func.mangleof == "_ZNSt6chrono4funcEv");
|
||||
version(CppMangle_MSVC) static assert(func.mangleof == "?func@chrono@std@@YAXXZ");
|
||||
else static assert(func.mangleof == "_ZNSt6chrono4funcEv");
|
||||
|
||||
struct Foo
|
||||
{
|
||||
|
210
gcc/testsuite/gdc.test/compilable/issue21203.d
Normal file
210
gcc/testsuite/gdc.test/compilable/issue21203.d
Normal file
@ -0,0 +1,210 @@
|
||||
version (CppRuntime_Clang) version = CppMangle_Itanium;
|
||||
version (CppRuntime_Gcc) version = CppMangle_Itanium;
|
||||
version (CppRuntime_Sun) version = CppMangle_Itanium;
|
||||
|
||||
template ScopeClass(C , string name = C.stringof)
|
||||
//if (is(C == class) && __traits(getLinkage, C) == "C++")
|
||||
{
|
||||
//enum name = C.stringof;
|
||||
enum ns = __traits(getCppNamespaces,C);
|
||||
extern(C++, class)
|
||||
{
|
||||
extern(C++,(ns))
|
||||
{
|
||||
pragma(mangle, C, name)
|
||||
struct ScopeClass
|
||||
{
|
||||
char[__traits(classInstanceSize, C)] buffer;
|
||||
//... all the things ...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Basic tests
|
||||
extern(C++)
|
||||
{
|
||||
class MyClassA {}
|
||||
void funa(ScopeClass!MyClassA); // mangles MyClass
|
||||
void funb(const ScopeClass!MyClassA); // mangles const MyClass
|
||||
void func(ref ScopeClass!MyClassA); // mangles MyClass&
|
||||
void fund(ref const ScopeClass!MyClassA); // mangles const MyClass&
|
||||
void fune(const(ScopeClass!MyClassA)*);
|
||||
}
|
||||
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(funa.mangleof == "_Z4funa8MyClassA");
|
||||
static assert(funb.mangleof == "_Z4funb8MyClassA");
|
||||
static assert(func.mangleof == "_Z4funcR8MyClassA");
|
||||
static assert(fund.mangleof == "_Z4fundRK8MyClassA");
|
||||
static assert(fune.mangleof == "_Z4funePK8MyClassA");
|
||||
}
|
||||
else version (CppRuntime_Microsoft)
|
||||
{
|
||||
static assert(funa.mangleof == "?funa@@YAXVMyClassA@@@Z");
|
||||
static assert(funb.mangleof == "?funb@@YAXVMyClassA@@@Z");
|
||||
static if (size_t.sizeof == ulong.sizeof)
|
||||
{
|
||||
static assert(func.mangleof == "?func@@YAXAEAVMyClassA@@@Z");
|
||||
static assert(fund.mangleof == "?fund@@YAXAEBVMyClassA@@@Z");
|
||||
static assert(fune.mangleof == "?fune@@YAXPEBVMyClassA@@@Z");
|
||||
}
|
||||
else
|
||||
{
|
||||
static assert(func.mangleof == "?func@@YAXAAVMyClassA@@@Z");
|
||||
static assert(fund.mangleof == "?fund@@YAXABVMyClassA@@@Z");
|
||||
static assert(fune.mangleof == "?fune@@YAXPBVMyClassA@@@Z");
|
||||
}
|
||||
}
|
||||
|
||||
//Basic tests with a namespace
|
||||
extern(C++, "ns")
|
||||
{
|
||||
class MyClassB {}
|
||||
void funf(ScopeClass!MyClassB); // mangles MyClass
|
||||
void fung(const ScopeClass!MyClassB); // mangles const MyClass
|
||||
void funh(ref ScopeClass!MyClassB); // mangles MyClass&
|
||||
void funi(ref const ScopeClass!MyClassB); // mangles const MyClass&
|
||||
void funj(const(ScopeClass!MyClassB)*);
|
||||
}
|
||||
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(funf.mangleof == "_ZN2ns4funfENS_8MyClassBE");
|
||||
static assert(fung.mangleof == "_ZN2ns4fungENS_8MyClassBE");
|
||||
static assert(funh.mangleof == "_ZN2ns4funhERNS_8MyClassBE");
|
||||
static assert(funi.mangleof == "_ZN2ns4funiERKNS_8MyClassBE");
|
||||
static assert(funj.mangleof == "_ZN2ns4funjEPKNS_8MyClassBE");
|
||||
}
|
||||
else version (CppRuntime_Microsoft)
|
||||
{
|
||||
static assert(funf.mangleof == "?funf@ns@@YAXVMyClassB@1@@Z");
|
||||
static assert(fung.mangleof == "?fung@ns@@YAXVMyClassB@1@@Z");
|
||||
static if (size_t.sizeof == ulong.sizeof)
|
||||
{
|
||||
static assert(funh.mangleof == "?funh@ns@@YAXAEAVMyClassB@1@@Z");
|
||||
static assert(funi.mangleof == "?funi@ns@@YAXAEBVMyClassB@1@@Z");
|
||||
static assert(funj.mangleof == "?funj@ns@@YAXPEBVMyClassB@1@@Z");
|
||||
}
|
||||
else
|
||||
{
|
||||
static assert(funh.mangleof == "?funh@ns@@YAXAAVMyClassB@1@@Z");
|
||||
static assert(funi.mangleof == "?funi@ns@@YAXABVMyClassB@1@@Z");
|
||||
static assert(funj.mangleof == "?funj@ns@@YAXPBVMyClassB@1@@Z");
|
||||
}
|
||||
}
|
||||
|
||||
//Templates
|
||||
extern(C++)
|
||||
{
|
||||
void funTempl(T)();
|
||||
class MyClassC {}
|
||||
alias funTemplA = funTempl!(ScopeClass!MyClassC);
|
||||
alias funTemplB = funTempl!(const ScopeClass!MyClassC);
|
||||
alias funTemplC = funTempl!(const(ScopeClass!MyClassC)*);
|
||||
// N.B funTempl!([const] ref ScopeClass!MyClassC) is not permissable in D
|
||||
}
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(funTemplA.mangleof == "_Z8funTemplI8MyClassCEvv");
|
||||
static assert(funTemplB.mangleof == "_Z8funTemplIK8MyClassCEvv");
|
||||
static assert(funTemplC.mangleof == "_Z8funTemplIPK8MyClassCEvv");
|
||||
}
|
||||
else version (CppRuntime_Microsoft)
|
||||
{
|
||||
static assert(funTemplA.mangleof == "??$funTempl@VMyClassC@@@@YAXXZ");
|
||||
static assert(funTemplB.mangleof == "??$funTempl@$$CBVMyClassC@@@@YAXXZ");
|
||||
static if (size_t.sizeof == ulong.sizeof)
|
||||
static assert(funTemplC.mangleof == "??$funTempl@PEBVMyClassC@@@@YAXXZ");
|
||||
else
|
||||
static assert(funTemplC.mangleof == "??$funTempl@PBVMyClassC@@@@YAXXZ");
|
||||
}
|
||||
|
||||
template _function(F)
|
||||
{
|
||||
extern(C++, "std")
|
||||
{
|
||||
extern(C++, struct)
|
||||
pragma(mangle, "function")
|
||||
class _function
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
template FunctionOf(F)
|
||||
{
|
||||
F f;
|
||||
alias FunctionOf = typeof(*f);
|
||||
}
|
||||
extern(C++) void funk(ScopeClass!(_function!(FunctionOf!(void function(int))),"function") a ){ }
|
||||
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(funk.mangleof == "_Z4funkSt8functionIFviEE");
|
||||
}
|
||||
else version (CppRuntime_Microsoft)
|
||||
{
|
||||
static assert(funk.mangleof == "?funk@@YAXV?$function@$$A6AXH@Z@std@@@Z");
|
||||
}
|
||||
|
||||
extern(C++, "ns")
|
||||
{
|
||||
pragma(mangle, "function")
|
||||
class _function2
|
||||
{
|
||||
public final void test();
|
||||
}
|
||||
}
|
||||
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(_function2.test.mangleof == "_ZN2ns8function4testEv");
|
||||
}
|
||||
else version (CppRuntime_Microsoft)
|
||||
{
|
||||
static if (size_t.sizeof == ulong.sizeof)
|
||||
static assert(_function2.test.mangleof == "?test@function@ns@@QEAAXXZ");
|
||||
else
|
||||
static assert(_function2.test.mangleof == "?test@function@ns@@QAEXXZ");
|
||||
}
|
||||
|
||||
extern(C++, "ns")
|
||||
{
|
||||
template _function3(T)
|
||||
{
|
||||
pragma(mangle, _function3, "function")
|
||||
class _function3
|
||||
{
|
||||
public final void test();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(_function3!(int).test.mangleof == "_ZN2ns8functionIiE4testEv");
|
||||
}
|
||||
else version (CppRuntime_Microsoft)
|
||||
{
|
||||
static if (size_t.sizeof == ulong.sizeof)
|
||||
static assert(_function3!(int).test.mangleof == "?test@?$function@H@ns@@QEAAXXZ");
|
||||
else
|
||||
static assert(_function3!(int).test.mangleof == "?test@?$function@H@ns@@QAEXXZ");
|
||||
}
|
||||
|
||||
extern(C++)
|
||||
{
|
||||
struct Foo {}
|
||||
pragma(mangle, Foo) struct Foo_Doppelganger {}
|
||||
|
||||
void funl(Foo_Doppelganger f);
|
||||
}
|
||||
version (CppMangle_Itanium)
|
||||
{
|
||||
static assert(funl.mangleof == "_Z4funl3Foo");
|
||||
}
|
||||
else version (CppRuntime_Microsoft)
|
||||
{
|
||||
static assert(funl.mangleof == "?funl@@YAXUFoo@@@Z");
|
||||
}
|
38
gcc/testsuite/gdc.test/compilable/issue21340.d
Normal file
38
gcc/testsuite/gdc.test/compilable/issue21340.d
Normal file
@ -0,0 +1,38 @@
|
||||
version (CppRuntime_Clang) version = CppMangle_Itanium;
|
||||
version (CppRuntime_Gcc) version = CppMangle_Itanium;
|
||||
version (CppRuntime_Sun) version = CppMangle_Itanium;
|
||||
|
||||
template ScopeClass(C)
|
||||
if (is(C == class) && __traits(getLinkage, C) == "C++")
|
||||
{
|
||||
|
||||
extern(C++, class)
|
||||
extern(C++, __traits(getCppNamespaces,C))
|
||||
extern(C++, (ns))
|
||||
class ScopeClass { }
|
||||
}
|
||||
extern(C++) class Foo {}
|
||||
extern(C++) void test(ScopeClass!Foo)
|
||||
{
|
||||
}
|
||||
version(CppMangle_Itanium)
|
||||
{
|
||||
static assert (test.mangleof == "_Z4testP10ScopeClassIP3FooE");
|
||||
}
|
||||
else version (CppRuntime_Microsoft)
|
||||
{
|
||||
version (Win32)
|
||||
{
|
||||
static assert (test.mangleof == "?test@@YAXPAV?$ScopeClass@PAVFoo@@@@@Z");
|
||||
}
|
||||
version (Win64)
|
||||
{
|
||||
static assert (test.mangleof == "?test@@YAXPEAV?$ScopeClass@PEAVFoo@@@@@Z");
|
||||
}
|
||||
}
|
||||
alias AliasSeq(T...) = T;
|
||||
alias ns = AliasSeq!();
|
||||
immutable ns2 = AliasSeq!();
|
||||
extern(C++,(ns)) class Bar {}
|
||||
extern(C++,) class Baz {}
|
||||
extern(C++, (ns2)) class Quux {}
|
7
gcc/testsuite/gdc.test/compilable/test10028.d
Normal file
7
gcc/testsuite/gdc.test/compilable/test10028.d
Normal file
@ -0,0 +1,7 @@
|
||||
enum E:char[4]{ str = "abcd" }
|
||||
enum x = {
|
||||
int[char[4]] aa;
|
||||
aa[E.str] = 1;
|
||||
foreach(key,val; aa) {}
|
||||
return aa["abcd"];
|
||||
}();
|
22
gcc/testsuite/gdc.test/compilable/test20236.d
Normal file
22
gcc/testsuite/gdc.test/compilable/test20236.d
Normal file
@ -0,0 +1,22 @@
|
||||
// https://issues.dlang.org/show_bug.cgi?id=20236
|
||||
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
---
|
||||
*/
|
||||
|
||||
struct X
|
||||
{
|
||||
alias y this;
|
||||
deprecated int y() { return 5; }
|
||||
int x() { return 5; }
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
static void func(int) {}
|
||||
with(X.init) {
|
||||
func(x);
|
||||
}
|
||||
}
|
16
gcc/testsuite/gdc.test/compilable/test20860.d
Normal file
16
gcc/testsuite/gdc.test/compilable/test20860.d
Normal file
@ -0,0 +1,16 @@
|
||||
// https://issues.dlang.org/show_bug.cgi?id=20860
|
||||
|
||||
struct A
|
||||
{
|
||||
this(int a) {}
|
||||
///
|
||||
void opDispatch(string methodName, Params...)(Params params) {
|
||||
}
|
||||
|
||||
~this() {}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
A(3).test();
|
||||
}
|
16
gcc/testsuite/gdc.test/compilable/test21073.d
Normal file
16
gcc/testsuite/gdc.test/compilable/test21073.d
Normal file
@ -0,0 +1,16 @@
|
||||
// https://issues.dlang.org/show_bug.cgi?id=21073
|
||||
|
||||
class C
|
||||
{
|
||||
auto internal() const
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
alias internal this;
|
||||
}
|
||||
|
||||
void main() pure
|
||||
{
|
||||
const c = new C;
|
||||
auto r = cast(C)c;
|
||||
}
|
13
gcc/testsuite/gdc.test/compilable/test21414.d
Normal file
13
gcc/testsuite/gdc.test/compilable/test21414.d
Normal file
@ -0,0 +1,13 @@
|
||||
// https://issues.dlang.org/show_bug.cgi?id=21414
|
||||
|
||||
struct State
|
||||
{
|
||||
string s;
|
||||
|
||||
immutable this(string s)
|
||||
{
|
||||
this.s = s;
|
||||
}
|
||||
}
|
||||
|
||||
immutable rootState = new immutable State("b");
|
@ -1,6 +1,6 @@
|
||||
/* TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/b15875.d(9): Error: circular reference to variable `a`
|
||||
fail_compilation/b15875.d(9): Error: undefined identifier `a`
|
||||
fail_compilation/b15875.d(10): Error: circular reference to `b15875.f`
|
||||
---
|
||||
*/
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail116.d(11): Error: circular `typeof` definition
|
||||
fail_compilation/fail116.d(11): Error: undefined identifier `x`
|
||||
fail_compilation/fail116.d(16): Error: template instance `square!1.2` does not match template declaration `square(_error_ x)`
|
||||
---
|
||||
*/
|
||||
|
26
gcc/testsuite/gdc.test/fail_compilation/fail20616.d
Normal file
26
gcc/testsuite/gdc.test/fail_compilation/fail20616.d
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail20616.d(16): Error: undefined identifier `$`
|
||||
fail_compilation/fail20616.d(16): Aggregate declaration 'X()' does not define 'opDollar'
|
||||
fail_compilation/fail20616.d(18): Error: undefined identifier `$`
|
||||
fail_compilation/fail20616.d(18): Aggregate declaration 'b' does not define 'opDollar'
|
||||
---
|
||||
*/
|
||||
module fail20616;
|
||||
|
||||
void g() {
|
||||
struct X {
|
||||
auto opSlice(size_t a, size_t b) { return ""; }
|
||||
}
|
||||
auto x = X()[0 .. $];
|
||||
auto b = X();
|
||||
auto c = b[0 .. $ - 1];
|
||||
auto v = [1, 2, 3];
|
||||
auto d = v[$.. $];
|
||||
}
|
||||
|
||||
int main() {
|
||||
g();
|
||||
return 0;
|
||||
}
|
14
gcc/testsuite/gdc.test/fail_compilation/fail22529.d
Normal file
14
gcc/testsuite/gdc.test/fail_compilation/fail22529.d
Normal file
@ -0,0 +1,14 @@
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22529
|
||||
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail22529.d(13): Error: found `return` when expecting `;` following statement
|
||||
---
|
||||
*/
|
||||
|
||||
void main()
|
||||
{
|
||||
foo()
|
||||
return;
|
||||
}
|
21
gcc/testsuite/gdc.test/fail_compilation/fail22570.d
Normal file
21
gcc/testsuite/gdc.test/fail_compilation/fail22570.d
Normal file
@ -0,0 +1,21 @@
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22570
|
||||
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail22570.d(19): Error: more initializers than fields (1) of `S`
|
||||
fail_compilation/fail22570.d(20): Error: more initializers than fields (1) of `S`
|
||||
---
|
||||
*/
|
||||
|
||||
struct S
|
||||
{
|
||||
Object o1;
|
||||
}
|
||||
|
||||
void main() @safe
|
||||
{
|
||||
S[] s;
|
||||
s = [S(null, null)];
|
||||
s ~= S(null, null);
|
||||
}
|
21
gcc/testsuite/gdc.test/fail_compilation/ice22516.d
Normal file
21
gcc/testsuite/gdc.test/fail_compilation/ice22516.d
Normal file
@ -0,0 +1,21 @@
|
||||
/++
|
||||
https://issues.dlang.org/show_bug.cgi?id=22516
|
||||
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/ice22516.d(18): Error: undefined identifier `X`
|
||||
---
|
||||
+/
|
||||
|
||||
struct Data
|
||||
{
|
||||
void function() eval;
|
||||
|
||||
}
|
||||
|
||||
struct Builtins
|
||||
{
|
||||
X x;
|
||||
|
||||
Data myData = { (){} };
|
||||
}
|
12
gcc/testsuite/gdc.test/fail_compilation/test22574.d
Normal file
12
gcc/testsuite/gdc.test/fail_compilation/test22574.d
Normal file
@ -0,0 +1,12 @@
|
||||
//https://issues.dlang.org/show_bug.cgi?id=22574
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test22574.d(100): Error: undefined identifier `x`
|
||||
---
|
||||
*/
|
||||
#line 100
|
||||
template test(x* x)
|
||||
{
|
||||
|
||||
}
|
101
gcc/testsuite/gdc.test/fail_compilation/test_switch_error.d
Normal file
101
gcc/testsuite/gdc.test/fail_compilation/test_switch_error.d
Normal file
@ -0,0 +1,101 @@
|
||||
/++
|
||||
https://issues.dlang.org/show_bug.cgi?id=22514
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test_switch_error.d(13): Error: undefined identifier `doesNotExist`
|
||||
fail_compilation/test_switch_error.d(16): Error: undefined identifier `alsoDoesNotExits`
|
||||
fail_compilation/test_switch_error.d(19): Error: duplicate `case 2` in `switch` statement
|
||||
---
|
||||
++/
|
||||
|
||||
void test1()
|
||||
{
|
||||
switch (doesNotExist)
|
||||
{
|
||||
case 1:
|
||||
alsoDoesNotExits();
|
||||
break;
|
||||
case 2: break;
|
||||
case 2: break;
|
||||
}
|
||||
}
|
||||
|
||||
/++
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test_switch_error.d(105): Error: undefined identifier `doesNotExist`
|
||||
---
|
||||
++/
|
||||
#line 100
|
||||
|
||||
enum foo = 1;
|
||||
|
||||
void test2()
|
||||
{
|
||||
switch (doesNotExist)
|
||||
{
|
||||
case foo: break;
|
||||
}
|
||||
}
|
||||
|
||||
/++
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test_switch_error.d(206): Error: undefined identifier `a`
|
||||
fail_compilation/test_switch_error.d(207): Error: undefined identifier `b`
|
||||
---
|
||||
++/
|
||||
#line 200
|
||||
|
||||
void test3()
|
||||
{
|
||||
|
||||
switch (1)
|
||||
{
|
||||
case a: break;
|
||||
case b: break;
|
||||
}
|
||||
}
|
||||
|
||||
/++
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test_switch_error.d(303): Error: undefined identifier `doesNotExits`
|
||||
---
|
||||
++/
|
||||
#line 300
|
||||
|
||||
void test4()
|
||||
{
|
||||
auto foo = doesNotExits();
|
||||
switch (1)
|
||||
{
|
||||
case foo: break;
|
||||
case foo: break;
|
||||
}
|
||||
}
|
||||
|
||||
/++
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test_switch_error.d(405): Error: `case` variables have to be `const` or `immutable`
|
||||
fail_compilation/test_switch_error.d(412): Error: `case` variables not allowed in `final switch` statements
|
||||
---
|
||||
++/
|
||||
#line 400
|
||||
|
||||
void test5(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case i: break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
const int j = i;
|
||||
final switch (i)
|
||||
{
|
||||
case j: break;
|
||||
|
||||
}
|
||||
}
|
@ -3660,6 +3660,28 @@ void test20133()
|
||||
auto rtest2 = fun20133_2();
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22530
|
||||
|
||||
class D22530 { }
|
||||
|
||||
class C22530
|
||||
{
|
||||
D22530 y = new D22530;
|
||||
alias y this;
|
||||
}
|
||||
|
||||
void test22530()
|
||||
{
|
||||
// fixed
|
||||
static assert(cast(D22530)(new C22530) is null);
|
||||
static assert((1 ? cast(D22530)(new C22530) : new D22530) is null);
|
||||
|
||||
// runtime version already works
|
||||
assert(cast(D22530)(new C22530) is null);
|
||||
assert((1 ? cast(D22530)(new C22530) : new D22530) is null);
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
|
||||
int main()
|
||||
@ -3789,6 +3811,7 @@ int main()
|
||||
test20400();
|
||||
test21878();
|
||||
test20133();
|
||||
test22530();
|
||||
|
||||
printf("Success\n");
|
||||
return 0;
|
||||
|
57
gcc/testsuite/gdc.test/runnable/test16579.d
Normal file
57
gcc/testsuite/gdc.test/runnable/test16579.d
Normal file
@ -0,0 +1,57 @@
|
||||
// REQUIRED_ARGS: -unittest
|
||||
// PERMUTE_ARGS:
|
||||
// https://issues.dlang.org/show_bug.cgi?id=16579
|
||||
|
||||
struct Thing
|
||||
{
|
||||
enum Instance = Thing();
|
||||
int a = 42;
|
||||
|
||||
void iter()
|
||||
{
|
||||
assert(this.a == 42);
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
return Thing.Instance.iter; // Added 'return'
|
||||
}
|
||||
|
||||
// From https://issues.dlang.org/show_bug.cgi?id=16576
|
||||
|
||||
alias a = test2!();
|
||||
alias b = test3!();
|
||||
|
||||
|
||||
template test2()
|
||||
{
|
||||
struct Thing{
|
||||
static enum Instance = Thing([0, 1, 2, 3]);
|
||||
int[] array;
|
||||
void iter(in string str) const{
|
||||
foreach(j, tup; this.array) assert(tup == j);
|
||||
assert(this.array && this.array.length == 4);
|
||||
}
|
||||
}
|
||||
unittest{
|
||||
auto test(in string str){return Thing.Instance.iter(str);}
|
||||
test("?");
|
||||
}
|
||||
}
|
||||
|
||||
template test3()
|
||||
{
|
||||
struct Thing{
|
||||
static enum Instance = Thing([0, 1, 2, 3]);
|
||||
int[] array;
|
||||
void iter() const{
|
||||
foreach(j, tup; this.array) assert(tup == j);
|
||||
assert(this.array && this.array.length == 4);
|
||||
}
|
||||
}
|
||||
unittest{
|
||||
auto test(){return Thing.Instance.iter();}
|
||||
test();
|
||||
}
|
||||
}
|
41
gcc/testsuite/gdc.test/runnable/test18054.d
Normal file
41
gcc/testsuite/gdc.test/runnable/test18054.d
Normal file
@ -0,0 +1,41 @@
|
||||
/+
|
||||
REQUIRED_ARGS: -d
|
||||
RUN_OUTPUT:
|
||||
---
|
||||
float: 1 == 1
|
||||
double: 1 == 1
|
||||
real: 1 == 1
|
||||
ifloat: 1 == 1
|
||||
idouble: 1 == 1
|
||||
ireal: 1 == 1
|
||||
cfloat: 1 == 1
|
||||
cdouble: 1 == 1
|
||||
creal: 1 == 1
|
||||
---
|
||||
+/
|
||||
|
||||
import core.stdc.stdio : printf;
|
||||
|
||||
void test(T, string lit)()
|
||||
{
|
||||
T d = mixin(lit);
|
||||
bool runtime = cast(bool) d;
|
||||
bool folded = cast(bool) mixin(lit);
|
||||
|
||||
printf((T.stringof ~ ": %d == %d\n\0").ptr, runtime, folded);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
test!(float, "0.5f");
|
||||
test!(double, "0.5" );
|
||||
test!(real, "0.5L");
|
||||
|
||||
test!(ifloat, "0.5i");
|
||||
test!(idouble, "0.5i");
|
||||
test!(ireal, "0.5i");
|
||||
|
||||
test!(cfloat, "0.3 + 0.5i");
|
||||
test!(cdouble, "0.3 + 0.5i");
|
||||
test!(creal, "0.3 + 0.5i");
|
||||
}
|
@ -442,28 +442,54 @@ void test13161()
|
||||
|
||||
version (linux)
|
||||
{
|
||||
extern(C++, __gnu_cxx)
|
||||
static if (__traits(getTargetInfo, "cppStd") < 201703)
|
||||
{
|
||||
struct new_allocator(T)
|
||||
// See note on std::allocator below.
|
||||
extern(C++, __gnu_cxx)
|
||||
{
|
||||
alias size_type = size_t;
|
||||
static if (is(T : char))
|
||||
void deallocate(T*, size_type) { }
|
||||
else
|
||||
void deallocate(T*, size_type);
|
||||
struct new_allocator(T)
|
||||
{
|
||||
alias size_type = size_t;
|
||||
static if (is(T : char))
|
||||
void deallocate(T*, size_type) { }
|
||||
else
|
||||
void deallocate(T*, size_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern (C++, std)
|
||||
{
|
||||
version (linux)
|
||||
{
|
||||
static if (__traits(getTargetInfo, "cppStd") >= 201703)
|
||||
{
|
||||
// std::allocator no longer derives from __gnu_cxx::new_allocator,
|
||||
// it derives from std::__new_allocator instead.
|
||||
struct __new_allocator(T)
|
||||
{
|
||||
alias size_type = size_t;
|
||||
static if (is(T : char))
|
||||
void deallocate(T*, size_type) { }
|
||||
else
|
||||
void deallocate(T*, size_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern (C++, class) struct allocator(T)
|
||||
{
|
||||
version (linux)
|
||||
{
|
||||
alias size_type = size_t;
|
||||
void deallocate(T* p, size_type sz)
|
||||
{ (cast(__gnu_cxx.new_allocator!T*)&this).deallocate(p, sz); }
|
||||
{
|
||||
static if (__traits(getTargetInfo, "cppStd") >= 201703)
|
||||
(cast(std.__new_allocator!T*)&this).deallocate(p, sz);
|
||||
else
|
||||
(cast(__gnu_cxx.new_allocator!T*)&this).deallocate(p, sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -476,12 +502,21 @@ extern (C++, std)
|
||||
{
|
||||
}
|
||||
|
||||
// https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
|
||||
version (none)
|
||||
version (CppRuntime_Gcc)
|
||||
{
|
||||
extern (C++, __cxx11)
|
||||
// https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
|
||||
static if (__traits(getTargetInfo, "cppStd") >= 201103)
|
||||
{
|
||||
struct basic_string(T, C = char_traits!T, A = allocator!T)
|
||||
extern (C++, __cxx11)
|
||||
{
|
||||
struct basic_string(T, C = char_traits!T, A = allocator!T)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
extern (C++, class) struct basic_string(T, C = char_traits!T, A = allocator!T)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,3 @@
|
||||
/*
|
||||
GCC 5.1 introduced new implementations of std::string and std::list:
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
|
||||
|
||||
This causes e.g. std::string to be actually defined as
|
||||
std::__cxx11::string.
|
||||
|
||||
On machines with GCC 5.1, this manifests as a linker error when
|
||||
running the cppa.d / cppb.cpp test:
|
||||
|
||||
cppa.o: In function `_D4cppa6test14FZv':
|
||||
cppa.d:(.text._D4cppa6test14FZv+0x11): undefined reference to `foo14a(std::string*)'
|
||||
cppa.d:(.text._D4cppa6test14FZv+0x18): undefined reference to `foo14b(std::basic_string<int, std::char_traits<int>, std::allocator<int> >*)'
|
||||
cppa.d:(.text._D4cppa6test14FZv+0x3a): undefined reference to `foo14f(std::char_traits<char>*, std::string*, std::string*)'
|
||||
cppa.o: In function `_D4cppa7testeh3FZv':
|
||||
cppa.d:(.text._D4cppa7testeh3FZv+0x19): undefined reference to `throwle()'
|
||||
collect2: error: ld returned 1 exit status
|
||||
--- errorlevel 1
|
||||
|
||||
When the .cpp file is compiled with g++ 5.3.0, the actual function
|
||||
signatures in the cppb.o object file are:
|
||||
|
||||
foo14a(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)
|
||||
foo14b(std::__cxx11::basic_string<int, std::char_traits<int>, std::allocator<int> >*)
|
||||
foo14f(std::char_traits<char>*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)
|
||||
|
||||
Fortunately, it is easily possible to disable the new feature
|
||||
by defining _GLIBCXX_USE_CXX11_ABI as 0 before including any standard
|
||||
headers.
|
||||
*/
|
||||
#define _GLIBCXX_USE_CXX11_ABI 0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
2
libphobos/configure
vendored
2
libphobos/configure
vendored
@ -15566,7 +15566,7 @@ SPEC_PHOBOS_DEPS="$LIBS"
|
||||
|
||||
|
||||
# Libdruntime / phobos soname version
|
||||
libtool_VERSION=2:0:0
|
||||
libtool_VERSION=3:0:0
|
||||
|
||||
|
||||
# Set default flags (after DRUNTIME_WERROR!)
|
||||
|
@ -265,7 +265,7 @@ SPEC_PHOBOS_DEPS="$LIBS"
|
||||
AC_SUBST(SPEC_PHOBOS_DEPS)
|
||||
|
||||
# Libdruntime / phobos soname version
|
||||
libtool_VERSION=2:0:0
|
||||
libtool_VERSION=3:0:0
|
||||
AC_SUBST(libtool_VERSION)
|
||||
|
||||
# Set default flags (after DRUNTIME_WERROR!)
|
||||
|
@ -1,4 +1,4 @@
|
||||
bc58b1e9ea68051af9094651a26313371297b79f
|
||||
6364e010bc87f3621028c8ac648133535c126fb3
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/druntime repository.
|
||||
|
@ -185,22 +185,38 @@ template dtorIsNothrow(T)
|
||||
}
|
||||
|
||||
// taken from std.meta.allSatisfy
|
||||
enum allSatisfy(alias pred, items...) =
|
||||
template allSatisfy(alias F, T...)
|
||||
{
|
||||
static foreach (item; items)
|
||||
static if (!pred!item)
|
||||
if (__ctfe) return false;
|
||||
return true;
|
||||
}();
|
||||
static foreach (Ti; T)
|
||||
{
|
||||
static if (!is(typeof(allSatisfy) == bool) && // not yet defined
|
||||
!F!(Ti))
|
||||
{
|
||||
enum allSatisfy = false;
|
||||
}
|
||||
}
|
||||
static if (!is(typeof(allSatisfy) == bool)) // if not yet defined
|
||||
{
|
||||
enum allSatisfy = true;
|
||||
}
|
||||
}
|
||||
|
||||
// taken from std.meta.anySatisfy
|
||||
enum anySatisfy(alias pred, items...) =
|
||||
template anySatisfy(alias F, Ts...)
|
||||
{
|
||||
static foreach (item; items)
|
||||
static if (pred!item)
|
||||
if (__ctfe) return true;
|
||||
return false;
|
||||
}();
|
||||
static foreach (T; Ts)
|
||||
{
|
||||
static if (!is(typeof(anySatisfy) == bool) && // not yet defined
|
||||
F!T)
|
||||
{
|
||||
enum anySatisfy = true;
|
||||
}
|
||||
}
|
||||
static if (!is(typeof(anySatisfy) == bool)) // if not yet defined
|
||||
{
|
||||
enum anySatisfy = false;
|
||||
}
|
||||
}
|
||||
|
||||
// simplified from std.traits.maxAlignment
|
||||
template maxAlignment(Ts...)
|
||||
|
@ -2111,9 +2111,6 @@ private T trustedMoveImpl(T)(return scope ref T source) @trusted
|
||||
// target must be first-parameter, because in void-functions DMD + dip1000 allows it to take the place of a return-scope
|
||||
private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source)
|
||||
{
|
||||
import core.stdc.string : memcpy, memset;
|
||||
import core.internal.traits;
|
||||
|
||||
// TODO: this assert pulls in half of phobos. we need to work out an alternative assert strategy.
|
||||
// static if (!is(T == class) && hasAliasing!T) if (!__ctfe)
|
||||
// {
|
||||
@ -2124,11 +2121,16 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source)
|
||||
|
||||
static if (is(T == struct))
|
||||
{
|
||||
import core.internal.traits;
|
||||
|
||||
// Unsafe when compiling without -preview=dip1000
|
||||
assert((() @trusted => &source !is &target)(), "source and target must not be identical");
|
||||
|
||||
static if (hasElaborateAssign!T || !isAssignable!T)
|
||||
{
|
||||
import core.stdc.string : memcpy;
|
||||
() @trusted { memcpy(&target, &source, T.sizeof); }();
|
||||
}
|
||||
else
|
||||
target = source;
|
||||
|
||||
@ -2146,15 +2148,21 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source)
|
||||
enum sz = T.sizeof;
|
||||
|
||||
static if (__traits(isZeroInit, T))
|
||||
{
|
||||
import core.stdc.string : memset;
|
||||
() @trusted { memset(&source, 0, sz); }();
|
||||
}
|
||||
else
|
||||
{
|
||||
import core.stdc.string : memcpy;
|
||||
() @trusted { memcpy(&source, __traits(initSymbol, T).ptr, sz); }();
|
||||
}
|
||||
}
|
||||
}
|
||||
else static if (__traits(isStaticArray, T))
|
||||
{
|
||||
for (size_t i = 0; i < source.length; ++i)
|
||||
move(source[i], target[i]);
|
||||
moveEmplaceImpl(target[i], source[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2204,6 +2212,34 @@ pure nothrow @nogc @system unittest
|
||||
assert(val == 0);
|
||||
}
|
||||
|
||||
@betterC
|
||||
pure nothrow @nogc @system unittest
|
||||
{
|
||||
static struct Foo
|
||||
{
|
||||
pure nothrow @nogc:
|
||||
this(int* ptr) { _ptr = ptr; }
|
||||
~this() { if (_ptr) ++*_ptr; }
|
||||
int* _ptr;
|
||||
}
|
||||
|
||||
int val;
|
||||
{
|
||||
Foo[1] foo1 = void; // uninitialized
|
||||
Foo[1] foo2 = [Foo(&val)];// initialized
|
||||
assert(foo2[0]._ptr is &val);
|
||||
|
||||
// Using `move(foo2, foo1)` would have an undefined effect because it would destroy
|
||||
// the uninitialized foo1.
|
||||
// moveEmplace directly overwrites foo1 without destroying or initializing it first.
|
||||
moveEmplace(foo2, foo1);
|
||||
assert(foo1[0]._ptr is &val);
|
||||
assert(foo2[0]._ptr is null);
|
||||
assert(val == 0);
|
||||
}
|
||||
assert(val == 1);
|
||||
}
|
||||
|
||||
// issue 18913
|
||||
@safe unittest
|
||||
{
|
||||
@ -2222,17 +2258,10 @@ pure nothrow @nogc @system unittest
|
||||
f(move(ncarray));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called for a delete statement where the value
|
||||
* being deleted is a pointer to a struct with a destructor
|
||||
* but doesn't have an overloaded delete operator.
|
||||
*
|
||||
* Params:
|
||||
* p = pointer to the value to be deleted
|
||||
*/
|
||||
void _d_delstruct(T)(ref T *p)
|
||||
/// Implementation of `_d_delstruct` and `_d_delstructTrace`
|
||||
template _d_delstructImpl(T)
|
||||
{
|
||||
if (p)
|
||||
private void _d_delstructImpure(ref T p)
|
||||
{
|
||||
debug(PRINTF) printf("_d_delstruct(%p)\n", p);
|
||||
|
||||
@ -2242,21 +2271,61 @@ void _d_delstruct(T)(ref T *p)
|
||||
GC.free(p);
|
||||
p = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called for a delete statement where the value being deleted is a
|
||||
* pointer to a struct with a destructor but doesn't have an overloaded
|
||||
* `delete` operator.
|
||||
*
|
||||
* Params:
|
||||
* p = pointer to the value to be deleted
|
||||
*
|
||||
* Bugs:
|
||||
* This function template was ported from a much older runtime hook that
|
||||
* bypassed safety, purity, and throwabilty checks. To prevent breaking
|
||||
* existing code, this function template is temporarily declared
|
||||
* `@trusted` until the implementation can be brought up to modern D
|
||||
* expectations.
|
||||
*/
|
||||
void _d_delstruct(ref T p) @trusted @nogc pure nothrow
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
alias Type = void function(ref T P) @nogc pure nothrow;
|
||||
(cast(Type) &_d_delstructImpure)(p);
|
||||
}
|
||||
}
|
||||
|
||||
import core.internal.array.utils : _d_HookTraceImpl;
|
||||
|
||||
private enum errorMessage = "Cannot delete struct if compiling without support for runtime type information!";
|
||||
|
||||
/**
|
||||
* TraceGC wrapper around $(REF _d_delstruct, core,lifetime,_d_delstructImpl).
|
||||
*
|
||||
* Bugs:
|
||||
* This function template was ported from a much older runtime hook that
|
||||
* bypassed safety, purity, and throwabilty checks. To prevent breaking
|
||||
* existing code, this function template is temporarily declared
|
||||
* `@trusted` until the implementation can be brought up to modern D
|
||||
* expectations.
|
||||
*/
|
||||
alias _d_delstructTrace = _d_HookTraceImpl!(T, _d_delstruct, errorMessage);
|
||||
}
|
||||
|
||||
@system unittest
|
||||
@system pure nothrow unittest
|
||||
{
|
||||
int dtors = 0;
|
||||
struct S { ~this() { ++dtors; } }
|
||||
|
||||
S *s = new S();
|
||||
_d_delstruct(s);
|
||||
_d_delstructImpl!(typeof(s))._d_delstruct(s);
|
||||
|
||||
assert(s == null);
|
||||
assert(dtors == 1);
|
||||
}
|
||||
|
||||
@system unittest
|
||||
@system pure unittest
|
||||
{
|
||||
int innerDtors = 0;
|
||||
int outerDtors = 0;
|
||||
@ -2277,16 +2346,16 @@ void _d_delstruct(T)(ref T *p)
|
||||
{
|
||||
++outerDtors;
|
||||
|
||||
_d_delstruct(i1);
|
||||
_d_delstructImpl!(typeof(i1))._d_delstruct(i1);
|
||||
assert(i1 == null);
|
||||
|
||||
_d_delstruct(i2);
|
||||
_d_delstructImpl!(typeof(i2))._d_delstruct(i2);
|
||||
assert(i2 == null);
|
||||
}
|
||||
}
|
||||
|
||||
Outer *o = new Outer(0);
|
||||
_d_delstruct(o);
|
||||
_d_delstructImpl!(typeof(o))._d_delstruct(o);
|
||||
|
||||
assert(o == null);
|
||||
assert(innerDtors == 2);
|
||||
|
@ -798,7 +798,7 @@ else static if (hasExecinfo) private class DefaultTraceInfo : Throwable.TraceInf
|
||||
enum CALL_INSTRUCTION_SIZE = 1;
|
||||
|
||||
static if (__traits(compiles, backtrace((void**).init, int.init)))
|
||||
numframes = backtrace(this.callstack.ptr, MAXFRAMES);
|
||||
numframes = cast(int) backtrace(this.callstack.ptr, MAXFRAMES);
|
||||
// Backtrace succeeded, adjust the frame to point to the caller
|
||||
if (numframes >= 2)
|
||||
foreach (ref elem; this.callstack)
|
||||
|
@ -11,137 +11,10 @@ module core.sys.openbsd.execinfo;
|
||||
version (OpenBSD):
|
||||
extern (C):
|
||||
nothrow:
|
||||
@nogc:
|
||||
|
||||
version (GNU)
|
||||
version = BacktraceExternal;
|
||||
|
||||
version (BacktraceExternal)
|
||||
{
|
||||
size_t backtrace(void**, size_t);
|
||||
char** backtrace_symbols(const(void*)*, size_t);
|
||||
void backtrace_symbols_fd(const(void*)*, size_t, int);
|
||||
char** backtrace_symbols_fmt(const(void*)*, size_t, const char*);
|
||||
int backtrace_symbols_fd_fmt(const(void*)*, size_t, int, const char*);
|
||||
}
|
||||
else
|
||||
{
|
||||
import core.sys.openbsd.dlfcn;
|
||||
|
||||
// Use extern (D) so that these functions don't collide with libexecinfo.
|
||||
|
||||
extern (D) int backtrace(void** buffer, int size)
|
||||
{
|
||||
import core.thread : thread_stackBottom;
|
||||
|
||||
void** p, pend=cast(void**)thread_stackBottom();
|
||||
version (D_InlineAsm_X86)
|
||||
asm nothrow @trusted { mov p[EBP], EBP; }
|
||||
else version (D_InlineAsm_X86_64)
|
||||
asm nothrow @trusted { mov p[RBP], RBP; }
|
||||
else
|
||||
static assert(false, "Architecture not supported.");
|
||||
|
||||
int i;
|
||||
for (; i < size && p < pend; ++i)
|
||||
{
|
||||
buffer[i] = *(p + 1);
|
||||
auto pnext = cast(void**)*p;
|
||||
if (pnext <= p) break;
|
||||
p = pnext;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
extern (D) char** backtrace_symbols(const(void*)* buffer, int size)
|
||||
{
|
||||
static void* realloc(void* p, size_t len) nothrow
|
||||
{
|
||||
static import cstdlib=core.stdc.stdlib;
|
||||
auto res = cstdlib.realloc(p, len);
|
||||
if (res is null) cstdlib.free(p);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (size <= 0) return null;
|
||||
|
||||
size_t pos = size * (char*).sizeof;
|
||||
char** p = cast(char**)realloc(null, pos);
|
||||
if (p is null) return null;
|
||||
|
||||
Dl_info info;
|
||||
foreach (i, addr; buffer[0 .. size])
|
||||
{
|
||||
if (dladdr(addr, &info) == 0)
|
||||
(cast(ubyte*)&info)[0 .. info.sizeof] = 0;
|
||||
fixupDLInfo(addr, info);
|
||||
|
||||
immutable len = formatStackFrame(null, 0, addr, info);
|
||||
assert(len > 0);
|
||||
|
||||
p = cast(char**)realloc(p, pos + len);
|
||||
if (p is null) return null;
|
||||
|
||||
formatStackFrame(cast(char*)p + pos, len, addr, info) == len || assert(0);
|
||||
|
||||
p[i] = cast(char*)pos;
|
||||
pos += len;
|
||||
}
|
||||
foreach (i; 0 .. size)
|
||||
{
|
||||
pos = cast(size_t)p[i];
|
||||
p[i] = cast(char*)p + pos;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
extern (D) void backtrace_symbols_fd(const(void*)* buffer, int size, int fd)
|
||||
{
|
||||
import core.sys.posix.unistd : write;
|
||||
import core.stdc.stdlib : alloca;
|
||||
|
||||
if (size <= 0) return;
|
||||
|
||||
Dl_info info;
|
||||
foreach (i, addr; buffer[0 .. size])
|
||||
{
|
||||
if (dladdr(addr, &info) == 0)
|
||||
(cast(ubyte*)&info)[0 .. info.sizeof] = 0;
|
||||
fixupDLInfo(addr, info);
|
||||
|
||||
enum maxAlloca = 1024;
|
||||
enum min = (size_t a, size_t b) => a <= b ? a : b;
|
||||
immutable len = min(formatStackFrame(null, 0, addr, info), maxAlloca);
|
||||
assert(len > 0);
|
||||
|
||||
auto p = cast(char*)alloca(len);
|
||||
if (p is null) return;
|
||||
|
||||
formatStackFrame(p, len, addr, info) >= len || assert(0);
|
||||
p[len - 1] = '\n';
|
||||
write(fd, p, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void fixupDLInfo(const(void)* addr, ref Dl_info info)
|
||||
{
|
||||
if (info.dli_fname is null) info.dli_fname = "???";
|
||||
if (info.dli_fbase is null) info.dli_fbase = null;
|
||||
if (info.dli_sname is null) info.dli_sname = "???";
|
||||
if (info.dli_saddr is null) info.dli_saddr = cast(void*)addr;
|
||||
}
|
||||
|
||||
|
||||
private size_t formatStackFrame(char* p, size_t plen, const(void)* addr, const ref Dl_info info)
|
||||
{
|
||||
import core.stdc.stdio : snprintf;
|
||||
|
||||
immutable off = addr - info.dli_saddr;
|
||||
immutable len = snprintf(p, plen, "%p <%s+%zd> at %s",
|
||||
addr, info.dli_sname, off, info.dli_fname);
|
||||
assert(len > 0);
|
||||
return cast(size_t)len + 1; // + '\0'
|
||||
}
|
||||
}
|
||||
size_t backtrace(void**, size_t);
|
||||
char** backtrace_symbols(const(void*)*, size_t);
|
||||
void backtrace_symbols_fd(const(void*)*, size_t, int);
|
||||
char** backtrace_symbols_fmt(const(void*)*, size_t, const char*);
|
||||
int backtrace_symbols_fd_fmt(const(void*)*, size_t, int, const char*);
|
||||
|
@ -340,26 +340,23 @@ version (CRuntime_Glibc)
|
||||
}
|
||||
c_long[14] st_pad5;
|
||||
}
|
||||
static if (!__USE_FILE_OFFSET64)
|
||||
static assert(stat_t.sizeof == 144);
|
||||
else
|
||||
static assert(stat_t.sizeof == 160);
|
||||
}
|
||||
else version (MIPS64)
|
||||
{
|
||||
struct stat_t
|
||||
{
|
||||
c_ulong st_dev;
|
||||
dev_t st_dev;
|
||||
int[3] st_pad1;
|
||||
static if (!__USE_FILE_OFFSET64)
|
||||
{
|
||||
ino_t st_ino;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_ulong st_ino;
|
||||
}
|
||||
ino_t st_ino;
|
||||
mode_t st_mode;
|
||||
nlink_t st_nlink;
|
||||
uid_t st_uid;
|
||||
gid_t st_gid;
|
||||
c_ulong st_rdev;
|
||||
dev_t st_rdev;
|
||||
static if (!__USE_FILE_OFFSET64)
|
||||
{
|
||||
uint[2] st_pad2;
|
||||
@ -368,8 +365,8 @@ version (CRuntime_Glibc)
|
||||
}
|
||||
else
|
||||
{
|
||||
c_long[3] st_pad2;
|
||||
c_long st_size;
|
||||
uint[3] st_pad2;
|
||||
off_t st_size;
|
||||
}
|
||||
static if (__USE_MISC || __USE_XOPEN2K8)
|
||||
{
|
||||
@ -394,15 +391,26 @@ version (CRuntime_Glibc)
|
||||
}
|
||||
blksize_t st_blksize;
|
||||
uint st_pad4;
|
||||
blkcnt_t st_blocks;
|
||||
int[14] st_pad5;
|
||||
}
|
||||
version (MIPS_N32)
|
||||
{
|
||||
static if (!__USE_FILE_OFFSET64)
|
||||
{
|
||||
blkcnt_t st_blocks;
|
||||
}
|
||||
static assert(stat_t.sizeof == 160);
|
||||
else
|
||||
{
|
||||
c_long st_blocks;
|
||||
}
|
||||
c_long[14] st_pad5;
|
||||
static assert(stat_t.sizeof == 176);
|
||||
}
|
||||
else version (MIPS_O64)
|
||||
{
|
||||
static if (!__USE_FILE_OFFSET64)
|
||||
static assert(stat_t.sizeof == 160);
|
||||
else
|
||||
static assert(stat_t.sizeof == 176);
|
||||
}
|
||||
else
|
||||
{
|
||||
static assert(stat_t.sizeof == 216);
|
||||
}
|
||||
}
|
||||
else version (PPC)
|
||||
|
@ -4651,7 +4651,7 @@ public import core.internal.array.construction : _d_arrayctor;
|
||||
public import core.internal.array.construction : _d_arraysetctor;
|
||||
public import core.internal.array.capacity: _d_arraysetlengthTImpl;
|
||||
|
||||
public import core.lifetime : _d_delstruct;
|
||||
public import core.lifetime : _d_delstructImpl;
|
||||
|
||||
public import core.internal.dassert: _d_assert_fail;
|
||||
|
||||
|
@ -6,10 +6,6 @@
|
||||
* Authors: Walter Bright, Sean Kelly, Martin Nowak
|
||||
* Source: $(DRUNTIMESRC rt/_monitor_.d)
|
||||
*/
|
||||
|
||||
/* NOTE: This file has been patched from the original DMD distribution to
|
||||
* work with the GDC compiler.
|
||||
*/
|
||||
module rt.monitor_;
|
||||
|
||||
import core.atomic, core.stdc.stdlib, core.stdc.string;
|
||||
@ -175,37 +171,7 @@ package:
|
||||
alias IMonitor = Object.Monitor;
|
||||
alias DEvent = void delegate(Object);
|
||||
|
||||
version (GNU)
|
||||
{
|
||||
import gcc.config;
|
||||
static if (GNU_Thread_Model == ThreadModel.Single)
|
||||
version = SingleThreaded;
|
||||
// Ignore ThreadModel, we don't want posix threads on windows and
|
||||
// will always use native threading instead.
|
||||
}
|
||||
|
||||
version (SingleThreaded)
|
||||
{
|
||||
@nogc:
|
||||
alias Mutex = int;
|
||||
|
||||
void initMutex(Mutex* mtx)
|
||||
{
|
||||
}
|
||||
|
||||
void destroyMutex(Mutex* mtx)
|
||||
{
|
||||
}
|
||||
|
||||
void lockMutex(Mutex* mtx)
|
||||
{
|
||||
}
|
||||
|
||||
void unlockMutex(Mutex* mtx)
|
||||
{
|
||||
}
|
||||
}
|
||||
else version (Windows)
|
||||
version (Windows)
|
||||
{
|
||||
version (CRuntime_DigitalMars)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
12329adb67fb43891d6e4e543e7257bc34db0aa7
|
||||
575b67a9b4f78415f96ca77ad50b2de4c667cc74
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/phobos repository.
|
||||
|
@ -638,7 +638,7 @@ Returns:
|
||||
*/
|
||||
size_t count(alias pred = "a == b", Range, E)(Range haystack, E needle)
|
||||
if (isInputRange!Range && !isInfinite!Range &&
|
||||
is(typeof(binaryFun!pred(haystack.front, needle)) : bool))
|
||||
is(typeof(binaryFun!pred(haystack.front, needle))))
|
||||
{
|
||||
bool pred2(ElementType!Range a) { return binaryFun!pred(a, needle); }
|
||||
return count!pred2(haystack);
|
||||
@ -693,7 +693,7 @@ if (isInputRange!Range && !isInfinite!Range &&
|
||||
size_t count(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
|
||||
if (isForwardRange!R1 && !isInfinite!R1 &&
|
||||
isForwardRange!R2 &&
|
||||
is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool))
|
||||
is(typeof(binaryFun!pred(haystack.front, needle.front))))
|
||||
{
|
||||
assert(!needle.empty, "Cannot count occurrences of an empty range");
|
||||
|
||||
@ -716,7 +716,7 @@ if (isForwardRange!R1 && !isInfinite!R1 &&
|
||||
/// Ditto
|
||||
size_t count(alias pred, R)(R haystack)
|
||||
if (isInputRange!R && !isInfinite!R &&
|
||||
is(typeof(unaryFun!pred(haystack.front)) : bool))
|
||||
is(typeof(unaryFun!pred(haystack.front))))
|
||||
{
|
||||
size_t result;
|
||||
alias T = ElementType!R; //For narrow strings forces dchar iteration
|
||||
@ -745,6 +745,12 @@ if (isInputRange!R && !isInfinite!R)
|
||||
assert([1, 2, 3].count([2, 3]) == 1);
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22582
|
||||
@safe unittest
|
||||
{
|
||||
assert([1, 2, 3].count!"a & 1" == 2);
|
||||
}
|
||||
|
||||
/++
|
||||
Counts elements in the given
|
||||
$(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
|
||||
|
@ -2464,7 +2464,8 @@ public:
|
||||
if (!tzName.extension().empty ||
|
||||
!tzName.startsWith(subName) ||
|
||||
baseName(tzName) == "leapseconds" ||
|
||||
tzName == "+VERSION")
|
||||
tzName == "+VERSION" ||
|
||||
tzName == "SECURITY")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -2738,7 +2738,7 @@ public:
|
||||
immutable size_t nBytesNeeded = nWorkUnits * RTask.sizeof;
|
||||
|
||||
import core.stdc.stdlib : malloc, free;
|
||||
if (nBytesNeeded < maxStack)
|
||||
if (nBytesNeeded <= maxStack)
|
||||
{
|
||||
tasks = (cast(RTask*) buf.ptr)[0 .. nWorkUnits];
|
||||
}
|
||||
@ -3045,11 +3045,11 @@ public:
|
||||
Since the underlying data for this struct is heap-allocated, this struct
|
||||
has reference semantics when passed between functions.
|
||||
|
||||
The main uses cases for `WorkerLocalStorageStorage` are:
|
||||
The main uses cases for `WorkerLocalStorage` are:
|
||||
|
||||
1. Performing parallel reductions with an imperative, as opposed to
|
||||
functional, programming style. In this case, it's useful to treat
|
||||
`WorkerLocalStorageStorage` as local to each thread for only the parallel
|
||||
`WorkerLocalStorage` as local to each thread for only the parallel
|
||||
portion of an algorithm.
|
||||
|
||||
2. Recycling temporary buffers across iterations of a parallel foreach loop.
|
||||
|
@ -70,7 +70,7 @@ $(TR $(TD Objects) $(TD
|
||||
|
||||
...
|
||||
// multi-pattern regex
|
||||
auto multi = regex([`\d+,\d+`,`(a-z]+):(\d+)`]);
|
||||
auto multi = regex([`\d+,\d+`, `([a-z]+):(\d+)`]);
|
||||
auto m = "abc:43 12,34".matchAll(multi);
|
||||
assert(m.front.whichPattern == 2);
|
||||
assert(m.front[1] == "abc");
|
||||
@ -80,9 +80,17 @@ $(TR $(TD Objects) $(TD
|
||||
assert(m.front[1] == "12");
|
||||
...
|
||||
|
||||
// The result of the `matchAll/matchFirst` is directly testable with if/assert/while.
|
||||
// e.g. test if a string consists of letters:
|
||||
assert(matchFirst("Letter", `^\p{L}+$`));
|
||||
// The result of `matchAll/matchFirst` is directly testable with `if/assert/while`,
|
||||
// e.g. test if a string consists of letters only:
|
||||
assert(matchFirst("LettersOnly", `^\p{L}+$`));
|
||||
|
||||
// And we can take advantage of the ability to define a variable in the $(LINK2 https://dlang.org/spec/statement.html#IfCondition `IfCondition`):
|
||||
if (const auto captures = matchFirst("At l34st one digit, but maybe more...", `((\d)(\d*))`))
|
||||
{
|
||||
assert(captures[2] == "3");
|
||||
assert(captures[3] == "4");
|
||||
assert(captures[1] == "34");
|
||||
}
|
||||
---
|
||||
|
||||
$(SECTION Syntax and general information)
|
||||
|
@ -829,6 +829,10 @@ private template fqnType(T,
|
||||
{
|
||||
enum fqnType = "dstring";
|
||||
}
|
||||
else static if (is(T == typeof(null)))
|
||||
{
|
||||
enum fqnType = "typeof(null)";
|
||||
}
|
||||
else static if (isBasicType!T && !is(T == enum))
|
||||
{
|
||||
enum fqnType = chain!((Unqual!T).stringof);
|
||||
@ -919,6 +923,7 @@ private template fqnType(T,
|
||||
static assert(fqn!(string) == "string");
|
||||
static assert(fqn!(wstring) == "wstring");
|
||||
static assert(fqn!(dstring) == "dstring");
|
||||
static assert(fqn!(typeof(null)) == "typeof(null)");
|
||||
static assert(fqn!(void) == "void");
|
||||
static assert(fqn!(const(void)) == "const(void)");
|
||||
static assert(fqn!(shared(void)) == "shared(void)");
|
||||
|
24
libphobos/testsuite/libphobos.traits/all_satisfy.d
Normal file
24
libphobos/testsuite/libphobos.traits/all_satisfy.d
Normal file
@ -0,0 +1,24 @@
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22210
|
||||
|
||||
import core.internal.traits : allSatisfy;
|
||||
|
||||
enum isHashable(T) = __traits(compiles,
|
||||
() { T.init; }
|
||||
);
|
||||
|
||||
class A
|
||||
{
|
||||
static if (isHashable!B) {}
|
||||
}
|
||||
|
||||
class B
|
||||
{
|
||||
static if (isHashable!C) {}
|
||||
}
|
||||
|
||||
class C
|
||||
{
|
||||
static if (allSatisfy!(isHashable, int, B)) {}
|
||||
}
|
||||
|
||||
void main() {}
|
27
libphobos/testsuite/libphobos.traits/traits.exp
Normal file
27
libphobos/testsuite/libphobos.traits/traits.exp
Normal file
@ -0,0 +1,27 @@
|
||||
# Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Initialize dg.
|
||||
dg-init
|
||||
|
||||
# Gather a list of all tests.
|
||||
set tests [lsort [find $srcdir/$subdir *.d]]
|
||||
|
||||
# Main loop.
|
||||
dg-runtest $tests "" $DEFAULT_DFLAGS
|
||||
|
||||
# All done.
|
||||
dg-finish
|
Loading…
Reference in New Issue
Block a user