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:
Martin Kinkelin 2021-08-01 14:04:25 +02:00 committed by GitHub
parent cdd9063115
commit 5ebfb077c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 122 additions and 13 deletions

View file

@ -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

View file

@ -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: |

View file

@ -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)

View file

@ -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);

View 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();
}