Skip to content

Commit

Permalink
Compile time checks for architecture size and records size
Browse files Browse the repository at this point in the history
  • Loading branch information
edubart committed Apr 4, 2020
1 parent 0f32cfa commit 3edc2f2
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 36 deletions.
2 changes: 1 addition & 1 deletion lib/allocators/gc.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ function GC:_mark_ptr(ptr: pointer)
end
end

function GC:_mark_stack() <noinline, cattribute 'no_sanitize(("address"))'>
function GC:_mark_stack() <noinline, nosanitizeaddress>
local stk: pointer
local bot: usize = (@usize)(self.bottom)
local top: usize = (@usize)(&stk)
Expand Down
13 changes: 9 additions & 4 deletions nelua/cbuiltins.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,19 @@ function builtins.nelua_unlikely(context)
end

function builtins.nelua_noinline(context)
define_builtin(context, 'nelua_noinline', "#define nelua_noinline __attribute__((noinline))\n")
define_builtin(context, 'nelua_noinline',
"#define nelua_noinline __attribute__((noinline))\n")
end

function builtins.nelua_noreturn(context)
define_builtin(context, 'nelua_noreturn', "#define nelua_noreturn __attribute__((noreturn))\n")
define_builtin(context, 'nelua_noreturn',
"#define nelua_noreturn __attribute__((noreturn))\n")
end

-- string
function builtins.nelua_nosanitizeaddress(context)
define_builtin(context, 'nelua_nosanitizeaddress',
"#define nelua_nosanitizeaddress __attribute__((no_sanitize_address))\n")
end

-- nil
function builtins.nelua_nilable(context)
Expand All @@ -67,7 +72,7 @@ function builtins.nelua_panic_cstring(context)
context:ensure_runtime_builtin('nelua_stderr_write_cstring')
define_builtin(context, 'nelua_panic_cstring',
'static nelua_noreturn nelua_noinline void nelua_panic_cstring(char* s);\n',
[[inline nelua_noreturn void nelua_panic_cstring(char *s) {
[[nelua_noreturn nelua_noinline void nelua_panic_cstring(char *s) {
nelua_stderr_write_cstring(s);
abort();
}
Expand Down
89 changes: 58 additions & 31 deletions nelua/cgenerator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ typevisitors[types.ArrayType] = function(context, type)
decemitter:add('typedef struct {', type.subtype, ' data[', type.length, '];} ', type.codename)
emit_type_attributes(decemitter, type)
decemitter:add_ln(';')
decemitter:add_ln('nelua_static_assert(sizeof(',type.codename,') == ', type.size,
', "Nelua and C disagree on type size");')
context:add_declaration(decemitter:generate(), type.codename)
end

Expand Down Expand Up @@ -289,6 +291,8 @@ typevisitors[types.RecordType] = function(context, type)
emit_type_attributes(defemitter, type)
defemitter:add_ln(';')
--end
defemitter:add_ln('nelua_static_assert(sizeof(',type.codename,') == ', type.size,
', "Nelua and C disagree on type size");')
table.insert(context.declarations, defemitter:generate())
end

Expand Down Expand Up @@ -1071,11 +1075,24 @@ function visitors.FuncDef(context, node, emitter)
define = false
end

if attr.cexport then qualifier = qualifier .. 'extern ' end
if attr.volatile then qualifier = qualifier .. 'volatile ' end
if attr.inline then qualifier = qualifier .. 'inline ' end
if attr.noinline then qualifier = qualifier .. context:ensure_runtime_builtin('nelua_noinline') .. ' ' end
if attr.noreturn then qualifier = qualifier .. context:ensure_runtime_builtin('nelua_noreturn') .. ' ' end
if attr.cexport then
qualifier = qualifier .. 'extern '
end
if attr.volatile then
qualifier = qualifier .. 'volatile '
end
if attr.inline then
qualifier = qualifier .. 'inline '
end
if attr.noinline then
qualifier = qualifier .. context:ensure_runtime_builtin('nelua_noinline') .. ' '
end
if attr.noreturn then
qualifier = qualifier .. context:ensure_runtime_builtin('nelua_noreturn') .. ' '
end
if attr.nosanitizeaddress then
qualifier = qualifier .. context:ensure_runtime_builtin('nelua_nosanitizeaddress') .. ' '
end
if attr.cqualifier then qualifier = qualifier .. attr.cqualifier .. ' ' end
if attr.cattribute then
qualifier = string.format('%s__attribute__((%s)) ', qualifier, attr.cattribute)
Expand Down Expand Up @@ -1261,40 +1278,49 @@ end

local generator = {}

local function emit_warn_setup(context)
local function emit_features_setup(context)
local emitter = CEmitter(context)
emitter:add_ln('#if defined(__GNUC__) || defined(__clang__)')

-- throw error on missing C bindings
emitter:add_ln('#pragma GCC diagnostic error "-Wimplicit-function-declaration"')
-- importing C functions can cause this warn
emitter:add_ln('#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"')
-- C zero initialization for anything
emitter:add_ln('#pragma GCC diagnostic ignored "-Wmissing-braces"')
-- ignore unknown C attributes used in GC
emitter:add_ln('#pragma GCC diagnostic ignored "-Wattributes"')

-- the code generator may generate unused variables, parameters, functions
emitter:add_ln('#if defined(__clang__)')
emitter:add_ln('#pragma GCC diagnostic ignored "-Wunused"')
emitter:add_ln('#else')
emitter:add_ln('#pragma GCC diagnostic ignored "-Wunused-variable"')
emitter:add_ln('#pragma GCC diagnostic ignored "-Wunused-function"')
emitter:add_ln('#pragma GCC diagnostic ignored "-Wunused-but-set-variable"')
-- for ignoring const* on pointers
emitter:add_ln('#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"')
emitter:add_ln('#endif')

emitter:add_ln('#endif')
do -- warnings
emitter:add_ln('#ifdef __GNUC__')

-- throw error on missing C bindings
emitter:add_ln('#pragma GCC diagnostic error "-Wimplicit-function-declaration"')
-- importing C functions can cause this warn
emitter:add_ln('#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"')
-- C zero initialization for anything
emitter:add_ln('#pragma GCC diagnostic ignored "-Wmissing-braces"')

-- the code generator may generate unused variables, parameters, functions
emitter:add_ln('#if defined(__clang__)')
emitter:add_ln('#pragma GCC diagnostic ignored "-Wunused"')
emitter:add_ln('#else')
emitter:add_ln('#pragma GCC diagnostic ignored "-Wunused-variable"')
emitter:add_ln('#pragma GCC diagnostic ignored "-Wunused-function"')
emitter:add_ln('#pragma GCC diagnostic ignored "-Wunused-but-set-variable"')
-- for ignoring const* on pointers
emitter:add_ln('#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"')
emitter:add_ln('#endif')

emitter:add_ln('#endif')
end
do -- static assert macro
emitter:add([[#if __STDC_VERSION__ >= 201112L
#define nelua_static_assert _Static_assert
#else
#define nelua_static_assert(x, y)
#endif
]])
emitter:add_ln('nelua_static_assert(sizeof(void*) == ', primtypes.pointer.size,
', "Nelua and C disagree on architecture size");')
end
context:add_declaration(emitter:generate())
end

local function emit_main(ast, context)
emit_warn_setup(context)
emit_features_setup(context)
context:add_include('<stddef.h>')
context:add_include('<stdint.h>')
context:add_include('<stdbool.h>')
context:ensure_runtime_builtin('nelua_noinline')

local mainemitter = CEmitter(context, -1)
context.mainemitter = mainemitter
Expand All @@ -1312,6 +1338,7 @@ local function emit_main(ast, context)
mainemitter:add_ln("}")
mainemitter:dec_indent()

context:ensure_runtime_builtin('nelua_noinline')
context:add_declaration('nelua_noinline int nelua_main();\n')
else
mainemitter:inc_indent()
Expand Down
1 change: 1 addition & 0 deletions nelua/typedefs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ typedefs.function_annots = {
inline = true,
noreturn = true,
noinline = true,
nosanitizeaddress = true,
volatile = true,
nodecl = true,
nosideeffect = true,
Expand Down

0 comments on commit 3edc2f2

Please sign in to comment.