mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 20:11:17 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b096e396d8 | ||
|
|
443ee75ccd | ||
|
|
f4751737e4 | ||
|
|
596e550882 | ||
|
|
54ddc9a81c |
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@@ -401,7 +401,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
llvm_version: [17, 18, 19, 20]
|
llvm_version: [19, 20]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
|
||||||
set(C3_LLVM_MIN_VERSION 17)
|
set(C3_LLVM_MIN_VERSION 19)
|
||||||
set(C3_LLVM_MAX_VERSION 22)
|
set(C3_LLVM_MAX_VERSION 22)
|
||||||
set(C3_LLVM_DEFAULT_VERSION 21)
|
set(C3_LLVM_DEFAULT_VERSION 21)
|
||||||
|
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ See the `build-with-docker.sh` script for more information on other configurable
|
|||||||
#### Installing on OS X using Homebrew
|
#### Installing on OS X using Homebrew
|
||||||
|
|
||||||
1. Install [Homebrew](https://brew.sh/)
|
1. Install [Homebrew](https://brew.sh/)
|
||||||
2. Install LLVM 17+: `brew install llvm`
|
2. Install LLVM 19+: `brew install llvm`
|
||||||
3. Install lld: `brew install lld`
|
3. Install lld: `brew install lld`
|
||||||
4. Install CMake: `brew install cmake`
|
4. Install CMake: `brew install cmake`
|
||||||
5. Clone the C3C github repository: `git clone https://github.com/c3lang/c3c.git`
|
5. Clone the C3C github repository: `git clone https://github.com/c3lang/c3c.git`
|
||||||
@@ -505,7 +505,7 @@ After compilation, the `c3c` binary will be located in the `build` directory. Yo
|
|||||||
#### Compiling on other Linux / Unix variants
|
#### Compiling on other Linux / Unix variants
|
||||||
|
|
||||||
1. Install CMake.
|
1. Install CMake.
|
||||||
2. Install or compile LLVM and LLD *libraries* (version 17+ or higher)
|
2. Install or compile LLVM and LLD *libraries* (version 19+ or higher)
|
||||||
3. Clone the C3C github repository: `git clone https://github.com/c3lang/c3c.git`
|
3. Clone the C3C github repository: `git clone https://github.com/c3lang/c3c.git`
|
||||||
4. Enter the C3C directory `cd c3c`.
|
4. Enter the C3C directory `cd c3c`.
|
||||||
5. Set up CMake build for debug: `cmake -B build -S .`. At this point you may need to manually
|
5. Set up CMake build for debug: `cmake -B build -S .`. At this point you may need to manually
|
||||||
|
|||||||
@@ -317,6 +317,9 @@ macro any.retype_to(&self, typeid type)
|
|||||||
return $$any_make(self.ptr, type);
|
return $$any_make(self.ptr, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<*
|
||||||
|
@require (bool)self.type : "A typed any was expected"
|
||||||
|
*>
|
||||||
macro any.as_inner(&self)
|
macro any.as_inner(&self)
|
||||||
{
|
{
|
||||||
return $$any_make(self.ptr, self.type.inner);
|
return $$any_make(self.ptr, self.type.inner);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ faultdef VALUE_OUT_OF_RANGE, VALUE_OUT_OF_UNSIGNED_RANGE;
|
|||||||
|
|
||||||
<*
|
<*
|
||||||
@require $Type.kindof.is_int() : "Type was not an integer"
|
@require $Type.kindof.is_int() : "Type was not an integer"
|
||||||
|
@require (bool)v.type : "The value was empty"
|
||||||
@require v.type.kindof == ENUM : "Value was not an enum"
|
@require v.type.kindof == ENUM : "Value was not an enum"
|
||||||
*>
|
*>
|
||||||
macro any_to_enum_ordinal(any v, $Type)
|
macro any_to_enum_ordinal(any v, $Type)
|
||||||
@@ -16,6 +17,7 @@ macro any_to_enum_ordinal(any v, $Type)
|
|||||||
|
|
||||||
<*
|
<*
|
||||||
@require $Type.kindof.is_int() : "Type was not an integer"
|
@require $Type.kindof.is_int() : "Type was not an integer"
|
||||||
|
@require (bool)v.type : "The value was empty"
|
||||||
@require v.type.kindof.is_int() : "Value was not an integer"
|
@require v.type.kindof.is_int() : "Value was not an integer"
|
||||||
*>
|
*>
|
||||||
macro any_to_int(any v, $Type)
|
macro any_to_int(any v, $Type)
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
# C3C Release Notes
|
# C3C Release Notes
|
||||||
|
|
||||||
|
## 0.7.11 Change list
|
||||||
|
|
||||||
|
### Changes / improvements
|
||||||
|
- Removed support for LLVM 17, 18.
|
||||||
|
- Detect large temporaries when creating slices on the stack #2665
|
||||||
|
|
||||||
|
### Stdlib changes
|
||||||
|
- Add contract on `any_to_enum_ordinal` and `any_to_int` to improve error when passed an empty any. #2977
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- `@deprecated` in function contracts would be processed twice, causing a compilation error despite being correct.
|
||||||
|
|
||||||
## 0.7.10 Change list
|
## 0.7.10 Change list
|
||||||
|
|
||||||
### Changes / improvements
|
### Changes / improvements
|
||||||
|
|||||||
@@ -835,11 +835,7 @@ static void llvm_codegen_setup()
|
|||||||
intrinsic_id.fshl = lookup_intrinsic("llvm.fshl");
|
intrinsic_id.fshl = lookup_intrinsic("llvm.fshl");
|
||||||
intrinsic_id.fshr = lookup_intrinsic("llvm.fshr");
|
intrinsic_id.fshr = lookup_intrinsic("llvm.fshr");
|
||||||
intrinsic_id.gather = lookup_intrinsic("llvm.masked.gather");
|
intrinsic_id.gather = lookup_intrinsic("llvm.masked.gather");
|
||||||
#if LLVM_VERSION_MAJOR < 16
|
|
||||||
intrinsic_id.get_rounding = lookup_intrinsic("llvm.flt.rounds");
|
|
||||||
#else
|
|
||||||
intrinsic_id.get_rounding = lookup_intrinsic("llvm.get.rounding");
|
intrinsic_id.get_rounding = lookup_intrinsic("llvm.get.rounding");
|
||||||
#endif
|
|
||||||
intrinsic_id.lifetime_end = lookup_intrinsic("llvm.lifetime.end");
|
intrinsic_id.lifetime_end = lookup_intrinsic("llvm.lifetime.end");
|
||||||
intrinsic_id.lifetime_start = lookup_intrinsic("llvm.lifetime.start");
|
intrinsic_id.lifetime_start = lookup_intrinsic("llvm.lifetime.start");
|
||||||
intrinsic_id.llrint = lookup_intrinsic("llvm.llrint");
|
intrinsic_id.llrint = lookup_intrinsic("llvm.llrint");
|
||||||
|
|||||||
@@ -113,35 +113,20 @@ void llvm_emit_debug_function(GenContext *c, Decl *decl)
|
|||||||
|
|
||||||
static void llvm_emit_debug_value(GenContext *c, LLVMValueRef value, LLVMMetadataRef debug_val, unsigned row, unsigned col, LLVMMetadataRef scope)
|
static void llvm_emit_debug_value(GenContext *c, LLVMValueRef value, LLVMMetadataRef debug_val, unsigned row, unsigned col, LLVMMetadataRef scope)
|
||||||
{
|
{
|
||||||
#if LLVM_VERSION_MAJOR < 19
|
|
||||||
LLVMDIBuilderInsertDbgValueAtEnd(c->debug.builder, value, debug_val,
|
|
||||||
LLVMDIBuilderCreateExpression(c->debug.builder, NULL, 0),
|
|
||||||
llvm_create_debug_location_with_inline(c, row, col, c->debug.function),
|
|
||||||
LLVMGetInsertBlock(c->builder));
|
|
||||||
#else
|
|
||||||
LLVMDIBuilderInsertDbgValueRecordAtEnd(c->debug.builder, value, debug_val,
|
LLVMDIBuilderInsertDbgValueRecordAtEnd(c->debug.builder, value, debug_val,
|
||||||
LLVMDIBuilderCreateExpression(c->debug.builder, NULL, 0),
|
LLVMDIBuilderCreateExpression(c->debug.builder, NULL, 0),
|
||||||
llvm_create_debug_location_with_inline(c, row, col, c->debug.function),
|
llvm_create_debug_location_with_inline(c, row, col, c->debug.function),
|
||||||
LLVMGetInsertBlock(c->builder));
|
LLVMGetInsertBlock(c->builder));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void llvm_emit_debug_declare(GenContext *c, LLVMValueRef var, LLVMMetadataRef debug_var, unsigned row, unsigned col, LLVMMetadataRef scope)
|
static void llvm_emit_debug_declare(GenContext *c, LLVMValueRef var, LLVMMetadataRef debug_var, unsigned row, unsigned col, LLVMMetadataRef scope)
|
||||||
{
|
{
|
||||||
#if LLVM_VERSION_MAJOR < 19
|
|
||||||
LLVMDIBuilderInsertDeclareAtEnd(c->debug.builder,
|
|
||||||
var, debug_var,
|
|
||||||
LLVMDIBuilderCreateExpression(c->debug.builder, NULL, 0),
|
|
||||||
llvm_create_debug_location_with_inline(c, row, col, scope),
|
|
||||||
LLVMGetInsertBlock(c->builder));
|
|
||||||
#else
|
|
||||||
LLVMDIBuilderInsertDeclareRecordAtEnd(c->debug.builder,
|
LLVMDIBuilderInsertDeclareRecordAtEnd(c->debug.builder,
|
||||||
var, debug_var,
|
var, debug_var,
|
||||||
LLVMDIBuilderCreateExpression(c->debug.builder, NULL, 0),
|
LLVMDIBuilderCreateExpression(c->debug.builder, NULL, 0),
|
||||||
llvm_create_debug_location_with_inline(c, row, col, scope),
|
llvm_create_debug_location_with_inline(c, row, col, scope),
|
||||||
LLVMGetInsertBlock(c->builder));
|
LLVMGetInsertBlock(c->builder));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void llvm_emit_debug_local_var(GenContext *c, Decl *decl)
|
void llvm_emit_debug_local_var(GenContext *c, Decl *decl)
|
||||||
|
|||||||
@@ -1958,6 +1958,7 @@ static bool parse_element_contract(ParseContext *c, ContractDescription *contrac
|
|||||||
INLINE void attach_deprecation_from_contract(ParseContext *c, ContractDescription *contract, Decl *decl)
|
INLINE void attach_deprecation_from_contract(ParseContext *c, ContractDescription *contract, Decl *decl)
|
||||||
{
|
{
|
||||||
if (contract->deprecated) vec_add(decl->attributes, contract->deprecated);
|
if (contract->deprecated) vec_add(decl->attributes, contract->deprecated);
|
||||||
|
contract->deprecated = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3649,6 +3650,7 @@ Decl *parse_top_level_statement(ParseContext *c, ParseContext **context_out)
|
|||||||
break;
|
break;
|
||||||
case TOKEN_FN:
|
case TOKEN_FN:
|
||||||
decl = parse_func_definition(c, &contracts, c->unit->is_interface_file ? FUNC_PARSE_C3I : FUNC_PARSE_REGULAR);
|
decl = parse_func_definition(c, &contracts, c->unit->is_interface_file ? FUNC_PARSE_C3I : FUNC_PARSE_REGULAR);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TOKEN_CT_ASSERT:
|
case TOKEN_CT_ASSERT:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -843,7 +843,6 @@ ConstInitializer *sema_merge_bitstruct_const_initializers(ConstInitializer *lhs,
|
|||||||
|
|
||||||
bool sema_expr_analyse_initializer_list(SemaContext *context, Type *to, Expr *expr, bool *no_match_ref)
|
bool sema_expr_analyse_initializer_list(SemaContext *context, Type *to, Expr *expr, bool *no_match_ref)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!to) to = type_untypedlist;
|
if (!to) to = type_untypedlist;
|
||||||
ASSERT(to);
|
ASSERT(to);
|
||||||
Type *flattened = type_flatten(to);
|
Type *flattened = type_flatten(to);
|
||||||
@@ -881,6 +880,16 @@ bool sema_expr_analyse_initializer_list(SemaContext *context, Type *to, Expr *ex
|
|||||||
// Resolve this as an inferred array.
|
// Resolve this as an inferred array.
|
||||||
Type *type = type_get_inferred_array(flattened->array.base);
|
Type *type = type_get_inferred_array(flattened->array.base);
|
||||||
if (!sema_expr_analyse_initializer(context, type, type, expr, no_match_ref)) return false;
|
if (!sema_expr_analyse_initializer(context, type, type, expr, no_match_ref)) return false;
|
||||||
|
if (context->call_env.kind == CALL_ENV_FUNCTION && type_size(expr->type) > compiler.build.max_stack_object_size * 1024)
|
||||||
|
{
|
||||||
|
size_t size = type_size(expr->type);
|
||||||
|
RETURN_SEMA_ERROR(
|
||||||
|
expr, "The size of this stack allocated expression (%s%d Kb) exceeds the maximum allowed stack object size (%d Kb), "
|
||||||
|
"you can increase this limit with --max-stack-object-size, but be aware that too large objects "
|
||||||
|
"allocated on the stack may lead to the stack running out of memory.", size % 1024 == 0 ? "" : "over ",
|
||||||
|
size / 1024,
|
||||||
|
compiler.build.max_stack_object_size);
|
||||||
|
}
|
||||||
if (expr_is_const_initializer(expr))
|
if (expr_is_const_initializer(expr))
|
||||||
{
|
{
|
||||||
ConstInitializer *init = expr->const_expr.initializer;
|
ConstInitializer *init = expr->const_expr.initializer;
|
||||||
@@ -931,6 +940,7 @@ bool sema_expr_analyse_initializer_list(SemaContext *context, Type *to, Expr *ex
|
|||||||
NO_MATCH:
|
NO_MATCH:
|
||||||
*no_match_ref = true;
|
*no_match_ref = true;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void const_init_rewrite_to_value(ConstInitializer *const_init, Expr *value)
|
void const_init_rewrite_to_value(ConstInitializer *const_init, Expr *value)
|
||||||
|
|||||||
@@ -1689,11 +1689,6 @@ static AlignData os_target_alignment_of_int(OsType os, ArchType arch, uint32_t b
|
|||||||
case ARCH_TYPE_XTENSA:
|
case ARCH_TYPE_XTENSA:
|
||||||
return (AlignData) { MIN(64u, bits), MIN(64u, bits) };
|
return (AlignData) { MIN(64u, bits), MIN(64u, bits) };
|
||||||
case ARCH_TYPE_X86_64:
|
case ARCH_TYPE_X86_64:
|
||||||
#if LLVM_AVAILABLE && LLVM_VERSION_MAJOR < 18
|
|
||||||
return (AlignData) { MIN(64u, bits), MIN(64u, bits) };
|
|
||||||
#else
|
|
||||||
FALLTHROUGH;
|
|
||||||
#endif
|
|
||||||
case ARCH_TYPE_RISCV64:
|
case ARCH_TYPE_RISCV64:
|
||||||
return (AlignData) { bits, bits };
|
return (AlignData) { bits, bits };
|
||||||
case ARCH_TYPE_WASM64:
|
case ARCH_TYPE_WASM64:
|
||||||
@@ -1709,9 +1704,7 @@ static AlignData os_target_alignment_of_int(OsType os, ArchType arch, uint32_t b
|
|||||||
return (AlignData) { bits, bits };
|
return (AlignData) { bits, bits };
|
||||||
case ARCH_TYPE_X86:
|
case ARCH_TYPE_X86:
|
||||||
if (bits <= 32) return (AlignData) { bits, bits };
|
if (bits <= 32) return (AlignData) { bits, bits };
|
||||||
#if !LLVM_AVAILABLE || LLVM_VERSION_MAJOR > 17
|
|
||||||
if (bits == 128) return (AlignData) { 128, 128 };
|
if (bits == 128) return (AlignData) { 128, 128 };
|
||||||
#endif
|
|
||||||
if (os == OS_TYPE_ELFIAMCU) return (AlignData) { 32, 32 };
|
if (os == OS_TYPE_ELFIAMCU) return (AlignData) { 32, 32 };
|
||||||
if (os == OS_TYPE_WIN32 || os == OS_TYPE_NACL) return (AlignData) { 64, 64 };
|
if (os == OS_TYPE_WIN32 || os == OS_TYPE_NACL) return (AlignData) { 64, 64 };
|
||||||
return (AlignData) { 32, 64 };
|
return (AlignData) { 32, 64 };
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#define COMPILER_VERSION "0.7.10"
|
#define COMPILER_VERSION "0.7.11"
|
||||||
#define PRERELEASE 0
|
#define PRERELEASE 1
|
||||||
|
|||||||
10
test/test_suite/slices/huge_temp_slice.c3
Normal file
10
test/test_suite/slices/huge_temp_slice.c3
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
module main;
|
||||||
|
|
||||||
|
char[] one_mb2 = { [0..(1024*1024)-1] = 0xA5 };
|
||||||
|
fn int main()
|
||||||
|
{
|
||||||
|
char[] one_mb;
|
||||||
|
one_mb = { [0..(1024*1024)-1] = 0xA5 }; // #error: The size of this stack allocated expression
|
||||||
|
one_mb2 = { [0..(1024*1024)-1] = 0xA5 }; // #error: The size of this stack allocated expression
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
#include "llvm/Transforms/Scalar/JumpThreading.h"
|
#include "llvm/Transforms/Scalar/JumpThreading.h"
|
||||||
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
||||||
#include "llvm/Analysis/GlobalsModRef.h"
|
#include "llvm/Analysis/GlobalsModRef.h"
|
||||||
static_assert(LLVM_VERSION_MAJOR >= 17, "Unsupported LLVM version, 17+ is needed.");
|
static_assert(LLVM_VERSION_MAJOR >= 19, "Unsupported LLVM version, 19+ is needed.");
|
||||||
|
|
||||||
#define LINK_SIG \
|
#define LINK_SIG \
|
||||||
bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, \
|
bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, \
|
||||||
@@ -96,9 +96,7 @@ static bool llvm_link(ObjFormat format, const char **args, int arg_count, const
|
|||||||
for (int i = 0; i < arg_count; i++) arg_vector.push_back(strdup(args[i]));
|
for (int i = 0; i < arg_count; i++) arg_vector.push_back(strdup(args[i]));
|
||||||
std::string output_string {};
|
std::string output_string {};
|
||||||
std::string output_err_string {};
|
std::string output_err_string {};
|
||||||
/*
|
|
||||||
llvm::raw_string_ostream output { output_string };
|
|
||||||
llvm::raw_string_ostream output_err { output_err_string };*/
|
|
||||||
llvm::raw_ostream &output = llvm::outs();
|
llvm::raw_ostream &output = llvm::outs();
|
||||||
llvm::raw_ostream &output_err = llvm::errs();
|
llvm::raw_ostream &output_err = llvm::errs();
|
||||||
bool success;
|
bool success;
|
||||||
@@ -154,9 +152,8 @@ bool llvm_run_passes(LLVMModuleRef m, LLVMTargetMachineRef tm, LLVMPasses *passe
|
|||||||
PTO.SLPVectorization = passes->opt.slp_vectorize;
|
PTO.SLPVectorization = passes->opt.slp_vectorize;
|
||||||
PTO.MergeFunctions = passes->opt.merge_functions;
|
PTO.MergeFunctions = passes->opt.merge_functions;
|
||||||
PTO.CallGraphProfile = true; // We always use integrated ASM
|
PTO.CallGraphProfile = true; // We always use integrated ASM
|
||||||
#if LLVM_VERSION_MAJOR > 16
|
|
||||||
PTO.UnifiedLTO = false;
|
PTO.UnifiedLTO = false;
|
||||||
#endif
|
|
||||||
llvm::PassBuilder PB(Machine, PTO, std::nullopt, &PIC);
|
llvm::PassBuilder PB(Machine, PTO, std::nullopt, &PIC);
|
||||||
|
|
||||||
llvm::LoopAnalysisManager LAM;
|
llvm::LoopAnalysisManager LAM;
|
||||||
|
|||||||
Reference in New Issue
Block a user