Skip to content

Commit 13e9b61

Browse files
committed
Prevent unexpected segmentation fault with -O1
The interpreter relies on tail call optimization, which is enabled when using -O2 and -O3 optimization levels. Consequently, if the optimization level is set to -O1, the interpreter may encounter a segmentation fault due to the absence of tail-optimized calls. In practice, GCC uses the term "tail" as a synonym. Formally, it applies to functions that have a return type of the same size and a parameter list with the same total word size. A sibling call is a special case of a tail call where the caller function and callee function do not need to be the same, but they must have compatible stack footprints. This means that the return types of both functions must be the same, and the arguments being passed must occupy the same amount of stack space. Every tail recursive call is considered a sibling call since the definition implies that every function is a sibling of itself. Why make this distinction? Because of the identical stack footprint, replacing the stack frame becomes relatively easier. Compiler developer do not have to resize the stack frame, and in-place mutation becomes straightforward. To ensure efficient instruction dispatch, it is necessary to pass the option "-foptimize-sibling-calls" to GCC/Clang. Known issue: A segmentation fault occurs when compiler optimization is disabled (i.e., "-O0").
1 parent 7aa4ea2 commit 13e9b61

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ endif
9090

9191
# For tail-call elimination, we need a specific set of build flags applied.
9292
# FIXME: On macOS + Apple Silicon, -fno-stack-protector might have a negative impact.
93-
$(OUT)/emulate.o: CFLAGS += $(CFLAGS_NO_CET) -fomit-frame-pointer -fno-stack-check -fno-stack-protector
93+
$(OUT)/emulate.o: CFLAGS += $(CFLAGS_NO_CET) -foptimize-sibling-calls -fomit-frame-pointer -fno-stack-check -fno-stack-protector
9494

9595
# Clear the .DEFAULT_GOAL special variable, so that the following turns
9696
# to the first target after .DEFAULT_GOAL is not set.

0 commit comments

Comments
 (0)