Skip to content

Commit

Permalink
Fix Issue 23650 - Using typeid with struct defined in __traits(compil…
Browse files Browse the repository at this point in the history
…es, ...) causes linker error
  • Loading branch information
RazvanN7 committed Jan 25, 2023
1 parent 49771d7 commit e1b41c4
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 7 deletions.
12 changes: 11 additions & 1 deletion compiler/src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -5519,8 +5519,18 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
// Handle this in the glue layer
e = new TypeidExp(exp.loc, ta);
e.type = getTypeInfoType(exp.loc, ta, sc);

bool genObjCode = true;

// https://issues.dlang.org/show_bug.cgi?id=23650
// We generate object code for typeinfo, required
// by typeid, only if in non-speculative context
if (sc.func && sc.func.skipCodegen)
{
genObjCode = false;
}

e.type = getTypeInfoType(exp.loc, ta, sc, genObjCode);
semanticTypeInfo(sc, ta);

if (ea)
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -8153,9 +8153,9 @@ extern Target target;

extern bool tpsemantic(TemplateParameter* tp, Scope* sc, Array<TemplateParameter* >* parameters);

extern void genTypeInfo(Expression* e, const Loc& loc, Type* torig, Scope* sc);
extern void genTypeInfo(Expression* e, const Loc& loc, Type* torig, Scope* sc, bool genObjCode = true);

extern Type* getTypeInfoType(const Loc& loc, Type* t, Scope* sc);
extern Type* getTypeInfoType(const Loc& loc, Type* t, Scope* sc, bool genObjCode = true);

extern bool builtinTypeInfo(Type* t);

Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dmd/semantic3.d
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ private extern(C++) final class Semantic3Visitor : Visitor
sc2.aligndecl = null;
if (funcdecl.ident != Id.require && funcdecl.ident != Id.ensure)
sc2.flags = sc.flags & ~SCOPE.contract;
if (sc2.flags & SCOPE.compile)
funcdecl.skipCodegen = true;
sc2.flags &= ~SCOPE.compile;
sc2.tf = null;
sc2.os = null;
Expand Down
10 changes: 6 additions & 4 deletions compiler/src/dmd/typinf.d
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ import core.stdc.stdio;
* loc = the location for reporting line numbers in errors
* torig = the type to generate the `TypeInfo` object for
* sc = the scope
* genObjCode = if true, object code will be generated for the obtained TypeInfo
*/
extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc)
extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc, bool genObjCode = true)
{
// printf("genTypeInfo() %s\n", torig.toChars());

Expand Down Expand Up @@ -80,7 +81,7 @@ extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope

// generate a COMDAT for other TypeInfos not available as builtins in
// druntime
if (!isUnqualifiedClassInfo && !builtinTypeInfo(t))
if (!isUnqualifiedClassInfo && !builtinTypeInfo(t) && genObjCode)
{
if (sc) // if in semantic() pass
{
Expand All @@ -105,13 +106,14 @@ extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope
* loc = the location for reporting line nunbers in errors
* t = the type to get the type of the `TypeInfo` object for
* sc = the scope
* genObjCode = if true, object code will be generated for the obtained TypeInfo
* Returns:
* The type of the `TypeInfo` object associated with `t`
*/
extern (C++) Type getTypeInfoType(const ref Loc loc, Type t, Scope* sc)
extern (C++) Type getTypeInfoType(const ref Loc loc, Type t, Scope* sc, bool genObjCode = true)
{
assert(t.ty != Terror);
genTypeInfo(null, loc, t, sc);
genTypeInfo(null, loc, t, sc, genObjCode);
return t.vtinfo.type;
}

Expand Down
13 changes: 13 additions & 0 deletions compiler/test/runnable/test23650.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// https://issues.dlang.org/show_bug.cgi?id=23650

__gshared int x;

void main()
{

static assert(__traits(compiles,
{
struct S { int *p = &x; }
auto t = typeid(S);
}));
}

0 comments on commit e1b41c4

Please sign in to comment.