Skip to content

Commit 4e903af

Browse files
authored
Handle StackOverflowError in macros (bazel-contrib#1491)
* Handle StackOverflowError in macros
1 parent 69c91a9 commit 4e903af

File tree

5 files changed

+42
-4
lines changed

5 files changed

+42
-4
lines changed

src/java/io/bazel/rulesscala/scalac/ScalacWorker.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@ private static void compileScalaSources(CompileOptions ops, String[] scalaSource
278278
} catch (Throwable ex) {
279279
if (ex.toString().contains("scala.reflect.internal.Types$TypeError")) {
280280
throw new RuntimeException("Build failure with type error", ex);
281+
} else if (ex.toString().contains("java.lang.StackOverflowError")) {
282+
throw new RuntimeException("Build failure with StackOverflowError", ex);
281283
} else if (isMacroException(ex)) {
282284
throw new RuntimeException("Build failure during macro expansion", ex);
283285
} else {

test/shell/test_persistent_worker.sh

100644100755
Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ runner=$(get_test_runner "${1:-local}")
77

88
PERSISTENT_WORKER_FLAGS="--strategy=Scalac=worker --worker_sandboxing"
99

10+
check_persistent_worker_failure() {
11+
command=$1
12+
output=$(bazel ${command} 2>&1)
13+
! (echo "$output" | grep -q -- "---8<---8<---") && echo "$output"
14+
}
15+
1016
test_persistent_worker_success() {
1117
# shellcheck disable=SC2086
1218
bazel build //test:ScalaBinary $PERSISTENT_WORKER_FLAGS
@@ -17,9 +23,8 @@ test_persistent_worker_failure() {
1723
}
1824

1925
test_persistent_worker_handles_exception_in_macro_invocation() {
20-
command="bazel build //test_expect_failure/scalac_exceptions:bad_macro_invocation $PERSISTENT_WORKER_FLAGS"
21-
output=$(${command} 2>&1)
22-
! (echo "$output" | grep -q -- "---8<---8<---") && (echo "$output" | grep -q "Build failure during macro expansion")
26+
command="build //test_expect_failure/scalac_exceptions:bad_macro_invocation $PERSISTENT_WORKER_FLAGS"
27+
check_persistent_worker_failure "$command" | grep -q "Build failure during macro expansion"
2328

2429
RESPONSE_CODE=$?
2530
if [ $RESPONSE_CODE -ne 0 ]; then
@@ -28,6 +33,19 @@ test_persistent_worker_handles_exception_in_macro_invocation() {
2833
fi
2934
}
3035

36+
test_persistent_worker_handles_stack_overflow_exception() {
37+
command="build //test_expect_failure/scalac_exceptions:stack_overflow_macro_invocation $PERSISTENT_WORKER_FLAGS"
38+
check_persistent_worker_failure "$command" | grep -q "Build failure with StackOverflowError"
39+
40+
RESPONSE_CODE=$?
41+
if [ $RESPONSE_CODE -ne 0 ]; then
42+
echo -e "${RED} Scalac persistent worker does not handle StackOverflowError in macro expansion. $NC"
43+
exit 1
44+
fi
45+
}
46+
47+
3148
$runner test_persistent_worker_success
3249
$runner test_persistent_worker_failure
33-
$runner test_persistent_worker_handles_exception_in_macro_invocation
50+
$runner test_persistent_worker_handles_exception_in_macro_invocation
51+
$runner test_persistent_worker_handles_stack_overflow_exception

test_expect_failure/scalac_exceptions/BUILD

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,9 @@ scala_library(
1010
srcs = ["BadMacroInvocation.scala"],
1111
deps = [":bad_macro"],
1212
)
13+
14+
scala_library(
15+
name = "stack_overflow_macro_invocation",
16+
srcs = ["StackOverflowMacroInvocation.scala"],
17+
deps = [":bad_macro"],
18+
)

test_expect_failure/scalac_exceptions/BadMacro.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,17 @@ import scala.language.experimental.macros
22

33
object BadMacro {
44
def badMacro(): Unit = macro badMacroImpl
5+
def stackOverflowMacro(): Unit = macro stackOverflowMacroImpl
56

67
def badMacroImpl(c: scala.reflect.macros.blackbox.Context)(): c.Tree = {
78
throw new NoSuchMethodError()
89
}
10+
11+
def uhOh(n: Int): Int = n + uhOh(n + 1)
12+
13+
def stackOverflowMacroImpl(c: scala.reflect.macros.blackbox.Context)(): c.Tree = {
14+
import c.universe._
15+
uhOh(1)
16+
q""
17+
}
918
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object StackOverflowMacroInvocation {
2+
BadMacro.stackOverflowMacro()
3+
}

0 commit comments

Comments
 (0)