From 279d3a89b79f85d07a8ac4db1bebe9f60cb549e5 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Thu, 21 Jan 2021 10:31:36 +0100 Subject: [PATCH] d: Enable private member access for __traits The following traits can now access non-public members: - hasMember - getMember - getOverloads - getVirtualMethods - getVirtualFuntions This fixes a long-standing issue in D where the allMembers trait would correctly return non-public members but those non-public members would be inaccessible to other traits. Reviewed-on: https://github.com/dlang/dmd/pull/12135 gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 3a7ebef73. --- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/traits.c | 10 ++++------ gcc/testsuite/gdc.test/compilable/imports/test15371.d | 9 +++++++++ gcc/testsuite/gdc.test/compilable/test15371.d | 10 ++++++++++ 4 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gdc.test/compilable/imports/test15371.d create mode 100644 gcc/testsuite/gdc.test/compilable/test15371.d diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 4f7f7a8ff3b..1f907b8f19f 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -2d3d137489f030395d06cb664087fd1a35bccabe +3a7ebef73cc01d4a877a95cf95cd3776c9e3ee66 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c index 5fd4b486a9b..70f7f2cb582 100644 --- a/gcc/d/dmd/traits.c +++ b/gcc/d/dmd/traits.c @@ -1103,12 +1103,14 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc) return new ErrorExp(); } + // ignore symbol visibility and disable access checks for these traits + Scope *scx = sc->push(); + scx->flags |= SCOPEignoresymbolvisibility | SCOPEnoaccesscheck; + if (e->ident == Id::hasMember) { /* Take any errors as meaning it wasn't found */ - Scope *scx = sc->push(); - scx->flags |= SCOPEignoresymbolvisibility; ex = trySemantic(ex, scx); scx->pop(); return ex ? True(e) : False(e); @@ -1118,8 +1120,6 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc) if (ex->op == TOKdotid) // Prevent semantic() from replacing Symbol with its initializer ((DotIdExp *)ex)->wantsym = true; - Scope *scx = sc->push(); - scx->flags |= SCOPEignoresymbolvisibility; ex = semantic(ex, scx); scx->pop(); return ex; @@ -1130,8 +1130,6 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc) { unsigned errors = global.errors; Expression *eorig = ex; - Scope *scx = sc->push(); - scx->flags |= SCOPEignoresymbolvisibility; ex = semantic(ex, scx); if (errors < global.errors) e->error("%s cannot be resolved", eorig->toChars()); diff --git a/gcc/testsuite/gdc.test/compilable/imports/test15371.d b/gcc/testsuite/gdc.test/compilable/imports/test15371.d new file mode 100644 index 00000000000..49b446a329b --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test15371.d @@ -0,0 +1,9 @@ +module imports.test15371; + +struct A +{ + private int a; + private void fun() {} + private void fun(int, int) {} + public void fun(int) {} +} diff --git a/gcc/testsuite/gdc.test/compilable/test15371.d b/gcc/testsuite/gdc.test/compilable/test15371.d new file mode 100644 index 00000000000..6e762beeb1e --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test15371.d @@ -0,0 +1,10 @@ +// EXTRA_FILES: imports/test15371.d +import imports.test15371; + +void main() +{ + A a; + static assert(__traits(hasMember, A, "a")); + static assert(__traits(getOverloads, A, "fun").length == 3); + static assert(__traits(compiles, __traits(getMember, a, "a") )); +} -- 2.30.2