mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +03:00

* Fix 23722 - Lambdas are mangled incorrectly when using multiple compilation units, resulting in incorrect code * Update test cases
627 lines
17 KiB
D
627 lines
17 KiB
D
// PERMUTE_ARGS:
|
||
// EXTRA_SOURCES: imports/mangle10077.d
|
||
// EXTRA_FILES: imports/testmangle.d
|
||
// UNICODE_NAMES:
|
||
/*
|
||
TEST_OUTPUT:
|
||
---
|
||
_D7imports10testmangle12detectMangleFPSQBlQBg6DetectZQq
|
||
_D7imports10testmangle__T10DetectTmplTiZQpFNaNbNiNfZv
|
||
true
|
||
false
|
||
---
|
||
*/
|
||
|
||
import imports.testmangle;
|
||
|
||
/***************************************************/
|
||
// https://issues.dlang.org/show_bug.cgi?id=10077
|
||
// pragma(mangle)
|
||
|
||
pragma(mangle, "_test10077a_") int test10077a;
|
||
static assert(test10077a.mangleof == "_test10077a_");
|
||
|
||
__gshared pragma(mangle, "_test10077b_") ubyte test10077b;
|
||
static assert(test10077b.mangleof == "_test10077b_");
|
||
|
||
pragma(mangle, "_test10077c_") void test10077c() {}
|
||
static assert(test10077c.mangleof == "_test10077c_");
|
||
|
||
pragma(mangle, "_test10077f_") __gshared char test10077f;
|
||
static assert(test10077f.mangleof == "_test10077f_");
|
||
|
||
pragma(mangle, "_test10077g_") @system { void test10077g() {} }
|
||
static assert(test10077g.mangleof == "_test10077g_");
|
||
|
||
template getModuleInfo(alias mod)
|
||
{
|
||
pragma(mangle, "_D"~mod.mangleof~"12__ModuleInfoZ") static __gshared extern ModuleInfo mi;
|
||
enum getModuleInfo = &mi;
|
||
}
|
||
|
||
void test10077h()
|
||
{
|
||
assert(getModuleInfo!(object).name == "object");
|
||
}
|
||
|
||
//UTF-8 chars
|
||
__gshared extern pragma(mangle, "test_эльфийские_письмена_9") ubyte test10077i_evar;
|
||
|
||
void test10077i()
|
||
{
|
||
import imports.mangle10077;
|
||
|
||
setTest10077i();
|
||
assert(test10077i_evar == 42);
|
||
}
|
||
|
||
/***************************************************/
|
||
// https://issues.dlang.org/show_bug.cgi?id=13050
|
||
|
||
void func13050(int);
|
||
template decl13050(Arg)
|
||
{
|
||
void decl13050(Arg);
|
||
}
|
||
template problem13050(Arg)
|
||
{
|
||
pragma(mangle, "foobar")
|
||
void problem13050(Arg);
|
||
}
|
||
template workaround13050(Arg)
|
||
{
|
||
pragma(mangle, "foobar")
|
||
void func(Arg);
|
||
alias workaround13050 = func;
|
||
}
|
||
|
||
static assert(is(typeof(&func13050) == void function(int)));
|
||
static assert(is(typeof(&decl13050!int) == void function(int)));
|
||
static assert(is(typeof(&problem13050!int) == void function(int)));
|
||
static assert(is(typeof(&workaround13050!int) == void function(int)));
|
||
|
||
/***************************************************/
|
||
// https://issues.dlang.org/show_bug.cgi?id=2774
|
||
|
||
int foo2774(int n) { return 0; }
|
||
static assert(foo2774.mangleof == "_D6mangle7foo2774FiZi");
|
||
|
||
class C2774
|
||
{
|
||
int foo2774() { return 0; }
|
||
}
|
||
static assert(C2774.foo2774.mangleof == "_D6mangle5C27747foo2774MFZi");
|
||
|
||
template TFoo2774(T) {}
|
||
static assert(TFoo2774!int.mangleof == "6mangle"~tl!"15"~"__T8TFoo2774TiZ");
|
||
|
||
void test2774()
|
||
{
|
||
int foo2774(int n) { return 0; }
|
||
static assert(foo2774.mangleof == "_D6mangle8test2774FZ7foo2774MFNaNbNiNfiZi");
|
||
}
|
||
|
||
/*******************************************/
|
||
// https://issues.dlang.org/show_bug.cgi?id=8847
|
||
|
||
auto S8847()
|
||
{
|
||
static struct Result
|
||
{
|
||
inout(Result) get() inout { return this; }
|
||
}
|
||
return Result();
|
||
}
|
||
|
||
void test8847a()
|
||
{
|
||
auto a = S8847();
|
||
auto b = a.get();
|
||
alias typeof(a) A;
|
||
alias typeof(b) B;
|
||
assert(is(A == B), A.stringof~ " is different from "~B.stringof);
|
||
}
|
||
|
||
// --------
|
||
|
||
enum result8847a = "S6mangle9iota8847aFZ6Result";
|
||
enum result8847b = "S6mangle9iota8847bFZ4iotaMFZ6Result";
|
||
enum result8847c = "C6mangle9iota8847cFZ6Result";
|
||
enum result8847d = "C6mangle9iota8847dFZ4iotaMFZ6Result";
|
||
|
||
auto iota8847a()
|
||
{
|
||
static struct Result
|
||
{
|
||
this(int) {}
|
||
inout(Result) test() inout { return cast(inout)Result(0); }
|
||
}
|
||
static assert(Result.mangleof == result8847a);
|
||
return Result.init;
|
||
}
|
||
auto iota8847b()
|
||
{
|
||
auto iota()
|
||
{
|
||
static struct Result
|
||
{
|
||
this(int) {}
|
||
inout(Result) test() inout { return cast(inout)Result(0); }
|
||
}
|
||
static assert(Result.mangleof == result8847b);
|
||
return Result.init;
|
||
}
|
||
return iota();
|
||
}
|
||
auto iota8847c()
|
||
{
|
||
static class Result
|
||
{
|
||
this(int) {}
|
||
inout(Result) test() inout { return cast(inout)new Result(0); }
|
||
}
|
||
static assert(Result.mangleof == result8847c);
|
||
return Result.init;
|
||
}
|
||
auto iota8847d()
|
||
{
|
||
auto iota()
|
||
{
|
||
static class Result
|
||
{
|
||
this(int) {}
|
||
inout(Result) test() inout { return cast(inout)new Result(0); }
|
||
}
|
||
static assert(Result.mangleof == result8847d);
|
||
return Result.init;
|
||
}
|
||
return iota();
|
||
}
|
||
void test8847b()
|
||
{
|
||
static assert(typeof(iota8847a().test()).mangleof == result8847a);
|
||
static assert(typeof(iota8847b().test()).mangleof == result8847b);
|
||
static assert(typeof(iota8847c().test()).mangleof == result8847c);
|
||
static assert(typeof(iota8847d().test()).mangleof == result8847d);
|
||
}
|
||
|
||
// --------
|
||
|
||
struct Test8847
|
||
{
|
||
enum result1 = "S6mangle8Test8847"~tl!("8")~"__T3fooZ"~id!("3foo","Qf")~"MFZ6Result";
|
||
enum result2 = "S6mangle8Test8847"~tl!("8")~"__T3fooZ"~id!("3foo","Qf")~"MxFiZ6Result";
|
||
|
||
auto foo()()
|
||
{
|
||
static struct Result
|
||
{
|
||
inout(Result) get() inout { return this; }
|
||
}
|
||
static assert(Result.mangleof == Test8847.result1);
|
||
return Result();
|
||
}
|
||
auto foo()(int n) const
|
||
{
|
||
static struct Result
|
||
{
|
||
inout(Result) get() inout { return this; }
|
||
}
|
||
static assert(Result.mangleof == Test8847.result2);
|
||
return Result();
|
||
}
|
||
}
|
||
void test8847c()
|
||
{
|
||
static assert(typeof(Test8847().foo( ).get()).mangleof == Test8847.result1);
|
||
static assert(typeof(Test8847().foo(1).get()).mangleof == Test8847.result2);
|
||
}
|
||
|
||
// --------
|
||
|
||
void test8847d()
|
||
{
|
||
enum resultS = "S6mangle9test8847dFZ3fooMFZ3barMFZ3bazMFZ1S";
|
||
enum resultX = "S6mangle9test8847dFZ3fooMFZ1X";
|
||
// Return types for test8847d and bar are mangled correctly,
|
||
// and return types for foo and baz are not mangled correctly.
|
||
|
||
auto foo()
|
||
{
|
||
struct X { inout(X) get() inout { return inout(X)(); } }
|
||
string bar()
|
||
{
|
||
auto baz()
|
||
{
|
||
struct S { inout(S) get() inout { return inout(S)(); } }
|
||
return S();
|
||
}
|
||
static assert(typeof(baz() ).mangleof == resultS);
|
||
static assert(typeof(baz().get()).mangleof == resultS);
|
||
return "";
|
||
}
|
||
return X();
|
||
}
|
||
static assert(typeof(foo() ).mangleof == resultX);
|
||
static assert(typeof(foo().get()).mangleof == resultX);
|
||
}
|
||
|
||
// --------
|
||
|
||
void test8847e()
|
||
{
|
||
enum resultHere = "6mangle"~"9test8847eFZ"~tl!"8"~"__T3fooZ"~id!("3foo","Qf");
|
||
enum resultBar = "S"~resultHere~"MFNaNfNgiZ3Bar";
|
||
static if(BackRefs) {} else
|
||
enum resultFoo = "_D"~resultHere~"MFNaNbNiNfNgiZNg"~resultBar; // added 'Nb'
|
||
|
||
// Make template function to infer 'nothrow' attributes
|
||
auto foo()(inout int) pure @safe
|
||
{
|
||
struct Bar {}
|
||
static assert(Bar.mangleof == resultBar);
|
||
return inout(Bar)();
|
||
}
|
||
|
||
import core.demangle : demangle, demangleType;
|
||
auto bar = foo(0);
|
||
static assert(typeof(bar).stringof == "Bar");
|
||
static assert(typeof(bar).mangleof == resultBar);
|
||
enum fooDemangled = "pure nothrow @nogc @safe inout(mangle.test8847e().foo!().foo(inout(int)).Bar) mangle.test8847e().foo!().foo(inout(int))";
|
||
|
||
static if (BackRefs)
|
||
static assert(demangle(foo!().mangleof) == fooDemangled);
|
||
else
|
||
static assert(foo!().mangleof == resultFoo);
|
||
}
|
||
|
||
// --------
|
||
|
||
pure f8847a()
|
||
{
|
||
struct S {}
|
||
return S();
|
||
}
|
||
|
||
pure
|
||
{
|
||
auto f8847b()
|
||
{
|
||
struct S {}
|
||
return S();
|
||
}
|
||
}
|
||
|
||
static assert(typeof(f8847a()).mangleof == "S6mangle6f8847aFNaZ1S");
|
||
static assert(typeof(f8847b()).mangleof == "S6mangle6f8847bFNaZ1S");
|
||
|
||
/*******************************************/
|
||
// https://issues.dlang.org/show_bug.cgi?id=12352
|
||
|
||
auto bar12352()
|
||
{
|
||
struct S { int var; void func() {} }
|
||
|
||
static assert(!__traits(compiles, bar12352.mangleof)); // forward reference to bar
|
||
static assert(S .mangleof == "S6mangle8bar12352FZ1S");
|
||
static assert(S.func.mangleof == "_D6mangle8bar12352FZ1S4funcMFZv");
|
||
|
||
return S();
|
||
}
|
||
static assert( bar12352 .mangleof == "_D6mangle8bar12352FNaNbNiNfZS"~id!("6mangle8bar12352FZ","QBbQxFZ","QL2H")~"1S");
|
||
static assert(typeof(bar12352()) .mangleof == "S6mangle8bar12352FZ1S");
|
||
static assert(typeof(bar12352()).func.mangleof == "_D6mangle8bar12352FZ1S4funcMFZv");
|
||
|
||
auto baz12352()
|
||
{
|
||
class C { int var; void func() {} }
|
||
|
||
static assert(!__traits(compiles, baz12352.mangleof)); // forward reference to baz
|
||
static assert(C .mangleof == "C6mangle8baz12352FZ1C");
|
||
static assert(C.func.mangleof == "_D6mangle8baz12352FZ1C4funcMFZv");
|
||
|
||
return new C();
|
||
}
|
||
static assert( baz12352 .mangleof == "_D6mangle8baz12352FNaNbNfZC"~id!("6mangle8baz12352FZ","QzQuFZ","QL2F")~"1C");
|
||
static assert(typeof(baz12352()) .mangleof == "C6mangle8baz12352FZ1C");
|
||
static assert(typeof(baz12352()).func.mangleof == "_D6mangle8baz12352FZ1C4funcMFZv");
|
||
|
||
/*******************************************/
|
||
// https://issues.dlang.org/show_bug.cgi?id=9525
|
||
|
||
void f9525(T)(in T*) { }
|
||
|
||
void test9525()
|
||
{
|
||
enum result1 = "S6mangle8test9525FZ"~tl!"26"~"__T5test1S"~tl!"13"~id!("6mangle","QBc")~"5f9525Z"~id!("5test1","Qr")~"MFZ1S";
|
||
enum result2 = "S6mangle8test9525FZ"~tl!"26"~"__T5test2S"~tl!"13"~id!("6mangle","QBc")~"5f9525Z"~id!("5test2","Qr")~"MFNaNbZ1S";
|
||
|
||
bool test1(alias a)()
|
||
{
|
||
static struct S {}
|
||
static assert(S.mangleof == result1);
|
||
S s;
|
||
a(&s); // Error: Cannot convert &S to const(S*) at compile time
|
||
return true;
|
||
}
|
||
enum evalTest1 = test1!f9525();
|
||
|
||
bool test2(alias a)() pure nothrow
|
||
{
|
||
static struct S {}
|
||
static assert(S.mangleof == result2);
|
||
S s;
|
||
a(&s); // Error: Cannot convert &S to const(S*) at compile time
|
||
return true;
|
||
}
|
||
enum evalTest2 = test2!f9525();
|
||
}
|
||
|
||
/******************************************/
|
||
// https://issues.dlang.org/show_bug.cgi?id=10249
|
||
|
||
template Seq10249(T...) { alias Seq10249 = T; }
|
||
|
||
mixin template Func10249(T)
|
||
{
|
||
void func10249(T) {}
|
||
}
|
||
mixin Func10249!long;
|
||
mixin Func10249!string;
|
||
|
||
void f10249(long) {}
|
||
|
||
class C10249
|
||
{
|
||
mixin Func10249!long;
|
||
mixin Func10249!string;
|
||
static assert(Seq10249!(.func10249)[0].mangleof == "6mangle9func10249"); // <- 9func10249
|
||
static assert(Seq10249!( func10249)[0].mangleof == "6mangle6C102499func10249"); // <- 9func10249
|
||
|
||
static: // necessary to make overloaded symbols accessible via __traits(getOverloads, C10249)
|
||
void foo(long) {}
|
||
void foo(string) {}
|
||
static assert(Seq10249!(foo)[0].mangleof == "6mangle6C102493foo"); // <- _D6mangle6C102493fooFlZv
|
||
static assert(Seq10249!(__traits(getOverloads, C10249, "foo"))[0].mangleof == "_D6mangle6C102493fooFlZv"); // <-
|
||
static assert(Seq10249!(__traits(getOverloads, C10249, "foo"))[1].mangleof == "_D6mangle6C102493fooFAyaZv"); // <-
|
||
|
||
void g(string) {}
|
||
alias bar = .f10249;
|
||
alias bar = g;
|
||
static assert(Seq10249!(bar)[0].mangleof == "6mangle6C102493bar"); // <- _D6mangle1fFlZv
|
||
static assert(Seq10249!(__traits(getOverloads, C10249, "bar"))[0].mangleof == "_D6mangle6f10249FlZv"); // <-
|
||
static assert(Seq10249!(__traits(getOverloads, C10249, "bar"))[1].mangleof == "_D6mangle6C102491gFAyaZv"); // <-
|
||
}
|
||
|
||
/*******************************************/
|
||
// https://issues.dlang.org/show_bug.cgi?id=11718
|
||
|
||
struct Ty11718(alias sym) {}
|
||
|
||
auto fn11718(T)(T a) { return Ty11718!(a).mangleof; }
|
||
auto fn11718(T)() { T a; return Ty11718!(a).mangleof; }
|
||
|
||
void test11718()
|
||
{
|
||
string TyName(string tail)()
|
||
{
|
||
enum s = "__T7Ty11718" ~ tail;
|
||
enum len = unsignedToString(s.length);
|
||
return "S6mangle" ~ tl!(len) ~ s;
|
||
}
|
||
string fnName(string paramPart)()
|
||
{
|
||
enum s = "_D6mangle"~tl!("35")~"__T7fn11718T"~
|
||
"S6mangle9test11718FZ1AZ7fn11718"~paramPart~"1a"~
|
||
"S6mangle9test11718FZ1A";
|
||
enum len = unsignedToString(s.length);
|
||
return tl!len ~ s;
|
||
}
|
||
enum result1 = TyName!("S" ~ fnName!("F"~"S6mangle9test11718FZ1A"~"Z") ~ "Z") ~ "7Ty11718";
|
||
enum result2 = TyName!("S" ~ fnName!("F"~"" ~"Z") ~ "Z") ~ "7Ty11718";
|
||
|
||
struct A {}
|
||
static if (BackRefs)
|
||
{
|
||
static assert(fn11718(A.init) == "S6mangle__T7Ty11718S_DQv__T7fn11718TSQBk9test11718FZ1AZQBcFQxZ1aQBcZQCf");
|
||
static assert(fn11718!A() == "S6mangle__T7Ty11718S_DQv__T7fn11718TSQBk9test11718FZ1AZQBcFZ1aQBaZQCd");
|
||
}
|
||
else
|
||
{
|
||
pragma(msg, fn11718(A.init));
|
||
static assert(fn11718(A.init) == result1);
|
||
static assert(fn11718!A() == result2);
|
||
}
|
||
}
|
||
|
||
/*******************************************/
|
||
// https://issues.dlang.org/show_bug.cgi?id=11776
|
||
|
||
struct S11776(alias fun) { }
|
||
|
||
void test11776()
|
||
{
|
||
auto g = ()
|
||
{
|
||
if (1)
|
||
return; // fill tf->next
|
||
if (1)
|
||
{
|
||
auto s = S11776!(a => 1)();
|
||
enum expected = "S"~"6mangle"~tl!("56")~
|
||
("__T"~"6S11776"~"S"~tl!("42")~
|
||
(id!("6mangle","Qs")~"9test11776"~"FZ"~"17__lambda_L444_C14MFZ17__lambda_L450_C30")~"Z"
|
||
)~id!("6S11776", "QCm");
|
||
static assert(typeof(s).mangleof == expected);
|
||
}
|
||
};
|
||
}
|
||
|
||
/***************************************************/
|
||
// https://issues.dlang.org/show_bug.cgi?id=12044
|
||
|
||
struct S12044(T)
|
||
{
|
||
void f()()
|
||
{
|
||
new T[1];
|
||
}
|
||
|
||
bool opEquals(O)(O)
|
||
{
|
||
f();
|
||
}
|
||
}
|
||
|
||
void test12044()
|
||
{
|
||
()
|
||
{
|
||
enum E { e }
|
||
auto arr = [E.e];
|
||
S12044!E s;
|
||
}
|
||
();
|
||
}
|
||
|
||
/*******************************************/
|
||
// https://issues.dlang.org/show_bug.cgi?id=12217
|
||
|
||
void test12217(int)
|
||
{
|
||
static struct S {}
|
||
void bar() {}
|
||
int var;
|
||
template X(T) {}
|
||
|
||
static assert( S.mangleof == "S6mangle9test12217FiZ1S");
|
||
static assert( bar.mangleof == "_D6mangle9test12217FiZ3barMFNaNbNiNfZv");
|
||
static assert( var.mangleof == "_D6mangle9test12217FiZ3vari");
|
||
static assert(X!int.mangleof == "6mangle9test12217FiZ"~tl!("8")~"__T1XTiZ");
|
||
}
|
||
|
||
void test12217() {}
|
||
|
||
/***************************************************/
|
||
// https://issues.dlang.org/show_bug.cgi?id=12231
|
||
|
||
void func12231a()()
|
||
if (is(typeof({
|
||
class C {}
|
||
static assert(C.mangleof ==
|
||
"C6mangle"~tl!("16")~"__U10func12231aZ"~id!("10func12231a","Qn")~"FZ17__lambda_L509_C15MFZ1C");
|
||
// ### L #
|
||
})))
|
||
{}
|
||
|
||
void func12231b()()
|
||
if (is(typeof({
|
||
class C {} static assert(C.mangleof ==
|
||
"C6mangle"~tl!("16")~"__U10func12231bZ"~id!("10func12231b","Qn")~"FZ17__lambda_L518_C15MFZ1C");
|
||
// L__L L LL
|
||
})) &&
|
||
is(typeof({
|
||
class C {}
|
||
static assert(C.mangleof ==
|
||
"C6mangle"~tl!("16")~"__U10func12231bZ"~id!("10func12231b","Qn")~"FZ17__lambda_L523_C15MFZ1C");
|
||
// L__L L LL
|
||
})))
|
||
{}
|
||
|
||
void func12231c()()
|
||
if (is(typeof({
|
||
class C {}
|
||
static assert(C.mangleof ==
|
||
"C6mangle"~tl!("16")~"__U10func12231cZ"~id!("10func12231c","Qn")~"FZ17__lambda_L532_C15MFZ1C");
|
||
// L__L L LL
|
||
})))
|
||
{
|
||
(){
|
||
class C {}
|
||
static assert(C.mangleof ==
|
||
"C6mangle"~tl!("16")~"__T10func12231cZ"~id!("10func12231c","Qn")~"FZ16__lambda_L539_C5MFZ1C");
|
||
// L__L L LL
|
||
}();
|
||
}
|
||
|
||
void func12231c(X)()
|
||
if (is(typeof({
|
||
class C {}
|
||
static assert(C.mangleof ==
|
||
"C6mangle"~tl!("20")~"__U10func12231cTAyaZ"~id!("10func12231c","Qr")~"FZ17__lambda_L548_C15MFZ1C");
|
||
// L__L L___L LL
|
||
})))
|
||
{
|
||
(){
|
||
class C {}
|
||
static assert(C.mangleof ==
|
||
"C6mangle"~tl!("20")~"__T10func12231cTAyaZ"~id!("10func12231c","Qr")~"FZ16__lambda_L555_C5MFZ1C");
|
||
// L__L L___L LL
|
||
}();
|
||
}
|
||
|
||
void test12231()
|
||
{
|
||
func12231a();
|
||
|
||
func12231b();
|
||
|
||
func12231c();
|
||
func12231c!string();
|
||
}
|
||
|
||
/***************************************************/
|
||
|
||
class CC
|
||
{
|
||
int* p;
|
||
|
||
int* member() scope
|
||
{
|
||
return p;
|
||
}
|
||
}
|
||
|
||
static assert(CC.member.mangleof == "_D6mangle2CC6memberMFNlZPi");
|
||
|
||
/***************************************************/
|
||
|
||
void fooA(void delegate (scope void delegate()) dg)
|
||
{
|
||
}
|
||
void fooB(void delegate (void delegate()) scope dg)
|
||
{
|
||
}
|
||
|
||
//pragma(msg, fooA.mangleof);
|
||
//pragma(msg, fooB.mangleof);
|
||
static assert(typeof(fooA).mangleof != typeof(fooB).mangleof);
|
||
|
||
|
||
/***************************************************/
|
||
|
||
@live int testLive() { return 42; }
|
||
|
||
static assert(testLive.mangleof == "_D6mangle8testLiveFNmZi");
|
||
|
||
/***************************************************/
|
||
|
||
alias noreturn = typeof(*null);
|
||
alias fpd = noreturn function();
|
||
int funcd(fpd);
|
||
static assert(funcd.mangleof == "_D6mangle5funcdFPFZNnZi");
|
||
|
||
/***************************************************/
|
||
|
||
struct S21753 { void function() f1; }
|
||
void fun21753(S21753 v)() {}
|
||
alias fl21753 = (){};
|
||
static assert((fun21753!(S21753(fl21753))).mangleof == "_D6mangle__T8fun21753VSQv6S21753S1f_DQBj16" ~ fl21753.stringof ~ "MFNaNbNiNfZvZQChQp");
|
||
|
||
/***************************************************/
|
||
void main()
|
||
{
|
||
test10077h();
|
||
test10077i();
|
||
test12044();
|
||
}
|