mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
Fix Issues 22149 & 22150 - TypeInfo names aren't unique, leading to botched equality semantics (#12928)
* Fix Issue 22149 - TypeInfo_Struct names aren't unique, leading to botched equality semantics By storing the mangled name, making the TypeInfo_Struct names truly unique and more compact at the same time. Requires https://github.com/dlang/druntime/pull/3527. * Fix Issue 22150 - TypeInfo_Class names aren't unique, leading to botched equality semantics By fully qualifying template arguments. * [temp] Cirrus CI: Use same-named druntime branch * Azure Pipelines: Try to use same-named druntime/Phobos branches for PRs originating from the official dlang repo * Cirrus CI: Try to use same-named druntime/Phobos branches for PRs originating from the official dlang repo
This commit is contained in:
parent
cdd9063115
commit
5ebfb077c6
5 changed files with 122 additions and 13 deletions
|
@ -77,8 +77,13 @@ install_grep() {
|
|||
|
||||
clone_repos() {
|
||||
if [ -z ${SYSTEM_PULLREQUEST_TARGETBRANCH+x} ]; then
|
||||
# no PR
|
||||
local REPO_BRANCH="$BUILD_SOURCEBRANCHNAME"
|
||||
elif [ ${SYSTEM_PULLREQUEST_ISFORK} == False ]; then
|
||||
# PR originating from the official dlang repo
|
||||
local REPO_BRANCH="$SYSTEM_PULLREQUEST_SOURCEBRANCH"
|
||||
else
|
||||
# PR from a fork
|
||||
local REPO_BRANCH="$SYSTEM_PULLREQUEST_TARGETBRANCH"
|
||||
fi
|
||||
|
||||
|
|
21
.cirrus.yml
21
.cirrus.yml
|
@ -5,13 +5,24 @@ common_steps_template: &COMMON_STEPS_TEMPLATE
|
|||
set -uexo pipefail
|
||||
ln -s $CIRRUS_WORKING_DIR ../dmd
|
||||
|
||||
# for PRs - merge with target branch first
|
||||
if [ ! -z ${CIRRUS_PR+x} ] ; then
|
||||
git fetch origin "+refs/pull/$CIRRUS_PR/merge:";
|
||||
git checkout -f FETCH_HEAD;
|
||||
if [ -z ${CIRRUS_PR+x} ] ; then
|
||||
# not a PR
|
||||
REPO_BRANCH="$CIRRUS_BRANCH"
|
||||
else
|
||||
# PR - merge with target branch first
|
||||
git fetch origin "+refs/pull/$CIRRUS_PR/merge:"
|
||||
git checkout -f FETCH_HEAD
|
||||
|
||||
if [[ ! "$CIRRUS_BRANCH" =~ ^pull/ ]]; then
|
||||
# PR originating from the official dlang repo
|
||||
REPO_BRANCH="$CIRRUS_BRANCH"
|
||||
else
|
||||
# PR from a fork
|
||||
REPO_BRANCH="$CIRRUS_BASE_BRANCH"
|
||||
fi
|
||||
fi
|
||||
|
||||
./ci.sh setup_repos "${CIRRUS_BASE_BRANCH:-$CIRRUS_BRANCH}"
|
||||
./ci.sh setup_repos "$REPO_BRANCH"
|
||||
build_script: ./ci.sh build
|
||||
|
||||
test_dmd_script: |
|
||||
|
|
|
@ -1293,7 +1293,7 @@ private extern (C++) class TypeInfoDtVisitor : Visitor
|
|||
}
|
||||
|
||||
/* Put out:
|
||||
* char[] name;
|
||||
* char[] mangledName;
|
||||
* void[] init;
|
||||
* hash_t function(in void*) xtoHash;
|
||||
* bool function(in void*, in void*) xopEquals;
|
||||
|
@ -1310,9 +1310,9 @@ private extern (C++) class TypeInfoDtVisitor : Visitor
|
|||
* xgetRTInfo
|
||||
*/
|
||||
|
||||
const name = sd.toPrettyChars();
|
||||
const namelen = strlen(name);
|
||||
dtb.size(namelen);
|
||||
const mangledName = tc.deco;
|
||||
const mangledNameLen = strlen(mangledName);
|
||||
dtb.size(mangledNameLen);
|
||||
dtb.xoff(d.csym, Type.typeinfostruct.structsize);
|
||||
|
||||
// void[] init;
|
||||
|
@ -1410,8 +1410,8 @@ private extern (C++) class TypeInfoDtVisitor : Visitor
|
|||
else
|
||||
dtb.size(0);
|
||||
|
||||
// Put out name[] immediately following TypeInfo_Struct
|
||||
dtb.nbytes(cast(uint)(namelen + 1), name);
|
||||
// Put out mangledName[] immediately following TypeInfo_Struct
|
||||
dtb.nbytes(cast(uint)(mangledNameLen + 1), mangledName);
|
||||
}
|
||||
|
||||
override void visit(TypeInfoClassDeclaration d)
|
||||
|
|
|
@ -1259,7 +1259,7 @@ private void genClassInfoForClass(ClassDeclaration cd, Symbol* sinit)
|
|||
size_t namelen = strlen(name);
|
||||
if (!(namelen > 9 && memcmp(name, "TypeInfo_".ptr, 9) == 0))
|
||||
{
|
||||
name = cd.toPrettyChars();
|
||||
name = cd.toPrettyChars(/*QualifyTypes=*/ true);
|
||||
namelen = strlen(name);
|
||||
}
|
||||
dtb.size(namelen);
|
||||
|
@ -1486,7 +1486,7 @@ private void genClassInfoForInterface(InterfaceDeclaration id)
|
|||
dtb.size(0); // initializer
|
||||
|
||||
// name[]
|
||||
const(char) *name = id.toPrettyChars();
|
||||
const(char) *name = id.toPrettyChars(/*QualifyTypes=*/ true);
|
||||
size_t namelen = strlen(name);
|
||||
dtb.size(namelen);
|
||||
dt_t *pdtname = dtb.xoffpatch(id.csym, 0, TYnptr);
|
||||
|
|
93
test/runnable/unique_typeinfo_names.d
Normal file
93
test/runnable/unique_typeinfo_names.d
Normal file
|
@ -0,0 +1,93 @@
|
|||
module unique_typeinfo_names;
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22149
|
||||
void structs()
|
||||
{
|
||||
static struct Foo(T) {}
|
||||
|
||||
auto foo()
|
||||
{
|
||||
struct S {}
|
||||
return Foo!S();
|
||||
}
|
||||
|
||||
auto bar()
|
||||
{
|
||||
struct S {}
|
||||
return Foo!S();
|
||||
}
|
||||
|
||||
auto f = foo();
|
||||
auto b = bar();
|
||||
|
||||
assert(typeid(f) != typeid(b));
|
||||
assert(typeid(f).name != typeid(b).name);
|
||||
|
||||
assert(typeid(f).mangledName == typeof(f).mangleof);
|
||||
assert(typeid(b).mangledName == typeof(b).mangleof);
|
||||
assert(typeid(f).name == "unique_typeinfo_names.structs().Foo!(unique_typeinfo_names.structs().foo().S).Foo");
|
||||
assert(typeid(b).name == "unique_typeinfo_names.structs().Foo!(unique_typeinfo_names.structs().bar().S).Foo");
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=22150
|
||||
void classes()
|
||||
{
|
||||
static class Foo(T) {}
|
||||
|
||||
static auto foo()
|
||||
{
|
||||
struct S {}
|
||||
return new Foo!S();
|
||||
}
|
||||
|
||||
static auto bar()
|
||||
{
|
||||
struct S {}
|
||||
return new Foo!S();
|
||||
}
|
||||
|
||||
auto f = foo();
|
||||
auto b = bar();
|
||||
|
||||
assert(typeid(f) != typeid(b));
|
||||
assert(typeid(f).name != typeid(b).name);
|
||||
|
||||
assert(typeid(f).name == "unique_typeinfo_names.classes.Foo!(unique_typeinfo_names.classes.foo.S).Foo");
|
||||
assert(typeid(b).name == "unique_typeinfo_names.classes.Foo!(unique_typeinfo_names.classes.bar.S).Foo");
|
||||
}
|
||||
|
||||
void interfaces()
|
||||
{
|
||||
static interface IFoo(T) {}
|
||||
static class Foo(T) : IFoo!T {}
|
||||
|
||||
static auto foo()
|
||||
{
|
||||
struct S {}
|
||||
IFoo!S r = new Foo!S();
|
||||
return r;
|
||||
}
|
||||
|
||||
static auto bar()
|
||||
{
|
||||
struct S {}
|
||||
IFoo!S r = new Foo!S();
|
||||
return r;
|
||||
}
|
||||
|
||||
auto f = foo();
|
||||
auto b = bar();
|
||||
|
||||
assert(typeid(f) != typeid(b));
|
||||
assert(typeid(f).name != typeid(b).name);
|
||||
|
||||
assert(typeid(f).name == "unique_typeinfo_names.interfaces.IFoo!(unique_typeinfo_names.interfaces.foo.S).IFoo");
|
||||
assert(typeid(b).name == "unique_typeinfo_names.interfaces.IFoo!(unique_typeinfo_names.interfaces.bar.S).IFoo");
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
structs();
|
||||
classes();
|
||||
interfaces();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue