diff --git a/.azure-pipelines/lib.sh b/.azure-pipelines/lib.sh index 437ffd2817..654198eace 100644 --- a/.azure-pipelines/lib.sh +++ b/.azure-pipelines/lib.sh @@ -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 diff --git a/.cirrus.yml b/.cirrus.yml index a6bf649494..33b86beb87 100644 --- a/.cirrus.yml +++ b/.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: | diff --git a/src/dmd/todt.d b/src/dmd/todt.d index ff0ffd33ce..23ead48a0d 100644 --- a/src/dmd/todt.d +++ b/src/dmd/todt.d @@ -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) diff --git a/src/dmd/toobj.d b/src/dmd/toobj.d index c00f284b21..60279bd474 100644 --- a/src/dmd/toobj.d +++ b/src/dmd/toobj.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); diff --git a/test/runnable/unique_typeinfo_names.d b/test/runnable/unique_typeinfo_names.d new file mode 100644 index 0000000000..120f8ffedc --- /dev/null +++ b/test/runnable/unique_typeinfo_names.d @@ -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(); +}