Fix Issues 23951 and 23279 - traits(hasMember) does not follow alias this + ICE when using traits(hasMember) on an erroneous member (#15406)

* Fix Issue 23951 - traits(getMember) does not follow alias this

* Fix Issue 23279 - ICE when using traits(hasMember) with an erroneous member
This commit is contained in:
Razvan Nitu 2023-07-14 14:34:04 +03:00 committed by GitHub
parent 8094a01e43
commit 452e170d2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 6 deletions

View file

@ -947,15 +947,24 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
*/ */
Dsymbol sym = getDsymbol(o); Dsymbol sym = getDsymbol(o);
if (sym && e.ident == Id.hasMember)
{
if (auto sm = sym.search(e.loc, id))
return True();
// https://issues.dlang.org/show_bug.cgi?id=23951
if (auto decl = sym.isDeclaration())
{
ex = typeDotIdExp(e.loc, decl.type, id);
goto doSemantic;
}
}
if (auto t = isType(o)) if (auto t = isType(o))
ex = typeDotIdExp(e.loc, t, id); ex = typeDotIdExp(e.loc, t, id);
else if (sym) else if (sym)
{ {
if (e.ident == Id.hasMember)
{
if (auto sm = sym.search(e.loc, id))
return True();
}
ex = new DsymbolExp(e.loc, sym); ex = new DsymbolExp(e.loc, sym);
ex = new DotIdExp(e.loc, ex, id); ex = new DotIdExp(e.loc, ex, id);
} }
@ -966,7 +975,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
e.error("invalid first argument"); e.error("invalid first argument");
return ErrorExp.get(); return ErrorExp.get();
} }
doSemantic:
// ignore symbol visibility and disable access checks for these traits // ignore symbol visibility and disable access checks for these traits
Scope* scx = sc.push(); Scope* scx = sc.push();
scx.flags |= SCOPE.ignoresymbolvisibility | SCOPE.noaccesscheck; scx.flags |= SCOPE.ignoresymbolvisibility | SCOPE.noaccesscheck;

View file

@ -0,0 +1,10 @@
// https://issues.dlang.org/show_bug.cgi?id=23951
struct S { int x; }
struct T { S a; alias a this; }
struct U { T t; }
static assert(__traits(hasMember, T, "x"));
static assert(__traits(hasMember, T.init, "x"));
static assert(__traits(hasMember, U.init.t, "x"));
static assert(__traits(hasMember, U.t, "a"));
static assert(__traits(hasMember, U.t, "x"));

View file

@ -0,0 +1,14 @@
// https://issues.dlang.org/show_bug.cgi?id=23279
/*
TEST_OUTPUT:
---
fail_compilation/test23279.d(13): Error: undefined identifier `Sth`
---
*/
class Tester
{
enum a = __traits(hasMember, Tester, "setIt");
void setIt(Sth sth){}
}