From 964dc722b88955110456b4b302da561743f7cb61 Mon Sep 17 00:00:00 2001 From: Oliver Bracevac Date: Tue, 16 Jul 2024 17:19:52 +0200 Subject: [PATCH 1/2] Check Java protected static in RefChecks --- .../dotty/tools/dotc/typer/RefChecks.scala | 22 +++++++++++++++++++ tests/neg/i18446.check | 4 ++++ tests/neg/i18446/Task.java | 5 +++++ tests/neg/i18446/Test.scala | 1 + tests/run/i18446.check | 2 ++ tests/run/i18446/Client.scala | 5 +++++ tests/run/i18446/Task.java | 5 +++++ tests/run/i18446/Test.scala | 4 ++++ tests/run/i18446/i18446.scala | 5 +++++ 9 files changed, 53 insertions(+) create mode 100644 tests/neg/i18446.check create mode 100644 tests/neg/i18446/Task.java create mode 100644 tests/neg/i18446/Test.scala create mode 100644 tests/run/i18446.check create mode 100644 tests/run/i18446/Client.scala create mode 100644 tests/run/i18446/Task.java create mode 100644 tests/run/i18446/Test.scala create mode 100644 tests/run/i18446/i18446.scala diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 7e53b38b5f98..2eb92de2c908 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -22,6 +22,7 @@ import config.Printers.refcheck import reporting.* import Constants.Constant import cc.stripCapturing +import dotty.tools.dotc.printing.Formatting.hl object RefChecks { import tpd.* @@ -1274,6 +1275,18 @@ object RefChecks { case tp: NamedType if tp.prefix.typeSymbol != ctx.owner.enclosingClass => report.warning(UnqualifiedCallToAnyRefMethod(tree, tree.symbol), tree) case _ => () + + def checkJavaStaticProtected(tree: tpd.Apply | tpd.Select | tpd.Assign)(using Context): Unit = + val sym = tree.symbol + if sym.isAllOf(StaticProtected) then + val definedPackage = sym.enclosingPackageClass + val definedClass = sym.owner.companionClass //it's _not_ sym.enclosingClass because it's static, therefore enclosed in a companion object, not a class + val enclosingPackage = ctx.owner.enclosingPackageClass + + if definedPackage != enclosingPackage && !ctx.owner.ownersIterator.exists(_.derivesFrom(definedClass)) then + report.error(em"${StaticProtected} $sym which is defined in $definedPackage is inaccessible at runtime from $enclosingPackage", tree.srcPos) + end checkJavaStaticProtected + } import RefChecks.* @@ -1363,6 +1376,15 @@ class RefChecks extends MiniPhase { thisPhase => override def transformSelect(tree: tpd.Select)(using Context): tpd.Tree = if defn.ScalaBoxedClasses().contains(tree.qualifier.tpe.typeSymbol) && tree.name == nme.synchronized_ then report.warning(SynchronizedCallOnBoxedClass(tree), tree.srcPos) + checkJavaStaticProtected(tree) + tree + + override def transformApply(tree: tpd.Apply)(using Context): tpd.Apply = + checkJavaStaticProtected(tree) + tree + + override def transformAssign(tree: tpd.Assign)(using Context): tpd.Assign = + checkJavaStaticProtected(tree) tree } diff --git a/tests/neg/i18446.check b/tests/neg/i18446.check new file mode 100644 index 000000000000..748818136c11 --- /dev/null +++ b/tests/neg/i18446.check @@ -0,0 +1,4 @@ +-- Error: tests/neg/i18446/Test.scala:1:17 ----------------------------------------------------------------------------- +1 |val _ = foo.Task.poll() // error + | ^^^^^^^^^^^^^ + |protected method poll which is defined in package foo is inaccessible at runtime from package diff --git a/tests/neg/i18446/Task.java b/tests/neg/i18446/Task.java new file mode 100644 index 000000000000..c3ada81c143c --- /dev/null +++ b/tests/neg/i18446/Task.java @@ -0,0 +1,5 @@ +package foo; + +public abstract class Task{ + protected static void poll(){ System.out.println("Task"); } +} diff --git a/tests/neg/i18446/Test.scala b/tests/neg/i18446/Test.scala new file mode 100644 index 000000000000..b0932061cf54 --- /dev/null +++ b/tests/neg/i18446/Test.scala @@ -0,0 +1 @@ +val _ = foo.Task.poll() // error diff --git a/tests/run/i18446.check b/tests/run/i18446.check new file mode 100644 index 000000000000..fb172e33cde4 --- /dev/null +++ b/tests/run/i18446.check @@ -0,0 +1,2 @@ +Task +Task diff --git a/tests/run/i18446/Client.scala b/tests/run/i18446/Client.scala new file mode 100644 index 000000000000..391cd8428953 --- /dev/null +++ b/tests/run/i18446/Client.scala @@ -0,0 +1,5 @@ +package bar; + +object Client extends foo.Task { + def run = foo.Task.poll() +} diff --git a/tests/run/i18446/Task.java b/tests/run/i18446/Task.java new file mode 100644 index 000000000000..c3ada81c143c --- /dev/null +++ b/tests/run/i18446/Task.java @@ -0,0 +1,5 @@ +package foo; + +public abstract class Task{ + protected static void poll(){ System.out.println("Task"); } +} diff --git a/tests/run/i18446/Test.scala b/tests/run/i18446/Test.scala new file mode 100644 index 000000000000..76da0522e2b9 --- /dev/null +++ b/tests/run/i18446/Test.scala @@ -0,0 +1,4 @@ + +@main def Test = + foo.run + bar.Client.run diff --git a/tests/run/i18446/i18446.scala b/tests/run/i18446/i18446.scala new file mode 100644 index 000000000000..938bcb55e023 --- /dev/null +++ b/tests/run/i18446/i18446.scala @@ -0,0 +1,5 @@ +package foo + +def run = { + foo.Task.poll() +} From ebf36e4d6eadc07b0e983075e2c6c7641f157610 Mon Sep 17 00:00:00 2001 From: Oliver Bracevac Date: Tue, 16 Jul 2024 20:30:42 +0200 Subject: [PATCH 2/2] Skip Scala.js in run tests --- tests/run/i18446/Client.scala | 2 ++ tests/run/i18446/Test.scala | 1 + tests/run/i18446/i18446.scala | 2 ++ 3 files changed, 5 insertions(+) diff --git a/tests/run/i18446/Client.scala b/tests/run/i18446/Client.scala index 391cd8428953..1bad08006011 100644 --- a/tests/run/i18446/Client.scala +++ b/tests/run/i18446/Client.scala @@ -1,3 +1,5 @@ +// scalajs: --skip + package bar; object Client extends foo.Task { diff --git a/tests/run/i18446/Test.scala b/tests/run/i18446/Test.scala index 76da0522e2b9..f6c85e39784c 100644 --- a/tests/run/i18446/Test.scala +++ b/tests/run/i18446/Test.scala @@ -1,3 +1,4 @@ +// scalajs: --skip @main def Test = foo.run diff --git a/tests/run/i18446/i18446.scala b/tests/run/i18446/i18446.scala index 938bcb55e023..e67c680990cb 100644 --- a/tests/run/i18446/i18446.scala +++ b/tests/run/i18446/i18446.scala @@ -1,3 +1,5 @@ +// scalajs: --skip + package foo def run = {