mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Limit vector max size, default is 4096 bits, but may be increased using --max-vector-size.
This commit is contained in:
@@ -120,6 +120,7 @@ const String COMPILER_BUILD_HASH = $$BUILD_HASH;
|
||||
const String COMPILER_BUILD_DATE = $$BUILD_DATE;
|
||||
const OsType OS_TYPE = OsType.from_ordinal($$OS_TYPE);
|
||||
const ArchType ARCH_TYPE = ArchType.from_ordinal($$ARCH_TYPE);
|
||||
const usz MAX_VECTOR_SIZE = $$MAX_VECTOR_SIZE;
|
||||
const bool ARCH_32_BIT = $$REGISTER_SIZE == 32;
|
||||
const bool ARCH_64_BIT = $$REGISTER_SIZE == 64;
|
||||
const bool LIBC = $$COMPILER_LIBC_AVAILABLE;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
- Deprecate `MyEnum.elements`.
|
||||
- Deprecate `SomeFn.params`.
|
||||
- Improve error message when encountering recursively defined structs. #2146
|
||||
- Limit vector max size, default is 4096 bits, but may be increased using --max-vector-size.
|
||||
|
||||
### Fixes
|
||||
- Assert triggered when casting from `int[2]` to `uint[2]` #2115
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "../version.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_SYMTAB_SIZE (1024 * 1024)
|
||||
#define MAX_BUILD_LIB_DIRS 1024
|
||||
#define MAX_COMMAND_LINE_FILES 4096
|
||||
#define MAX_COMMAND_LINE_RUN_ARGS 2048
|
||||
@@ -578,6 +579,7 @@ typedef struct BuildOptions_
|
||||
RiscvFloatCapability riscv_float_capability;
|
||||
MemoryEnvironment memory_environment;
|
||||
SanitizeMode sanitize_mode;
|
||||
uint32_t max_vector_size;
|
||||
bool print_keywords;
|
||||
bool print_attributes;
|
||||
bool print_builtins;
|
||||
@@ -702,6 +704,7 @@ typedef struct
|
||||
CompilerBackend backend;
|
||||
LinkerType linker_type;
|
||||
uint32_t symtab_size;
|
||||
uint32_t max_vector_size;
|
||||
uint32_t switchrange_max_size;
|
||||
uint32_t switchjump_max_size;
|
||||
const char **args;
|
||||
|
||||
@@ -168,6 +168,7 @@ static void usage(bool full)
|
||||
print_opt("--fp-math=<option>", "FP math behaviour: strict, relaxed, fast.");
|
||||
print_opt("--win64-simd=<option>", "Win64 SIMD ABI: array, 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).");
|
||||
PRINTF("");
|
||||
print_opt("--print-linking", "Print linker arguments.");
|
||||
PRINTF("");
|
||||
@@ -771,7 +772,11 @@ static void parse_option(BuildOptions *options)
|
||||
if (at_end() || next_is_opt()) error_exit("error: --symtab needs a valid integer.");
|
||||
const char *symtab_string = next_arg();
|
||||
int symtab = atoi(symtab_string);
|
||||
if (symtab < 1024) PRINTF("Expected a valid positive integer >= 1024.");
|
||||
if (symtab < 1024) error_exit("Expected the --symtab size to be valid positive integer >= 1024.");
|
||||
if (symtab > MAX_SYMTAB_SIZE)
|
||||
{
|
||||
error_exit("The symtab size is too large. The maximum size is %d.", (int)MAX_SYMTAB_SIZE);
|
||||
}
|
||||
options->symtab_size = next_highest_power_of_2(symtab);
|
||||
return;
|
||||
}
|
||||
@@ -887,6 +892,17 @@ static void parse_option(BuildOptions *options)
|
||||
options->riscv_float_capability = parse_opt_select(RiscvFloatCapability, argopt, riscv_capability);
|
||||
return;
|
||||
}
|
||||
if ((argopt = match_argopt("max-vector-size")))
|
||||
{
|
||||
int size = atoi(next_arg());
|
||||
if (size < 128) error_exit("Expected a valid positive integer >= 128 or --max-vector-size.");
|
||||
if (size > MAX_VECTOR_WIDTH) error_exit("Expected a valid positive integer <= %u for --max-vector-size.", (unsigned)MAX_VECTOR_WIDTH);
|
||||
if (size != next_highest_power_of_2(size))
|
||||
{
|
||||
error_exit("The --max-vector-size value must be a power of 2, try using %u instead.", next_highest_power_of_2(size));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ((argopt = match_argopt("memory-env")))
|
||||
{
|
||||
options->memory_environment = parse_opt_select(MemoryEnvironment, argopt, memory_environment);
|
||||
|
||||
@@ -403,6 +403,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
OVERRIDE_IF_SET(testfn);
|
||||
OVERRIDE_IF_SET(benchfn);
|
||||
OVERRIDE_IF_SET(symtab_size);
|
||||
OVERRIDE_IF_SET(max_vector_size);
|
||||
OVERRIDE_IF_SET(win.def);
|
||||
OVERRIDE_IF_SET(no_entry);
|
||||
|
||||
@@ -416,6 +417,8 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
OVERRIDE_IF_SET(android.ndk_path);
|
||||
OVERRIDE_IF_SET(android.api_version);
|
||||
|
||||
if (!target->max_vector_size) target->max_vector_size = DEFAULT_VECTOR_WIDTH;
|
||||
|
||||
if (options->silence_deprecation || options->verbosity_level < 0) target->silence_deprecation = options->silence_deprecation || options->verbosity_level < 0;
|
||||
target->print_linking = options->print_linking || options->verbosity_level > 1;
|
||||
|
||||
|
||||
@@ -143,7 +143,6 @@ const char* project_target_keys[][2] = {
|
||||
const int project_target_keys_count = ELEMENTLEN(project_target_keys);
|
||||
const int project_deprecated_target_keys_count = ELEMENTLEN(project_deprecated_target_keys);
|
||||
|
||||
#define MAX_SYMTAB_SIZE (1024 * 1024)
|
||||
#define GET_SETTING(type__, key__, strings__, comment__) \
|
||||
(type__)get_valid_string_setting(context, json, key__, strings__, 0, ELEMENTLEN(strings__), comment__)
|
||||
|
||||
@@ -276,6 +275,21 @@ static void load_into_build_target(BuildParseContext context, JSONObject *json,
|
||||
target->symtab_size = (uint32_t)symtab_size;
|
||||
}
|
||||
|
||||
// Vector size
|
||||
long vector_size = get_valid_integer(context, json, "max-vector-size", false);
|
||||
if (vector_size > 0)
|
||||
{
|
||||
if (vector_size < 128)
|
||||
{
|
||||
error_exit("Error reading %s: max vector size was less than 128.", context.file);
|
||||
}
|
||||
if (vector_size > MAX_VECTOR_WIDTH)
|
||||
{
|
||||
error_exit("Error reading %s: max vector width may not exceed %d.", context.file, MAX_VECTOR_WIDTH);
|
||||
}
|
||||
target->max_vector_size = (uint32_t)vector_size;
|
||||
}
|
||||
|
||||
// Target
|
||||
const char *arch_os_string = get_optional_string(context, json, "target");
|
||||
if (arch_os_string)
|
||||
|
||||
@@ -1456,6 +1456,7 @@ void compile()
|
||||
setup_int_define("C_LONG_SIZE", compiler.platform.width_c_long, type_int);
|
||||
setup_int_define("C_LONG_LONG_SIZE", compiler.platform.width_c_long_long, type_int);
|
||||
setup_int_define("REGISTER_SIZE", compiler.platform.width_register, type_int);
|
||||
setup_int_define("MAX_VECTOR_SIZE", compiler.build.max_vector_size, type_int);
|
||||
setup_bool_define("C_CHAR_IS_SIGNED", compiler.platform.signed_c_char);
|
||||
setup_bool_define("PLATFORM_BIG_ENDIAN", compiler.platform.big_endian);
|
||||
setup_bool_define("PLATFORM_I128_SUPPORTED", compiler.platform.int128);
|
||||
|
||||
@@ -81,11 +81,11 @@ bool sema_resolve_array_like_len(SemaContext *context, TypeInfo *type_info, Arra
|
||||
}
|
||||
|
||||
// Check max values.
|
||||
if (int_icomp(len, is_vector ? MAX_VECTOR_WIDTH : MAX_ARRAY_SIZE, BINARYOP_GT))
|
||||
if (int_icomp(len, is_vector ? compiler.build.max_vector_size / 8 : MAX_ARRAY_SIZE, BINARYOP_GT))
|
||||
{
|
||||
if (is_vector)
|
||||
{
|
||||
SEMA_ERROR(len_expr, "A vector may not exceed %d in width.", MAX_VECTOR_WIDTH);
|
||||
SEMA_ERROR(len_expr, "A vector may not exceed %d in bit width.", compiler.build.max_vector_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -190,6 +190,15 @@ static inline bool sema_resolve_array_type(SemaContext *context, TypeInfo *type,
|
||||
if (!sema_check_array_type(context, type, type->array.base->type, kind, len, &type->type)) return type_info_poison(type);
|
||||
ASSERT(!type->array.len || sema_cast_const(type->array.len));
|
||||
type->resolve_status = RESOLVE_DONE;
|
||||
if (kind == TYPE_INFO_VECTOR)
|
||||
{
|
||||
if (kind == TYPE_INFO_VECTOR && type_size(type->type) > compiler.build.max_vector_size / 8)
|
||||
{
|
||||
RETURN_SEMA_ERROR(type, "Vectors with bitsize over %u are not supported (this vector is %llu bits), "
|
||||
"but you can increase the maximum allowed using '--max-vector-size'.",
|
||||
compiler.build.max_vector_size, (unsigned long long)type_size(type->type) * 8);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#define NO_ARENA 0
|
||||
#define MAX_VECTOR_WIDTH 65536
|
||||
#define DEFAULT_VECTOR_WIDTH 4096
|
||||
#define MAX_ARRAY_SIZE INT64_MAX
|
||||
#define MAX_SOURCE_LOCATION_LEN 255
|
||||
#define PROJECT_JSON "project.json"
|
||||
|
||||
5
test/test_suite/vector/vector_limit.c3
Normal file
5
test/test_suite/vector/vector_limit.c3
Normal file
@@ -0,0 +1,5 @@
|
||||
fn void main()
|
||||
{
|
||||
double[<65>] x; // #error: Vectors with bitsize over
|
||||
$echo $sizeof(x) * 8;
|
||||
}
|
||||
@@ -81,16 +81,16 @@ fn void test_hash()
|
||||
(uint[<100>]){}.hash();
|
||||
(uint[100]){}.hash();
|
||||
(long){}.hash();
|
||||
(long[<100>]){}.hash();
|
||||
(long[<20>]){}.hash();
|
||||
(long[100]){}.hash();
|
||||
(ulong){}.hash();
|
||||
(ulong[<100>]){}.hash();
|
||||
(ulong[<20>]){}.hash();
|
||||
(ulong[100]){}.hash();
|
||||
(int128){}.hash();
|
||||
(int128[<100>]){}.hash();
|
||||
(int128[<20>]){}.hash();
|
||||
(int128[100]){}.hash();
|
||||
(uint128){}.hash();
|
||||
(uint128[<100>]){}.hash();
|
||||
(uint128[<20>]){}.hash();
|
||||
(uint128[100]){}.hash();
|
||||
(bool){}.hash();
|
||||
(bool[<100>]){}.hash();
|
||||
@@ -122,16 +122,16 @@ fn void test_hash_repeat()
|
||||
assert((uint[<100>]){}.hash() == (uint[<100>]){}.hash());
|
||||
assert((uint[100]){}.hash() == (uint[100]){}.hash());
|
||||
assert((long){}.hash() == (long){}.hash());
|
||||
assert((long[<100>]){}.hash() == (long[<100>]){}.hash());
|
||||
assert((long[<20>]){}.hash() == (long[<20>]){}.hash());
|
||||
assert((long[100]){}.hash() == (long[100]){}.hash());
|
||||
assert((ulong){}.hash() == (ulong){}.hash());
|
||||
assert((ulong[<100>]){}.hash() == (ulong[<100>]){}.hash());
|
||||
assert((ulong[<20>]){}.hash() == (ulong[<20>]){}.hash());
|
||||
assert((ulong[100]){}.hash() == (ulong[100]){}.hash());
|
||||
assert((int128){}.hash() == (int128){}.hash());
|
||||
assert((int128[<100>]){}.hash() == (int128[<100>]){}.hash());
|
||||
assert((int128[<20>]){}.hash() == (int128[<20>]){}.hash());
|
||||
assert((int128[100]){}.hash() == (int128[100]){}.hash());
|
||||
assert((uint128){}.hash() == (uint128){}.hash());
|
||||
assert((uint128[<100>]){}.hash() == (uint128[<100>]){}.hash());
|
||||
assert((uint128[<20>]){}.hash() == (uint128[<20>]){}.hash());
|
||||
assert((uint128[100]){}.hash() == (uint128[100]){}.hash());
|
||||
assert((bool){}.hash() == (bool){}.hash());
|
||||
assert((bool[<100>]){}.hash() == (bool[<100>]){}.hash());
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
module std::os::process @test;
|
||||
// Currently disabled as they somewhat mess up the test output.
|
||||
module std::os::process @test @if(false);
|
||||
import std::os, std::io;
|
||||
|
||||
fn void test_inherit_stdio_stdout()
|
||||
|
||||
Reference in New Issue
Block a user