Fix Segmentation when Compiling druntime
Task Accomplished
After moving the newScope function (which is a semantic import) from attrib.d to dsymbolsem.d, and turning it into a visitor. I encountered an error with the following description:
make[2]: Entering directory '/home/dencomac/DL/dmd/druntime'
../generated/linux/release/64/dmd -c -conf= -Isrc -Iimport -w -de -preview=dip1000 -preview=fieldwise -m64 -fPIC -preview=dtorfields -O -release -inline -version=Shared -fPIC -version=Shared -fPIC -I. -P=-I. src/core/stdc/errno.c -of../generated/linux/release/64/errno_c.o
make[2]: *** [Makefile:394: ../generated/linux/release/64/errno_c.o] Segmentation fault
make[2]: Leaving directory '/home/dencomac/DL/dmd/druntime'
make[1]: *** [Makefile:89: druntime] Error 2
make[1]: Leaving directory '/home/dencomac/DL/dmd'
make: *** [posix.mak:8: all] Error 2
It became a challenge to me and to the reviewers. It was a runtime error. Although the dmd compiler was built successfully, when druntime(core runtime library that provides essential low-level support for the D) was tested, it failed.
Druntime, in combination with the D standard library Phobos, provides a complete ecosystem for building D applications.
It was later found out that the DeprecatedDeclaration function was not properly type casted.
What do I mean?
DeprecatedDeclaration inherits from StorageClassDeclaration. This allows the function to access properties or methods that are specific to StorageClassDeclaration.
Error code:
override void visit(DeprecatedDeclaration dpd) {
auto scx = (cast(StorageClassDeclaration)dpd).newScope(sc); // The enclosing scope is deprecated as well
if (scx == sc)
scx = sc.push();
scx.depdecl = dpd;
sc = scx;
}
The code above casts dpd (of type DeprecatedDeclaration) to StorageClassDeclaration and then tries to call newScope on it. The cast failed at runtime because dpd does not have a relation to StorageClassDeclaration. That resulted in a segfault.
Modified code:
override void visit(DeprecatedDeclaration dpd)
{
auto oldsc = sc;
visit((cast(StorageClassDeclaration)dpd)); // Delegates to the parent visit method
auto scx = sc;
sc = oldsc; // Restores the original scope
// The enclosing scope is deprecated as well
if (scx == sc)
scx = sc.push(); // Pushes a new scope if no changes have been made
scx.depdecl = dpd;
sc = scx;
}
sc is saved into oldsc before any changes are made. Thereafter, visit((cast(StorageClassDeclaration)dpd))
calls the parent visit() method for StorageClassDeclaration,
allowing for any scope adjustments associated with this type.
The updated scope is now stored in sc.
The main aim was to restore the scope where appropriate.
Commit link
https://github.com/dlang/dmd/pull/16880)](
https://github.com/dlang/dmd/pull/16880)
The error took most of my time and made me research a little on what segmentation error and type casting in D lang is, with the help of a youtube video from Mike shah [Dlang Episode 47] D Language - Casting with ‘cast’
Summary
In conclusion, segmentation fault occurs when a program tries to access memory that it is not authorized to access, or that does not exist. Some scenarios that can cause it is as follows: Modifying a String Literal, Accessing an Address that is Freed, invalid cast OR Dereferencing Uninitialized.
Next on the task
Completely remove all other functions that depends on dsymbolsem in attrib.d and move to Cond.d refactoring although the previous PR has been merged but a lot a work needs to be done.