mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Error message on bus error or segmentation fault. Some additional SIG… (#848)
* Error message on bus error or segmentation fault. Some additional SIG info. Full debug info by default. Trapping is now debugtrap rather than trap for LLVM. Row now initialized when entering function for stacktrace.
This commit is contained in:
committed by
GitHub
parent
c99f298cad
commit
c7d90baad1
27
.github/workflows/main.yml
vendored
27
.github/workflows/main.yml
vendored
@@ -37,9 +37,9 @@ jobs:
|
|||||||
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\time.c3
|
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\time.c3
|
||||||
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\fannkuch-redux.c3
|
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\fannkuch-redux.c3
|
||||||
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\contextfree\boolerr.c3
|
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\contextfree\boolerr.c3
|
||||||
|
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\ls.c3
|
||||||
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\load_world.c3
|
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\load_world.c3
|
||||||
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\process.c3
|
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\process.c3
|
||||||
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\ls.c3
|
|
||||||
|
|
||||||
|
|
||||||
- name: Build testproject
|
- name: Build testproject
|
||||||
@@ -108,6 +108,7 @@ jobs:
|
|||||||
../build/c3c compile-run examples/fannkuch-redux.c3
|
../build/c3c compile-run examples/fannkuch-redux.c3
|
||||||
../build/c3c compile-run examples/contextfree/boolerr.c3
|
../build/c3c compile-run examples/contextfree/boolerr.c3
|
||||||
../build/c3c compile-run examples/load_world.c3
|
../build/c3c compile-run examples/load_world.c3
|
||||||
|
../build/c3c compile-run examples/load_world.c3
|
||||||
|
|
||||||
- name: Build testproject
|
- name: Build testproject
|
||||||
run: |
|
run: |
|
||||||
@@ -339,31 +340,29 @@ jobs:
|
|||||||
- name: Compile and run some examples
|
- name: Compile and run some examples
|
||||||
run: |
|
run: |
|
||||||
cd resources
|
cd resources
|
||||||
../build/c3c compile examples/base64.c3
|
|
||||||
../build/c3c compile examples/binarydigits.c3
|
|
||||||
../build/c3c compile examples/brainfk.c3
|
|
||||||
../build/c3c compile examples/factorial_macro.c3
|
|
||||||
../build/c3c compile examples/fasta.c3
|
|
||||||
../build/c3c compile examples/gameoflife.c3
|
../build/c3c compile examples/gameoflife.c3
|
||||||
../build/c3c compile examples/hash.c3
|
|
||||||
../build/c3c compile examples/levenshtein.c3
|
../build/c3c compile examples/levenshtein.c3
|
||||||
../build/c3c compile examples/load_world.c3
|
|
||||||
../build/c3c compile examples/map.c3
|
../build/c3c compile examples/map.c3
|
||||||
../build/c3c compile examples/mandelbrot.c3
|
../build/c3c compile examples/mandelbrot.c3
|
||||||
../build/c3c compile examples/plus_minus.c3
|
../build/c3c compile examples/plus_minus.c3
|
||||||
../build/c3c compile examples/nbodies.c3
|
|
||||||
../build/c3c compile examples/spectralnorm.c3
|
../build/c3c compile examples/spectralnorm.c3
|
||||||
../build/c3c compile examples/swap.c3
|
../build/c3c compile examples/swap.c3
|
||||||
../build/c3c compile examples/contextfree/boolerr.c3
|
|
||||||
../build/c3c compile examples/contextfree/dynscope.c3
|
|
||||||
../build/c3c compile examples/contextfree/guess_number.c3
|
../build/c3c compile examples/contextfree/guess_number.c3
|
||||||
../build/c3c compile examples/contextfree/multi.c3
|
../build/c3c compile-run examples/hash.c3
|
||||||
../build/c3c compile examples/contextfree/cleanup.c3
|
../build/c3c compile-run examples/nbodies.c3
|
||||||
|
../build/c3c compile-run examples/contextfree/boolerr.c3
|
||||||
|
../build/c3c compile-run examples/contextfree/dynscope.c3
|
||||||
|
../build/c3c compile-run examples/contextfree/multi.c3
|
||||||
|
../build/c3c compile-run examples/contextfree/cleanup.c3
|
||||||
../build/c3c compile-run examples/hello_world_many.c3
|
../build/c3c compile-run examples/hello_world_many.c3
|
||||||
../build/c3c compile-run examples/time.c3
|
../build/c3c compile-run examples/time.c3
|
||||||
../build/c3c compile-run examples/fannkuch-redux.c3
|
../build/c3c compile-run examples/fannkuch-redux.c3
|
||||||
../build/c3c compile-run examples/contextfree/boolerr.c3
|
|
||||||
../build/c3c compile-run examples/load_world.c3
|
../build/c3c compile-run examples/load_world.c3
|
||||||
|
../build/c3c compile-run examples/base64.c3
|
||||||
|
../build/c3c compile-run examples/binarydigits.c3
|
||||||
|
../build/c3c compile-run examples/brainfk.c3
|
||||||
|
../build/c3c compile-run examples/factorial_macro.c3
|
||||||
|
../build/c3c compile-run examples/fasta.c3
|
||||||
../build/c3c compile-run examples/process.c3
|
../build/c3c compile-run examples/process.c3
|
||||||
|
|
||||||
- name: Compile run unit tests
|
- name: Compile run unit tests
|
||||||
|
|||||||
@@ -285,4 +285,54 @@ macro uint uint128.hash(uint128 i) => (uint)((i >> 96) ^ (i >> 64) ^ (i >> 32) ^
|
|||||||
macro uint bool.hash(bool b) => (uint)b;
|
macro uint bool.hash(bool b) => (uint)b;
|
||||||
macro uint typeid.hash(typeid t) => ((ulong)(uptr)t).hash();
|
macro uint typeid.hash(typeid t) => ((ulong)(uptr)t).hash();
|
||||||
macro uint String.hash(String c) => (uint)fnv32a::encode(c);
|
macro uint String.hash(String c) => (uint)fnv32a::encode(c);
|
||||||
macro uint char[].hash(char[] c) => (uint)fnv32a::encode(c);
|
macro uint char[].hash(char[] c) => (uint)fnv32a::encode(c);
|
||||||
|
|
||||||
|
module std::core::builtin @if((env::LINUX || env::DARWIN) && env::COMPILER_SAFE_MODE && env::DEBUG_SYMBOLS);
|
||||||
|
import libc;
|
||||||
|
|
||||||
|
fn void sig_panic(String message)
|
||||||
|
{
|
||||||
|
$if $defined(io::stderr) && $defined(File.printf):
|
||||||
|
CallstackElement* stack = $$stacktrace();
|
||||||
|
if (stack) stack = stack.prev;
|
||||||
|
if (stack) stack = stack.prev;
|
||||||
|
(void)io::stderr().print("\nERROR: '");
|
||||||
|
(void)io::stderr().print(message);
|
||||||
|
(void)io::stderr().printn("'");
|
||||||
|
while (stack)
|
||||||
|
{
|
||||||
|
(void)io::stderr().printfn(" in function %s (%s:%s)", stack.function, stack.file, stack.line);
|
||||||
|
if (stack == stack.prev) break;
|
||||||
|
stack = stack.prev;
|
||||||
|
}
|
||||||
|
$endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalFunction old_bus_error;
|
||||||
|
SignalFunction old_segmentation_fault;
|
||||||
|
|
||||||
|
fn void sig_bus_error(CInt i)
|
||||||
|
{
|
||||||
|
sig_panic("Illegal memory access.");
|
||||||
|
$$trap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void sig_segmentation_fault(CInt i)
|
||||||
|
{
|
||||||
|
sig_panic("Out of bounds memory access.");
|
||||||
|
$$trap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void install_signal_handler(CInt signal, SignalFunction func) @local
|
||||||
|
{
|
||||||
|
SignalFunction old = libc::signal(signal, func);
|
||||||
|
// Restore
|
||||||
|
if ((iptr)old > 1024) libc::signal(signal, old);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean this up
|
||||||
|
static initialize @priority(101)
|
||||||
|
{
|
||||||
|
install_signal_handler(libc::SIGBUS, &sig_bus_error);
|
||||||
|
install_signal_handler(libc::SIGSEGV, &sig_segmentation_fault);
|
||||||
|
}
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ const bool I128_NATIVE_SUPPORT = $$PLATFORM_I128_SUPPORTED;
|
|||||||
const bool F16_SUPPORT = $$PLATFORM_F16_SUPPORTED;
|
const bool F16_SUPPORT = $$PLATFORM_F16_SUPPORTED;
|
||||||
const bool F128_SUPPORT = $$PLATFORM_F128_SUPPORTED;
|
const bool F128_SUPPORT = $$PLATFORM_F128_SUPPORTED;
|
||||||
const bool COMPILER_SAFE_MODE = $$COMPILER_SAFE_MODE;
|
const bool COMPILER_SAFE_MODE = $$COMPILER_SAFE_MODE;
|
||||||
|
const bool DEBUG_SYMBOLS = $$DEBUG_SYMBOLS;
|
||||||
const usz LLVM_VERSION = $$LLVM_VERSION;
|
const usz LLVM_VERSION = $$LLVM_VERSION;
|
||||||
const bool BENCHMARKING = $$BENCHMARKING;
|
const bool BENCHMARKING = $$BENCHMARKING;
|
||||||
const bool TESTING = $$TESTING;
|
const bool TESTING = $$TESTING;
|
||||||
|
|||||||
@@ -38,6 +38,30 @@ def JmpBuf = uptr[$$JMP_BUF_SIZE];
|
|||||||
def Fd = CInt;
|
def Fd = CInt;
|
||||||
def Fpos_t = long; // TODO make sure fpos is correct on all targets.
|
def Fpos_t = long; // TODO make sure fpos is correct on all targets.
|
||||||
def SignalFunction = fn void(int);
|
def SignalFunction = fn void(int);
|
||||||
|
|
||||||
|
|
||||||
|
const CInt SIGHUP = 1;
|
||||||
|
const CInt SIGINT = 2;
|
||||||
|
const CInt SIGQUIT = 3;
|
||||||
|
const CInt SIGILL = 4;
|
||||||
|
const CInt SIGTRAP = 5;
|
||||||
|
const CInt SIGABTR = 6;
|
||||||
|
const CInt SIGBUS = BSD_FLAVOR_SIG ? 10 : 7; // Or Mips
|
||||||
|
const CInt SIGFPE = 8;
|
||||||
|
const CInt SIGKILL = 9;
|
||||||
|
const CInt SIGSEGV = 11;
|
||||||
|
const CInt SIGSYS = BSD_FLAVOR_SIG ? 12 : 31;
|
||||||
|
const CInt SIGPIPE = 13;
|
||||||
|
const CInt SIGALRM = 14;
|
||||||
|
const CInt SIGTERM = 15;
|
||||||
|
const CInt SIGURG = BSD_FLAVOR_SIG ? 16 : 23;
|
||||||
|
const CInt SIGSTOP = BSD_FLAVOR_SIG ? 17 : 19;
|
||||||
|
const CInt SIGTSTP = BSD_FLAVOR_SIG ? 18 : 20;
|
||||||
|
const CInt SIGCONT = BSD_FLAVOR_SIG ? 19 : 18;
|
||||||
|
const CInt SIGCHLD = BSD_FLAVOR_SIG ? 20 : 17;
|
||||||
|
|
||||||
|
const bool BSD_FLAVOR_SIG @local = env::OPENBSD || env::DARWIN || env::FREEBSD || env::NETBSD;
|
||||||
|
|
||||||
def Time_t = $typefrom(env::WIN32 ? long.typeid : CLong.typeid);
|
def Time_t = $typefrom(env::WIN32 ? long.typeid : CLong.typeid);
|
||||||
def Off_t = $typefrom(env::WIN32 ? int.typeid : usz.typeid);
|
def Off_t = $typefrom(env::WIN32 ? int.typeid : usz.typeid);
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
- Dropped support for LLVM 13-14.
|
- Dropped support for LLVM 13-14.
|
||||||
- Updated grammar and lexer definition.
|
- Updated grammar and lexer definition.
|
||||||
- Removal of `$elif`.
|
- Removal of `$elif`.
|
||||||
|
- `@stdcall` etc removed in favor of `@callconv`
|
||||||
- Empty fault definitions is now an error.
|
- Empty fault definitions is now an error.
|
||||||
- Better errors on incorrect bitstruct syntax.
|
- Better errors on incorrect bitstruct syntax.
|
||||||
- Internal use wildcard type rather than optional wildcard.
|
- Internal use wildcard type rather than optional wildcard.
|
||||||
|
|||||||
@@ -335,31 +335,31 @@ or_stmt_expr
|
|||||||
| or_stmt_expr OR_OP and_expr
|
| or_stmt_expr OR_OP and_expr
|
||||||
;
|
;
|
||||||
|
|
||||||
or_expr_with_suffix
|
suffix_expr
|
||||||
: or_expr
|
: or_expr
|
||||||
| or_expr '?'
|
| or_expr '?'
|
||||||
| or_expr '?' '!'
|
| or_expr '?' '!'
|
||||||
;
|
;
|
||||||
|
|
||||||
or_stmt_expr_with_suffix
|
suffix_stmt_expr
|
||||||
: or_stmt_expr
|
: or_stmt_expr
|
||||||
| or_stmt_expr '?'
|
| or_stmt_expr '?'
|
||||||
| or_stmt_expr '?' '!'
|
| or_stmt_expr '?' '!'
|
||||||
;
|
;
|
||||||
|
|
||||||
ternary_expr
|
ternary_expr
|
||||||
: or_expr_with_suffix
|
: suffix_expr
|
||||||
| or_expr '?' expr ':' ternary_expr
|
| or_expr '?' expr ':' ternary_expr
|
||||||
| or_expr_with_suffix ELVIS ternary_expr
|
| suffix_expr ELVIS ternary_expr
|
||||||
| or_expr_with_suffix OPTELSE ternary_expr
|
| suffix_expr OPTELSE ternary_expr
|
||||||
| lambda_decl implies_body
|
| lambda_decl implies_body
|
||||||
;
|
;
|
||||||
|
|
||||||
ternary_stmt_expr
|
ternary_stmt_expr
|
||||||
: or_stmt_expr_with_suffix
|
: suffix_stmt_expr
|
||||||
| or_stmt_expr '?' expr ':' ternary_expr
|
| or_stmt_expr '?' expr ':' ternary_expr
|
||||||
| or_stmt_expr_with_suffix ELVIS ternary_expr
|
| suffix_stmt_expr ELVIS ternary_expr
|
||||||
| or_stmt_expr_with_suffix OPTELSE ternary_expr
|
| suffix_stmt_expr OPTELSE ternary_expr
|
||||||
| lambda_decl implies_body
|
| lambda_decl implies_body
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ void init_default_build_target(BuildTarget *target, BuildOptions *options)
|
|||||||
.size_optimization_level = SIZE_OPTIMIZATION_NONE,
|
.size_optimization_level = SIZE_OPTIMIZATION_NONE,
|
||||||
.symtab_size = options->symtab_size ? options->symtab_size : DEFAULT_SYMTAB_SIZE,
|
.symtab_size = options->symtab_size ? options->symtab_size : DEFAULT_SYMTAB_SIZE,
|
||||||
.switchrange_max_size = DEFAULT_SWITCHRANGE_MAX_SIZE,
|
.switchrange_max_size = DEFAULT_SWITCHRANGE_MAX_SIZE,
|
||||||
.debug_info = DEBUG_INFO_NONE,
|
.debug_info = DEBUG_INFO_NOT_SET,
|
||||||
.arch_os_target = ARCH_OS_TARGET_DEFAULT,
|
.arch_os_target = ARCH_OS_TARGET_DEFAULT,
|
||||||
.reloc_model = RELOC_DEFAULT,
|
.reloc_model = RELOC_DEFAULT,
|
||||||
.feature.x86_vector_capability = X86VECTOR_DEFAULT,
|
.feature.x86_vector_capability = X86VECTOR_DEFAULT,
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ static void project_add_targets(Project *project, JSONObject *project_data)
|
|||||||
.memory_environment = MEMORY_ENV_NORMAL,
|
.memory_environment = MEMORY_ENV_NORMAL,
|
||||||
.size_optimization_level = SIZE_OPTIMIZATION_NONE,
|
.size_optimization_level = SIZE_OPTIMIZATION_NONE,
|
||||||
.arch_os_target = ARCH_OS_TARGET_DEFAULT,
|
.arch_os_target = ARCH_OS_TARGET_DEFAULT,
|
||||||
.debug_info = DEBUG_INFO_NONE,
|
.debug_info = DEBUG_INFO_NOT_SET,
|
||||||
.symtab_size = DEFAULT_SYMTAB_SIZE,
|
.symtab_size = DEFAULT_SYMTAB_SIZE,
|
||||||
.cc = "cc",
|
.cc = "cc",
|
||||||
.version = "1.0.0",
|
.version = "1.0.0",
|
||||||
|
|||||||
@@ -835,6 +835,7 @@ void compile()
|
|||||||
setup_int_define("OS_TYPE", (uint64_t)platform_target.os, type_int);
|
setup_int_define("OS_TYPE", (uint64_t)platform_target.os, type_int);
|
||||||
setup_int_define("COMPILER_SIZE_OPT_LEVEL", (uint64_t)active_target.size_optimization_level, type_int);
|
setup_int_define("COMPILER_SIZE_OPT_LEVEL", (uint64_t)active_target.size_optimization_level, type_int);
|
||||||
setup_bool_define("COMPILER_SAFE_MODE", active_target.feature.safe_mode);
|
setup_bool_define("COMPILER_SAFE_MODE", active_target.feature.safe_mode);
|
||||||
|
setup_bool_define("DEBUG_SYMBOLS", active_target.debug_info == DEBUG_INFO_FULL);
|
||||||
setup_int_define("LLVM_VERSION", llvm_version_major, type_int);
|
setup_int_define("LLVM_VERSION", llvm_version_major, type_int);
|
||||||
setup_bool_define("BENCHMARKING", active_target.benchmarking);
|
setup_bool_define("BENCHMARKING", active_target.benchmarking);
|
||||||
setup_int_define("JMP_BUF_SIZE", jump_buffer_size(), type_int);
|
setup_int_define("JMP_BUF_SIZE", jump_buffer_size(), type_int);
|
||||||
|
|||||||
@@ -757,7 +757,7 @@ typedef enum
|
|||||||
ATTRIBUTE_ALIGN,
|
ATTRIBUTE_ALIGN,
|
||||||
ATTRIBUTE_BIGENDIAN,
|
ATTRIBUTE_BIGENDIAN,
|
||||||
ATTRIBUTE_BUILTIN,
|
ATTRIBUTE_BUILTIN,
|
||||||
ATTRIBUTE_CDECL,
|
ATTRIBUTE_CALLCONV,
|
||||||
ATTRIBUTE_DEPRECATED,
|
ATTRIBUTE_DEPRECATED,
|
||||||
ATTRIBUTE_DYNAMIC,
|
ATTRIBUTE_DYNAMIC,
|
||||||
ATTRIBUTE_EXPORT,
|
ATTRIBUTE_EXPORT,
|
||||||
@@ -784,11 +784,9 @@ typedef enum
|
|||||||
ATTRIBUTE_PURE,
|
ATTRIBUTE_PURE,
|
||||||
ATTRIBUTE_REFLECT,
|
ATTRIBUTE_REFLECT,
|
||||||
ATTRIBUTE_SECTION,
|
ATTRIBUTE_SECTION,
|
||||||
ATTRIBUTE_STDCALL,
|
|
||||||
ATTRIBUTE_TEST,
|
ATTRIBUTE_TEST,
|
||||||
ATTRIBUTE_UNUSED,
|
ATTRIBUTE_UNUSED,
|
||||||
ATTRIBUTE_USED,
|
ATTRIBUTE_USED,
|
||||||
ATTRIBUTE_VECCALL,
|
|
||||||
ATTRIBUTE_WASM,
|
ATTRIBUTE_WASM,
|
||||||
ATTRIBUTE_WEAK,
|
ATTRIBUTE_WEAK,
|
||||||
ATTRIBUTE_WINMAIN,
|
ATTRIBUTE_WINMAIN,
|
||||||
|
|||||||
@@ -429,8 +429,9 @@ void llvm_emit_stacktrace_definitions(GenContext *c)
|
|||||||
LLVMSetThreadLocal(current_stack, true);
|
LLVMSetThreadLocal(current_stack, true);
|
||||||
LLVMSetInitializer(current_stack, llvm_get_zero_raw(c->ptr_type));
|
LLVMSetInitializer(current_stack, llvm_get_zero_raw(c->ptr_type));
|
||||||
llvm_set_weak(c, current_stack);
|
llvm_set_weak(c, current_stack);
|
||||||
LLVMTypeRef args[5] = { c->ptr_type, c->ptr_type, c->size_type, c->ptr_type, c->size_type };
|
LLVMTypeRef uint_type = llvm_get_type(c, type_uint);
|
||||||
LLVMTypeRef func_type = c->debug.stack_init_fn_type = LLVMFunctionType(LLVMVoidTypeInContext(c->context), args, 5, false);
|
LLVMTypeRef args[6] = { c->ptr_type, c->ptr_type, c->size_type, c->ptr_type, c->size_type, uint_type };
|
||||||
|
LLVMTypeRef func_type = c->debug.stack_init_fn_type = LLVMFunctionType(LLVMVoidTypeInContext(c->context), args, 6, false);
|
||||||
LLVMValueRef func = c->debug.stack_init_fn = LLVMAddFunction(c->module, ".stacktrace_init", func_type);
|
LLVMValueRef func = c->debug.stack_init_fn = LLVMAddFunction(c->module, ".stacktrace_init", func_type);
|
||||||
llvm_set_weak(c, func);
|
llvm_set_weak(c, func);
|
||||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(c->context);
|
LLVMBuilderRef builder = LLVMCreateBuilderInContext(c->context);
|
||||||
@@ -460,6 +461,8 @@ void llvm_emit_stacktrace_definitions(GenContext *c)
|
|||||||
c->debug.current_stack_ptr,
|
c->debug.current_stack_ptr,
|
||||||
stacktrace,
|
stacktrace,
|
||||||
type_alloca_alignment(type_voidptr));
|
type_alloca_alignment(type_voidptr));
|
||||||
|
LLVMValueRef line = llvm_emit_struct_gep_raw(c, stacktrace, slot_type, 3, alignment, &align_to_use);
|
||||||
|
llvm_store_to_ptr_raw_aligned(c, line, LLVMGetParam(func, 5), align_to_use);
|
||||||
LLVMBuildRetVoid(c->builder);
|
LLVMBuildRetVoid(c->builder);
|
||||||
LLVMDisposeBuilder(c->builder);
|
LLVMDisposeBuilder(c->builder);
|
||||||
c->builder = NULL;
|
c->builder = NULL;
|
||||||
@@ -526,8 +529,9 @@ void llvm_emit_body(GenContext *c, LLVMValueRef function, const char *module_nam
|
|||||||
AlignSize alignment = llvm_abi_alignment(c, slot_type);
|
AlignSize alignment = llvm_abi_alignment(c, slot_type);
|
||||||
LLVMValueRef stacktrace = c->debug.stack_slot = llvm_emit_alloca(c, slot_type, alignment, ".$stacktrace");
|
LLVMValueRef stacktrace = c->debug.stack_slot = llvm_emit_alloca(c, slot_type, alignment, ".$stacktrace");
|
||||||
LLVMValueRef args[] = { stacktrace, c->debug.func_name, llvm_const_int(c, type_usz, func_name_len),
|
LLVMValueRef args[] = { stacktrace, c->debug.func_name, llvm_const_int(c, type_usz, func_name_len),
|
||||||
c->debug.file_name, llvm_const_int(c, type_usz, file_name_len) };
|
c->debug.file_name, llvm_const_int(c, type_usz, file_name_len),
|
||||||
LLVMBuildCall2(c->builder, c->debug.stack_init_fn_type, c->debug.stack_init_fn, args, 5, "");
|
llvm_const_int(c, type_uint, body->span.row) };
|
||||||
|
LLVMBuildCall2(c->builder, c->debug.stack_init_fn_type, c->debug.stack_init_fn, args, 6, "");
|
||||||
c->debug.stack_slot_row = LLVMBuildStructGEP2(c->builder, slot_type, c->debug.stack_slot, 3, ".$row");
|
c->debug.stack_slot_row = LLVMBuildStructGEP2(c->builder, slot_type, c->debug.stack_slot, 3, ".$row");
|
||||||
if (function_name == kw_main || function_name == kw_mainstub)
|
if (function_name == kw_main || function_name == kw_mainstub)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1567,6 +1567,47 @@ static const char *attribute_domain_to_string(AttributeDomain domain)
|
|||||||
UNREACHABLE
|
UNREACHABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INLINE bool update_abi(Decl *decl, CallABI abi)
|
||||||
|
{
|
||||||
|
decl->func_decl.signature.abi = abi;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
static bool update_call_abi_from_string(Decl *decl, Expr *expr)
|
||||||
|
{
|
||||||
|
const char *str = expr->const_expr.bytes.ptr;
|
||||||
|
CallABI abi;
|
||||||
|
if (strcmp(str, "cdecl") == 0) return update_abi(decl, CALL_C);
|
||||||
|
if (strcmp(str, "veccall") == 0)
|
||||||
|
{
|
||||||
|
switch (platform_target.arch)
|
||||||
|
{
|
||||||
|
case ARCH_TYPE_X86_64:
|
||||||
|
return update_abi(decl, CALL_X64_VECTOR);
|
||||||
|
case ARCH_TYPE_ARM:
|
||||||
|
case ARCH_TYPE_ARMB:
|
||||||
|
case ARCH_TYPE_AARCH64:
|
||||||
|
case ARCH_TYPE_AARCH64_32:
|
||||||
|
case ARCH_TYPE_AARCH64_BE:
|
||||||
|
return update_abi(decl, CALL_AAPCS_VFP);
|
||||||
|
case ARCH_TYPE_X86:
|
||||||
|
// Unsupported
|
||||||
|
FALLTHROUGH;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strcmp(str, "stdcall") == 0)
|
||||||
|
{
|
||||||
|
if (platform_target.arch == ARCH_TYPE_ARM || platform_target.arch == ARCH_TYPE_ARMB)
|
||||||
|
{
|
||||||
|
return update_abi(decl, CALL_AAPCS);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
SEMA_ERROR(expr, "Unknown call convention, only 'cdecl', 'stdcall' and 'veccall' are supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#define EXPORTED_USER_DEFINED_TYPES ATTR_ENUM | ATTR_UNION | ATTR_STRUCT | ATTR_FAULT
|
#define EXPORTED_USER_DEFINED_TYPES ATTR_ENUM | ATTR_UNION | ATTR_STRUCT | ATTR_FAULT
|
||||||
#define USER_DEFINED_TYPES EXPORTED_USER_DEFINED_TYPES | ATTR_BITSTRUCT
|
#define USER_DEFINED_TYPES EXPORTED_USER_DEFINED_TYPES | ATTR_BITSTRUCT
|
||||||
static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr, AttributeDomain domain, bool *erase_decl)
|
static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr, AttributeDomain domain, bool *erase_decl)
|
||||||
@@ -1577,11 +1618,11 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
|
|||||||
[ATTRIBUTE_ALIGN] = ATTR_FUNC | ATTR_CONST | ATTR_LOCAL | ATTR_GLOBAL | ATTR_BITSTRUCT | ATTR_STRUCT | ATTR_UNION | ATTR_MEMBER,
|
[ATTRIBUTE_ALIGN] = ATTR_FUNC | ATTR_CONST | ATTR_LOCAL | ATTR_GLOBAL | ATTR_BITSTRUCT | ATTR_STRUCT | ATTR_UNION | ATTR_MEMBER,
|
||||||
[ATTRIBUTE_BIGENDIAN] = ATTR_BITSTRUCT,
|
[ATTRIBUTE_BIGENDIAN] = ATTR_BITSTRUCT,
|
||||||
[ATTRIBUTE_BUILTIN] = ATTR_MACRO | ATTR_FUNC | ATTR_GLOBAL | ATTR_CONST,
|
[ATTRIBUTE_BUILTIN] = ATTR_MACRO | ATTR_FUNC | ATTR_GLOBAL | ATTR_CONST,
|
||||||
[ATTRIBUTE_CDECL] = ATTR_FUNC,
|
[ATTRIBUTE_CALLCONV] = ATTR_FUNC,
|
||||||
[ATTRIBUTE_DEPRECATED] = USER_DEFINED_TYPES | ATTR_FUNC | ATTR_MACRO | ATTR_CONST | ATTR_GLOBAL | ATTR_MEMBER,
|
[ATTRIBUTE_DEPRECATED] = USER_DEFINED_TYPES | ATTR_FUNC | ATTR_MACRO | ATTR_CONST | ATTR_GLOBAL | ATTR_MEMBER,
|
||||||
[ATTRIBUTE_DYNAMIC] = ATTR_FUNC,
|
[ATTRIBUTE_DYNAMIC] = ATTR_FUNC,
|
||||||
[ATTRIBUTE_EXPORT] = ATTR_FUNC | ATTR_GLOBAL | ATTR_CONST | EXPORTED_USER_DEFINED_TYPES,
|
[ATTRIBUTE_EXPORT] = ATTR_FUNC | ATTR_GLOBAL | ATTR_CONST | EXPORTED_USER_DEFINED_TYPES,
|
||||||
[ATTRIBUTE_EXTERN] = (AttributeDomain)~(ATTR_CALL | ATTR_BITSTRUCT | ATTR_DEFINE | ATTR_MACRO | ATTR_XXLIZER),
|
[ATTRIBUTE_EXTERN] = ATTR_FUNC | ATTR_GLOBAL | ATTR_CONST | USER_DEFINED_TYPES,
|
||||||
[ATTRIBUTE_IF] = (AttributeDomain)~(ATTR_CALL | ATTR_LOCAL),
|
[ATTRIBUTE_IF] = (AttributeDomain)~(ATTR_CALL | ATTR_LOCAL),
|
||||||
[ATTRIBUTE_INLINE] = ATTR_FUNC | ATTR_CALL,
|
[ATTRIBUTE_INLINE] = ATTR_FUNC | ATTR_CALL,
|
||||||
[ATTRIBUTE_INTERFACE] = ATTR_FUNC,
|
[ATTRIBUTE_INTERFACE] = ATTR_FUNC,
|
||||||
@@ -1600,14 +1641,13 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
|
|||||||
[ATTRIBUTE_PACKED] = ATTR_STRUCT | ATTR_UNION,
|
[ATTRIBUTE_PACKED] = ATTR_STRUCT | ATTR_UNION,
|
||||||
[ATTRIBUTE_PRIORITY] = ATTR_XXLIZER,
|
[ATTRIBUTE_PRIORITY] = ATTR_XXLIZER,
|
||||||
[ATTRIBUTE_PRIVATE] = ATTR_FUNC | ATTR_MACRO | ATTR_GLOBAL | ATTR_CONST | USER_DEFINED_TYPES | ATTR_DEFINE,
|
[ATTRIBUTE_PRIVATE] = ATTR_FUNC | ATTR_MACRO | ATTR_GLOBAL | ATTR_CONST | USER_DEFINED_TYPES | ATTR_DEFINE,
|
||||||
|
[ATTRIBUTE_PUBLIC] = ATTR_FUNC | ATTR_MACRO | ATTR_GLOBAL | ATTR_CONST | USER_DEFINED_TYPES | ATTR_DEFINE,
|
||||||
[ATTRIBUTE_PURE] = ATTR_CALL,
|
[ATTRIBUTE_PURE] = ATTR_CALL,
|
||||||
[ATTRIBUTE_REFLECT] = ATTR_ENUM,
|
[ATTRIBUTE_REFLECT] = ATTR_FUNC | ATTR_GLOBAL | ATTR_CONST | USER_DEFINED_TYPES,
|
||||||
[ATTRIBUTE_SECTION] = ATTR_FUNC | ATTR_CONST | ATTR_GLOBAL,
|
[ATTRIBUTE_SECTION] = ATTR_FUNC | ATTR_CONST | ATTR_GLOBAL,
|
||||||
[ATTRIBUTE_STDCALL] = ATTR_FUNC,
|
|
||||||
[ATTRIBUTE_TEST] = ATTR_FUNC,
|
[ATTRIBUTE_TEST] = ATTR_FUNC,
|
||||||
[ATTRIBUTE_UNUSED] = (AttributeDomain)~(ATTR_CALL | ATTR_XXLIZER),
|
[ATTRIBUTE_UNUSED] = (AttributeDomain)~(ATTR_CALL | ATTR_XXLIZER),
|
||||||
[ATTRIBUTE_USED] = (AttributeDomain)~(ATTR_CALL | ATTR_XXLIZER ),
|
[ATTRIBUTE_USED] = (AttributeDomain)~(ATTR_CALL | ATTR_XXLIZER ),
|
||||||
[ATTRIBUTE_VECCALL] = ATTR_FUNC,
|
|
||||||
[ATTRIBUTE_WASM] = ATTR_FUNC,
|
[ATTRIBUTE_WASM] = ATTR_FUNC,
|
||||||
[ATTRIBUTE_WEAK] = ATTR_FUNC | ATTR_CONST | ATTR_GLOBAL,
|
[ATTRIBUTE_WEAK] = ATTR_FUNC | ATTR_CONST | ATTR_GLOBAL,
|
||||||
[ATTRIBUTE_WINMAIN] = ATTR_FUNC,
|
[ATTRIBUTE_WINMAIN] = ATTR_FUNC,
|
||||||
@@ -1652,25 +1692,16 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
|
|||||||
}
|
}
|
||||||
decl->func_decl.attr_winmain = true;
|
decl->func_decl.attr_winmain = true;
|
||||||
break;
|
break;
|
||||||
case ATTRIBUTE_CDECL:
|
case ATTRIBUTE_CALLCONV:
|
||||||
decl->func_decl.signature.abi = CALL_C;
|
if (expr && !sema_analyse_expr(context, expr)) return false;
|
||||||
break;
|
if (!expr || !expr_is_const_string(expr))
|
||||||
case ATTRIBUTE_VECCALL:
|
|
||||||
switch (platform_target.arch)
|
|
||||||
{
|
{
|
||||||
case ARCH_TYPE_X86_64:
|
SEMA_ERROR(expr, "Expected a constant string value as argument.");
|
||||||
decl->func_decl.signature.abi = CALL_X64_VECTOR;
|
return false;
|
||||||
break;
|
}
|
||||||
case ARCH_TYPE_X86:
|
else
|
||||||
case ARCH_TYPE_ARM:
|
{
|
||||||
case ARCH_TYPE_ARMB:
|
if (!update_call_abi_from_string(decl, expr)) return false;
|
||||||
case ARCH_TYPE_AARCH64:
|
|
||||||
case ARCH_TYPE_AARCH64_32:
|
|
||||||
case ARCH_TYPE_AARCH64_BE:
|
|
||||||
decl->func_decl.signature.abi = CALL_AAPCS_VFP;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ATTRIBUTE_TEST:
|
case ATTRIBUTE_TEST:
|
||||||
@@ -1682,13 +1713,6 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
|
|||||||
case ATTRIBUTE_DYNAMIC:
|
case ATTRIBUTE_DYNAMIC:
|
||||||
decl->func_decl.attr_dynamic = true;
|
decl->func_decl.attr_dynamic = true;
|
||||||
break;
|
break;
|
||||||
case ATTRIBUTE_STDCALL:
|
|
||||||
assert(decl->decl_kind == DECL_FUNC);
|
|
||||||
if (platform_target.arch == ARCH_TYPE_ARM || platform_target.arch == ARCH_TYPE_ARMB)
|
|
||||||
{
|
|
||||||
decl->func_decl.signature.abi = CALL_AAPCS;
|
|
||||||
}
|
|
||||||
break; // Check args
|
|
||||||
case ATTRIBUTE_OPERATOR:
|
case ATTRIBUTE_OPERATOR:
|
||||||
{
|
{
|
||||||
assert(decl->decl_kind == DECL_FUNC || decl->decl_kind == DECL_MACRO);
|
assert(decl->decl_kind == DECL_FUNC || decl->decl_kind == DECL_MACRO);
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ void symtab_init(uint32_t capacity)
|
|||||||
attribute_list[ATTRIBUTE_ALIGN] = KW_DEF("@align");
|
attribute_list[ATTRIBUTE_ALIGN] = KW_DEF("@align");
|
||||||
attribute_list[ATTRIBUTE_BIGENDIAN] = KW_DEF("@bigendian");
|
attribute_list[ATTRIBUTE_BIGENDIAN] = KW_DEF("@bigendian");
|
||||||
attribute_list[ATTRIBUTE_BUILTIN] = KW_DEF("@builtin");
|
attribute_list[ATTRIBUTE_BUILTIN] = KW_DEF("@builtin");
|
||||||
attribute_list[ATTRIBUTE_CDECL] = KW_DEF("@cdecl");
|
attribute_list[ATTRIBUTE_CALLCONV] = KW_DEF("@callconv");
|
||||||
attribute_list[ATTRIBUTE_DEPRECATED] = KW_DEF("@deprecated");
|
attribute_list[ATTRIBUTE_DEPRECATED] = KW_DEF("@deprecated");
|
||||||
attribute_list[ATTRIBUTE_DYNAMIC] = KW_DEF("@dynamic");
|
attribute_list[ATTRIBUTE_DYNAMIC] = KW_DEF("@dynamic");
|
||||||
attribute_list[ATTRIBUTE_EXPORT] = KW_DEF("@export");
|
attribute_list[ATTRIBUTE_EXPORT] = KW_DEF("@export");
|
||||||
@@ -328,11 +328,9 @@ void symtab_init(uint32_t capacity)
|
|||||||
attribute_list[ATTRIBUTE_PUBLIC] = KW_DEF("@public");
|
attribute_list[ATTRIBUTE_PUBLIC] = KW_DEF("@public");
|
||||||
attribute_list[ATTRIBUTE_REFLECT] = KW_DEF("@reflect");
|
attribute_list[ATTRIBUTE_REFLECT] = KW_DEF("@reflect");
|
||||||
attribute_list[ATTRIBUTE_SECTION] = KW_DEF("@section");
|
attribute_list[ATTRIBUTE_SECTION] = KW_DEF("@section");
|
||||||
attribute_list[ATTRIBUTE_STDCALL] = KW_DEF("@stdcall");
|
|
||||||
attribute_list[ATTRIBUTE_TEST] = KW_DEF("@test");
|
attribute_list[ATTRIBUTE_TEST] = KW_DEF("@test");
|
||||||
attribute_list[ATTRIBUTE_UNUSED] = KW_DEF("@unused");
|
attribute_list[ATTRIBUTE_UNUSED] = KW_DEF("@unused");
|
||||||
attribute_list[ATTRIBUTE_USED] = KW_DEF("@used");
|
attribute_list[ATTRIBUTE_USED] = KW_DEF("@used");
|
||||||
attribute_list[ATTRIBUTE_VECCALL] = KW_DEF("@veccall");
|
|
||||||
attribute_list[ATTRIBUTE_WASM] = KW_DEF("@wasm");
|
attribute_list[ATTRIBUTE_WASM] = KW_DEF("@wasm");
|
||||||
attribute_list[ATTRIBUTE_WEAK] = KW_DEF("@weak");
|
attribute_list[ATTRIBUTE_WEAK] = KW_DEF("@weak");
|
||||||
attribute_list[ATTRIBUTE_WINMAIN] = KW_DEF("@winmain");
|
attribute_list[ATTRIBUTE_WINMAIN] = KW_DEF("@winmain");
|
||||||
|
|||||||
@@ -1765,6 +1765,18 @@ void target_setup(BuildTarget *target)
|
|||||||
platform_target.os = os_from_llvm_string(slice_next_token(&target_triple_string, '-'));
|
platform_target.os = os_from_llvm_string(slice_next_token(&target_triple_string, '-'));
|
||||||
platform_target.environment_type = environment_type_from_llvm_string(target_triple_string);
|
platform_target.environment_type = environment_type_from_llvm_string(target_triple_string);
|
||||||
|
|
||||||
|
if (target->debug_info == DEBUG_INFO_NOT_SET)
|
||||||
|
{
|
||||||
|
if (platform_target.os == OS_TYPE_WIN32)
|
||||||
|
{
|
||||||
|
target->debug_info = DEBUG_INFO_NONE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target->debug_info = DEBUG_INFO_FULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
platform_target.float_abi = false;
|
platform_target.float_abi = false;
|
||||||
// TLS should not be supported for:
|
// TLS should not be supported for:
|
||||||
// ARM Cygwin
|
// ARM Cygwin
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
#define COMPILER_VERSION "0.4.563"
|
#define COMPILER_VERSION "0.4.564"
|
||||||
@@ -106,7 +106,7 @@ class Issues:
|
|||||||
def compile(self, args):
|
def compile(self, args):
|
||||||
os.chdir(TEST_DIR)
|
os.chdir(TEST_DIR)
|
||||||
target = ""
|
target = ""
|
||||||
debug = ""
|
debug = "-g0 "
|
||||||
if (self.arch):
|
if (self.arch):
|
||||||
target = " --target " + self.arch
|
target = " --target " + self.arch
|
||||||
if (self.debuginfo):
|
if (self.debuginfo):
|
||||||
|
|||||||
Reference in New Issue
Block a user