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:
Christoffer Lerno
2023-07-13 15:25:06 +02:00
committed by GitHub
parent c99f298cad
commit c7d90baad1
16 changed files with 179 additions and 67 deletions

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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.

View File

@@ -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
; ;

View File

@@ -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,

View File

@@ -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",

View File

@@ -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);

View File

@@ -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,

View File

@@ -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)
{ {

View File

@@ -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);

View File

@@ -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");

View File

@@ -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

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.563" #define COMPILER_VERSION "0.4.564"

View File

@@ -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):