Add --max-macro-iterations to set macro iteration limit.

This commit is contained in:
Christoffer Lerno
2025-10-11 16:26:07 +02:00
parent ae33d1a206
commit 6eee760239
8 changed files with 30 additions and 5 deletions

View File

@@ -9,6 +9,7 @@
- `"build-dir"` option now available for `project.json`, added to project. #2323
- Allow `..` ranges to use "a..a-1" in order to express zero length.
- Disallow aliasing of `@local` symbols with a higher visibility in the alias.
- Add `--max-macro-iterations` to set macro iteration limit.
### Fixes
- Bug in `io::write_using_write_byte`.

View File

@@ -586,6 +586,7 @@ typedef struct BuildOptions_
SanitizeMode sanitize_mode;
uint32_t max_vector_size;
uint32_t max_stack_object_size;
uint32_t max_macro_iterations;
bool print_keywords;
bool print_attributes;
bool print_builtins;
@@ -728,6 +729,7 @@ typedef struct
uint32_t symtab_size;
uint32_t max_vector_size;
uint32_t max_stack_object_size;
uint32_t max_macro_iterations;
uint32_t switchrange_max_size;
uint32_t switchjump_max_size;
const char **args;

View File

@@ -182,6 +182,7 @@ static void usage(bool full)
print_opt("--win-debug=<option>", "Select debug output on Windows: codeview or dwarf (default: codeview).");
print_opt("--max-vector-size <number>", "Set the maximum vector bit size to allow (default: 4096).");
print_opt("--max-stack-object-size <number>", "Set the maximum size of a stack object in KB (default: 128).");
print_opt("--max-macro-iterations <number>", "Set the maximum number of iterations in a macro loop (default: 1048575).");
PRINTF("");
print_opt("--print-linking", "Print linker arguments.");
PRINTF("");
@@ -972,10 +973,18 @@ static void parse_option(BuildOptions *options)
{
int size = (at_end() || next_is_opt()) ? 0 : atoi(next_arg());
if (size < 1) error_exit("Expected a valid positive integer >= 1 for --max-stack-object-size.");
if (size > MAX_STACK_OBJECT_SIZE) error_exit("Expected a valid positive integer <= %u for --max-vector-size.", (unsigned)MAX_STACK_OBJECT_SIZE);
if (size > MAX_STACK_OBJECT_SIZE) error_exit("Expected a valid positive integer <= %u for --max-stack-object-size.", (unsigned)MAX_STACK_OBJECT_SIZE);
options->max_stack_object_size = size;
return;
}
if (match_longopt("max-macro-iterations"))
{
int size = (at_end() || next_is_opt()) ? 0 : atoi(next_arg());
if (size < 1) error_exit("Expected a valid positive integer >= 128 for --max-macro-iterations");
if (size > MAX_MACRO_ITERATIONS) error_exit("Expected a valid positive integer <= %u for --max-macro-iterations.", (unsigned)MAX_MACRO_ITERATIONS);
options->max_macro_iterations = size;
return;
}
if (match_longopt("max-vector-size"))
{
int size = (at_end() || next_is_opt()) ? 0 : atoi(next_arg());

View File

@@ -432,6 +432,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
OVERRIDE_IF_SET(symtab_size);
OVERRIDE_IF_SET(max_vector_size);
OVERRIDE_IF_SET(max_stack_object_size);
OVERRIDE_IF_SET(max_macro_iterations);
OVERRIDE_IF_SET(win.def);
OVERRIDE_IF_SET(no_entry);
OVERRIDE_IF_SET(echo_prefix);
@@ -448,7 +449,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
if (!target->max_vector_size) target->max_vector_size = DEFAULT_VECTOR_WIDTH;
if (!target->max_stack_object_size) target->max_stack_object_size = DEFAULT_STACK_OBJECT_SIZE;
if (!target->max_macro_iterations) target->max_macro_iterations = DEFAULT_MAX_MACRO_ITERATIONS;
if (target->quiet && !options->verbosity_level) options->verbosity_level = -1;
if (options->silence_deprecation || options->verbosity_level < 0) target->silence_deprecation = true;

View File

@@ -42,7 +42,6 @@ typedef uint16_t FileId;
#define INITIAL_SYMBOL_MAP 0x10000
#define INITIAL_GENERIC_SYMBOL_MAP 0x1000
#define MAX_INCLUDE_DIRECTIVES 2048
#define MAX_MACRO_ITERATIONS 0xFFFFFF
#define MAX_PARAMS 255
#define MAX_BITSTRUCT 0x1000
#define MAX_MEMBERS ((StructIndex)1) << 15

View File

@@ -3110,8 +3110,13 @@ static inline bool sema_analyse_ct_for_stmt(SemaContext *context, Ast *statement
// We set a maximum of macro iterations.
// we might consider reducing this.
unsigned current_ct_scope = sema_context_push_ct_stack(context);
for (int i = 0; i < MAX_MACRO_ITERATIONS; i++)
for (int i = 0; ; i++)
{
if (i >= compiler.build.max_macro_iterations)
{
SEMA_ERROR(statement, "Too many iterations in '$for' (it exceeded %d), you can change this limit using '--max-macro-iterations'.", compiler.build.max_macro_iterations);
goto FAILED;
}
sema_context_pop_ct_stack(context, current_ct_scope);
// First evaluate the cond, which we note that we *must* have.
// we need to make a copy

View File

@@ -23,6 +23,8 @@
#define NO_ARENA 0
#define MAX_VECTOR_WIDTH 65536
#define MAX_STACK_OBJECT_SIZE (256 * 1024)
#define MAX_MACRO_ITERATIONS 0xFFFFFF
#define DEFAULT_MAX_MACRO_ITERATIONS 0xFFFFF
#define DEFAULT_VECTOR_WIDTH 4096
#define DEFAULT_STACK_OBJECT_SIZE 64
#define MAX_ARRAY_SIZE INT64_MAX

View File

@@ -0,0 +1,6 @@
fn int main()
{
$for var $i = 0; $i < 1000000000; $i++: // #error: Too many iterations in
$endfor
return 0;
}