diff mbox series

[committed] d: Enable private member access for __traits

Message ID 20210121135535.659903-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Enable private member access for __traits | expand

Commit Message

Iain Buclaw Jan. 21, 2021, 1:55 p.m. UTC
Hi,

This patch merges the D front-end with upstream dmd 3a7ebef73.

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.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and
committed to mainline.

Regards
Iain.

---
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 mbox series

Patch

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") ));
+}