mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
commit
9b0936f351
14 changed files with 122 additions and 51 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
v2.104.0
|
||||
v2.104.1-beta.1
|
||||
|
|
|
@ -118,7 +118,7 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN
|
|||
{
|
||||
auto sd = ts.sym;
|
||||
const id = ce.f.ident;
|
||||
if (sd.postblit && isArrayConstructionOrAssign(id))
|
||||
if (sd.postblit && isArrayConstruction(id))
|
||||
{
|
||||
checkFuncThrows(ce, sd.postblit);
|
||||
return;
|
||||
|
|
|
@ -3890,7 +3890,7 @@ public:
|
|||
newval = copyLiteral(newval).copy();
|
||||
assignInPlace(oldval, newval);
|
||||
}
|
||||
else if (wantCopy && e.op == EXP.assign)
|
||||
else if (wantCopy && (e.op == EXP.assign || e.op == EXP.loweredAssignExp))
|
||||
{
|
||||
// Currently postblit/destructor calls on static array are done
|
||||
// in the druntime internal functions so they don't appear in AST.
|
||||
|
@ -4299,7 +4299,7 @@ public:
|
|||
rb.newval = newval;
|
||||
rb.refCopy = wantRef || cow;
|
||||
rb.needsPostblit = sd && sd.postblit && e.op != EXP.blit && e.e2.isLvalue();
|
||||
rb.needsDtor = sd && sd.dtor && e.op == EXP.assign;
|
||||
rb.needsDtor = sd && sd.dtor && (e.op == EXP.assign || e.op == EXP.loweredAssignExp);
|
||||
if (Expression ex = rb.assignTo(existingAE, cast(size_t)lowerbound, cast(size_t)upperbound))
|
||||
return ex;
|
||||
|
||||
|
@ -4773,12 +4773,11 @@ public:
|
|||
result = CTFEExp.voidexp;
|
||||
return;
|
||||
}
|
||||
else if (isArrayConstructionOrAssign(fd.ident))
|
||||
else if (isArrayConstruction(fd.ident))
|
||||
{
|
||||
// In expressionsem.d, the following lowerings were performed:
|
||||
// * `T[x] ea = eb;` to `_d_array{,set}ctor(ea[], eb[]);`.
|
||||
// * `ea = eb` to `_d_array{,setassign,assign_l,assign_r}(ea[], eb)`.
|
||||
// The following code will rewrite them back to `ea = eb` and
|
||||
// In expressionsem.d, `T[x] ea = eb;` was lowered to:
|
||||
// `_d_array{,set}ctor(ea[], eb[]);`.
|
||||
// The following code will rewrite it back to `ea = eb` and
|
||||
// then interpret that expression.
|
||||
|
||||
if (fd.ident == Id._d_arrayctor)
|
||||
|
@ -4791,17 +4790,14 @@ public:
|
|||
ea = ea.isCastExp.e1;
|
||||
|
||||
Expression eb = (*e.arguments)[1];
|
||||
if (eb.isCastExp() && fd.ident != Id._d_arraysetctor)
|
||||
if (eb.isCastExp() && fd.ident == Id._d_arrayctor)
|
||||
eb = eb.isCastExp.e1;
|
||||
|
||||
Expression rewrittenExp;
|
||||
if (fd.ident == Id._d_arrayctor || fd.ident == Id._d_arraysetctor)
|
||||
rewrittenExp = new ConstructExp(e.loc, ea, eb);
|
||||
else
|
||||
rewrittenExp = new AssignExp(e.loc, ea, eb);
|
||||
ConstructExp ce = new ConstructExp(e.loc, ea, eb);
|
||||
ce.type = ea.type;
|
||||
|
||||
rewrittenExp.type = ea.type;
|
||||
result = interpret(rewrittenExp, istate);
|
||||
ce.type = ea.type;
|
||||
result = interpret(ce, istate);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -93,22 +93,7 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf,
|
|||
bool isMutable; // true if reference to mutable
|
||||
}
|
||||
|
||||
/* Store escapeBy as static data escapeByStorage so we can keep reusing the same
|
||||
* arrays rather than reallocating them.
|
||||
*/
|
||||
__gshared EscapeBy[] escapeByStorage;
|
||||
auto escapeBy = escapeByStorage;
|
||||
if (escapeBy.length < len)
|
||||
{
|
||||
auto newPtr = cast(EscapeBy*)mem.xrealloc(escapeBy.ptr, len * EscapeBy.sizeof);
|
||||
// Clear the new section
|
||||
memset(newPtr + escapeBy.length, 0, (len - escapeBy.length) * EscapeBy.sizeof);
|
||||
escapeBy = newPtr[0 .. len];
|
||||
escapeByStorage = escapeBy;
|
||||
}
|
||||
else
|
||||
escapeBy = escapeBy[0 .. len];
|
||||
|
||||
auto escapeBy = new EscapeBy[len];
|
||||
const paramLength = tf.parameterList.length;
|
||||
|
||||
// Fill in escapeBy[] with arguments[], ethis, and outerVars[]
|
||||
|
@ -228,13 +213,6 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf,
|
|||
escape(i, eb, false);
|
||||
}
|
||||
|
||||
/* Reset the arrays in escapeBy[] so we can reuse them next time through
|
||||
*/
|
||||
foreach (ref eb; escapeBy)
|
||||
{
|
||||
eb.er.reset();
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
@ -2487,6 +2465,9 @@ bool isReferenceToMutable(Type t)
|
|||
}
|
||||
break;
|
||||
|
||||
case Tnull:
|
||||
return false;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
@ -7425,23 +7425,20 @@ extern(D) Modifiable checkModifiable(Expression exp, Scope* sc, ModifyFlags flag
|
|||
}
|
||||
|
||||
/**
|
||||
* Verify if the given identifier is any of
|
||||
* _d_array{ctor,setctor,setassign,assign_l, assign_r}.
|
||||
* Verify if the given identifier is _d_array{,set}ctor.
|
||||
*
|
||||
* Params:
|
||||
* id = the identifier to verify
|
||||
*
|
||||
* Returns:
|
||||
* `true` if the identifier corresponds to a construction of assignement
|
||||
* runtime hook, `false` otherwise.
|
||||
* `true` if the identifier corresponds to a construction runtime hook,
|
||||
* `false` otherwise.
|
||||
*/
|
||||
bool isArrayConstructionOrAssign(const Identifier id)
|
||||
bool isArrayConstruction(const Identifier id)
|
||||
{
|
||||
import dmd.id : Id;
|
||||
|
||||
return id == Id._d_arrayctor || id == Id._d_arraysetctor ||
|
||||
id == Id._d_arrayassign_l || id == Id._d_arrayassign_r ||
|
||||
id == Id._d_arraysetassign;
|
||||
return id == Id._d_arrayctor || id == Id._d_arraysetctor;
|
||||
}
|
||||
|
||||
/******************************
|
||||
|
|
|
@ -10362,6 +10362,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
if (global.params.verbose)
|
||||
message("lowered %s =>\n %s", ae.toChars(), res.toChars());
|
||||
|
||||
res = new LoweredAssignExp(ae, res);
|
||||
res.type = ae.type;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -416,9 +416,11 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
|
|||
* op(e1.aliasthis)
|
||||
*/
|
||||
//printf("att una %s e1 = %s\n", EXPtoString(op).ptr, this.e1.type.toChars());
|
||||
e.e1 = resolveAliasThis(sc, e.e1, true);
|
||||
if (e.e1)
|
||||
if (auto e1 = resolveAliasThis(sc, e.e1, true))
|
||||
{
|
||||
e.e1 = e1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -65,10 +65,12 @@
|
|||
#ifndef __DMC__ // no tgmath.h
|
||||
#ifndef _MSC_VER // C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt\tgmath.h(33): Error: no type for declarator before `)`
|
||||
#ifndef __APPLE__ // /Applications/Xcode-14.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/tgmath.h(39): Error: named parameter required before `...`
|
||||
#if !(defined(__linux__) && defined(__aarch64__)) // /tmp/clang/lib/clang/15.0.3/include/tgmath.h(34): Error: named parameter required before `...`
|
||||
#include <tgmath.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __DMC__
|
||||
#ifndef __linux__
|
||||
|
|
30
compiler/test/compilable/test23978.d
Normal file
30
compiler/test/compilable/test23978.d
Normal file
|
@ -0,0 +1,30 @@
|
|||
// REQUIRED_ARGS: -preview=dip1021 -lowmem
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23978
|
||||
|
||||
// Note: this is a memory corruption bug.
|
||||
// Memory returned by `GC.realloc` retains references to old memory in it,
|
||||
// mostly because of the smallarray optimization for `Array(T)`.
|
||||
// If this fails again, it might not be consistent, so try running it multiple times.
|
||||
|
||||
class LUBench { }
|
||||
void lup(ulong , ulong , int , int = 1)
|
||||
{
|
||||
new LUBench;
|
||||
}
|
||||
void lup_3200(ulong iters, ulong flops)
|
||||
{
|
||||
lup(iters, flops, 3200);
|
||||
}
|
||||
void raytrace()
|
||||
{
|
||||
struct V
|
||||
{
|
||||
float x, y, z;
|
||||
auto normalize() { }
|
||||
struct Tid { }
|
||||
auto spawnLinked() { }
|
||||
string[] namesByTid;
|
||||
class MessageBox { }
|
||||
auto cross() { }
|
||||
}
|
||||
}
|
17
compiler/test/compilable/test23979.d
Normal file
17
compiler/test/compilable/test23979.d
Normal file
|
@ -0,0 +1,17 @@
|
|||
// REQUIRED_ARGS: -o-
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23979
|
||||
// Issue 23979 - ICE on failed alias this attempt on pointer expression
|
||||
|
||||
class A {}
|
||||
|
||||
void h()
|
||||
{
|
||||
const auto classPtr = SPtr.init;
|
||||
assert(!__traits(compiles, *classPtr));
|
||||
}
|
||||
|
||||
struct SPtr
|
||||
{
|
||||
A ptr() { return A.init; }
|
||||
alias ptr this;
|
||||
}
|
11
compiler/test/compilable/test23986.d
Normal file
11
compiler/test/compilable/test23986.d
Normal file
|
@ -0,0 +1,11 @@
|
|||
// REQUIRED_ARGS: -preview=dip1021 -o-
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23986
|
||||
// dip1021 asserts on `typeof(null)` parameter
|
||||
@safe:
|
||||
|
||||
void f(typeof(null) obj, int* x) {}
|
||||
|
||||
void g()
|
||||
{
|
||||
f(null, null);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/* TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/failcstuff4.i(605): Error: invalid flag for line marker directive
|
||||
fail_compilation/failcstuff4b.i(605): Error: invalid flag for line marker directive
|
||||
---
|
||||
*/
|
||||
|
30
compiler/test/runnable/test23959.d
Normal file
30
compiler/test/runnable/test23959.d
Normal file
|
@ -0,0 +1,30 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=23959;
|
||||
|
||||
struct ST()
|
||||
{
|
||||
int i;
|
||||
this(this) {}
|
||||
}
|
||||
|
||||
alias S = ST!();
|
||||
|
||||
void poison()
|
||||
{
|
||||
static S g;
|
||||
auto s = g;
|
||||
}
|
||||
|
||||
S[1] sa;
|
||||
|
||||
void fun(S[] values...)
|
||||
{
|
||||
sa[] = values;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
fun(S(1));
|
||||
assert(sa[0].i);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -141,9 +141,11 @@
|
|||
// Ubuntu's assert.h uses this
|
||||
#define __PRETTY_FUNCTION__ __func__
|
||||
|
||||
#ifndef __aarch64__
|
||||
#define _Float128 long double
|
||||
#define __float128 long double
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if __APPLE__
|
||||
#undef __SIZEOF_INT128__
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue