mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +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() {
|
clone_repos() {
|
||||||
if [ -z ${SYSTEM_PULLREQUEST_TARGETBRANCH+x} ]; then
|
if [ -z ${SYSTEM_PULLREQUEST_TARGETBRANCH+x} ]; then
|
||||||
|
# no PR
|
||||||
local REPO_BRANCH="$BUILD_SOURCEBRANCHNAME"
|
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
|
else
|
||||||
|
# PR from a fork
|
||||||
local REPO_BRANCH="$SYSTEM_PULLREQUEST_TARGETBRANCH"
|
local REPO_BRANCH="$SYSTEM_PULLREQUEST_TARGETBRANCH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
21
.cirrus.yml
21
.cirrus.yml
|
@ -5,13 +5,24 @@ common_steps_template: &COMMON_STEPS_TEMPLATE
|
||||||
set -uexo pipefail
|
set -uexo pipefail
|
||||||
ln -s $CIRRUS_WORKING_DIR ../dmd
|
ln -s $CIRRUS_WORKING_DIR ../dmd
|
||||||
|
|
||||||
# for PRs - merge with target branch first
|
if [ -z ${CIRRUS_PR+x} ] ; then
|
||||||
if [ ! -z ${CIRRUS_PR+x} ] ; then
|
# not a PR
|
||||||
git fetch origin "+refs/pull/$CIRRUS_PR/merge:";
|
REPO_BRANCH="$CIRRUS_BRANCH"
|
||||||
git checkout -f FETCH_HEAD;
|
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
|
fi
|
||||||
|
|
||||||
./ci.sh setup_repos "${CIRRUS_BASE_BRANCH:-$CIRRUS_BRANCH}"
|
./ci.sh setup_repos "$REPO_BRANCH"
|
||||||
build_script: ./ci.sh build
|
build_script: ./ci.sh build
|
||||||
|
|
||||||
test_dmd_script: |
|
test_dmd_script: |
|
||||||
|
|
|
@ -1293,7 +1293,7 @@ private extern (C++) class TypeInfoDtVisitor : Visitor
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put out:
|
/* Put out:
|
||||||
* char[] name;
|
* char[] mangledName;
|
||||||
* void[] init;
|
* void[] init;
|
||||||
* hash_t function(in void*) xtoHash;
|
* hash_t function(in void*) xtoHash;
|
||||||
* bool function(in void*, in void*) xopEquals;
|
* bool function(in void*, in void*) xopEquals;
|
||||||
|
@ -1310,9 +1310,9 @@ private extern (C++) class TypeInfoDtVisitor : Visitor
|
||||||
* xgetRTInfo
|
* xgetRTInfo
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const name = sd.toPrettyChars();
|
const mangledName = tc.deco;
|
||||||
const namelen = strlen(name);
|
const mangledNameLen = strlen(mangledName);
|
||||||
dtb.size(namelen);
|
dtb.size(mangledNameLen);
|
||||||
dtb.xoff(d.csym, Type.typeinfostruct.structsize);
|
dtb.xoff(d.csym, Type.typeinfostruct.structsize);
|
||||||
|
|
||||||
// void[] init;
|
// void[] init;
|
||||||
|
@ -1410,8 +1410,8 @@ private extern (C++) class TypeInfoDtVisitor : Visitor
|
||||||
else
|
else
|
||||||
dtb.size(0);
|
dtb.size(0);
|
||||||
|
|
||||||
// Put out name[] immediately following TypeInfo_Struct
|
// Put out mangledName[] immediately following TypeInfo_Struct
|
||||||
dtb.nbytes(cast(uint)(namelen + 1), name);
|
dtb.nbytes(cast(uint)(mangledNameLen + 1), mangledName);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(TypeInfoClassDeclaration d)
|
override void visit(TypeInfoClassDeclaration d)
|
||||||
|
|
|
@ -1259,7 +1259,7 @@ private void genClassInfoForClass(ClassDeclaration cd, Symbol* sinit)
|
||||||
size_t namelen = strlen(name);
|
size_t namelen = strlen(name);
|
||||||
if (!(namelen > 9 && memcmp(name, "TypeInfo_".ptr, 9) == 0))
|
if (!(namelen > 9 && memcmp(name, "TypeInfo_".ptr, 9) == 0))
|
||||||
{
|
{
|
||||||
name = cd.toPrettyChars();
|
name = cd.toPrettyChars(/*QualifyTypes=*/ true);
|
||||||
namelen = strlen(name);
|
namelen = strlen(name);
|
||||||
}
|
}
|
||||||
dtb.size(namelen);
|
dtb.size(namelen);
|
||||||
|
@ -1486,7 +1486,7 @@ private void genClassInfoForInterface(InterfaceDeclaration id)
|
||||||
dtb.size(0); // initializer
|
dtb.size(0); // initializer
|
||||||
|
|
||||||
// name[]
|
// name[]
|
||||||
const(char) *name = id.toPrettyChars();
|
const(char) *name = id.toPrettyChars(/*QualifyTypes=*/ true);
|
||||||
size_t namelen = strlen(name);
|
size_t namelen = strlen(name);
|
||||||
dtb.size(namelen);
|
dtb.size(namelen);
|
||||||
dt_t *pdtname = dtb.xoffpatch(id.csym, 0, TYnptr);
|
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