Skip to content

Commit

Permalink
Fix issue 20700 - Fwd refs leads to extern(C++, class|struct) being i…
Browse files Browse the repository at this point in the history
…gnored

On the long run, it looks like we should just move the setScope to AttribDeclaration,
but this is a simple bugfix to target stable.
  • Loading branch information
Geod24 committed Apr 2, 2020
1 parent e34203a commit c533ad1
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 5 deletions.
7 changes: 7 additions & 0 deletions src/dmd/attrib.d
Expand Up @@ -435,6 +435,13 @@ extern (C++) final class CPPMangleDeclaration : AttribDeclaration
sc.aligndecl, sc.inlining);
}

override void setScope(Scope* sc)
{
if (decl)
Dsymbol.setScope(sc); // for forward reference
return AttribDeclaration.setScope(sc);
}

override const(char)* toChars() const
{
return toString().ptr;
Expand Down
1 change: 1 addition & 0 deletions src/dmd/attrib.h
Expand Up @@ -88,6 +88,7 @@ class CPPMangleDeclaration : public AttribDeclaration

Dsymbol *syntaxCopy(Dsymbol *s);
Scope *newScope(Scope *sc);
void setScope(Scope *sc);
const char *toChars() const;
void accept(Visitor *v) { v->visit(this); }
};
Expand Down
13 changes: 8 additions & 5 deletions src/dmd/typesem.d
Expand Up @@ -1810,13 +1810,16 @@ extern(C++) Type typeSemantic(Type t, const ref Loc loc, Scope* sc)
Type visitStruct(TypeStruct mtype)
{
//printf("TypeStruct::semantic('%s')\n", mtype.toChars());
// If this is called via a forward reference,
// use the dsymbol's scope so that `extern(C++ class|struct)` applies
// https://issues.dlang.org/show_bug.cgi?id=20700
auto cppmangle = (mtype.sym && mtype.sym._scope) ?
mtype.sym._scope.cppmangle : sc.cppmangle;

if (mtype.deco)
{
if (sc && sc.cppmangle != CPPMANGLE.def)
{
if (mtype.cppmangle == CPPMANGLE.def)
mtype.cppmangle = sc.cppmangle;
}
assert(cppmangle == CPPMANGLE.def ||
cppmangle == mtype.cppmangle);
return mtype;
}

Expand Down
13 changes: 13 additions & 0 deletions test/compilable/cppmangle.d
Expand Up @@ -1251,3 +1251,16 @@ extern(C++, `bar`)
{
void func19542(T)();
}

// https://issues.dlang.org/show_bug.cgi?id=20700
version (Windows)
extern(C++)
{
void test20700_1(const ref Struct20700);
extern(C++, class) struct Struct20700 {}
void test20700_2(const ref Struct20700);

// Note: Needs to be `BV` (`class`), not `BU` (`struct`)
static assert(test20700_1.mangleof == `?test20700_1@@YAXABVStruct20700@@@Z`);
static assert(test20700_2.mangleof == `?test20700_2@@YAXABVStruct20700@@@Z`);
}

0 comments on commit c533ad1

Please sign in to comment.