From aa216fa51070984e169cf68dd8949d504030b845 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 17 Jul 2023 02:00:27 +0200 Subject: [PATCH] Dev (#859) * Fix bug where analysing subexpr relied on them not being analysed. Fix issue where converting a const initializer bool to integer failed. Fix of issue where the case check assumed other cases were const values. * Fix bug where analysing subexpr relied on them not being analysed. Fix issue where converting a const initializer bool to integer failed. Fix of issue where the case check assumed other cases were const values. Remove PTHREAD for windows. * Fix bug where analysing subexpr relied on them not being analysed. Fix issue where converting a const initializer bool to integer failed. Fix of issue where the case check assumed other cases were const values. Remove PTHREAD for windows. --- .github/workflows/main.yml | 10 ++--- CMakeLists.txt | 30 ++++++++------- resources/examples/constants.c3 | 4 ++ src/compiler/compiler_internal.h | 1 - src/compiler/llvm_codegen.c | 2 + src/compiler/number.c | 1 + src/compiler/sema_casts.c | 1 + src/compiler/sema_expr.c | 4 +- src/compiler/sema_stmts.c | 4 +- src/utils/common.h | 60 ++++++++++++++++++++++++++--- src/utils/errors.c | 2 +- src/utils/errors.h | 65 -------------------------------- src/utils/file_utils.c | 1 - src/utils/taskqueue.c | 2 +- src/utils/vmem.c | 4 +- src/utils/whereami.c | 9 +++-- 16 files changed, 98 insertions(+), 102 deletions(-) create mode 100644 resources/examples/constants.c3 delete mode 100644 src/utils/errors.h diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1f4a5cac7..e616de43e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -40,7 +40,7 @@ jobs: ..\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\process.c3 - + ..\build\${{ matrix.build_type }}\c3c.exe compile --test -g -O0 --threads 1 --target macos-x64 examples\constants.c3 - name: Build testproject run: | @@ -93,8 +93,8 @@ jobs: install: git binutils mingw-w64-x86_64-ninja mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain mingw-w64-x86_64-python - shell: msys2 {0} run: | - pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-llvm-15.0.3-1-any.pkg.tar.zst - pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-lld-15.0.3-1-any.pkg.tar.zst + pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-llvm-16.0.5-1-any.pkg.tar.zst + pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-lld-16.0.5-1-any.pkg.tar.zst - name: CMake run: | cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} @@ -108,7 +108,7 @@ jobs: ../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 --test -g -O0 --threads 1 --target macos-x64 examples/constants.c3 - name: Build testproject run: | @@ -164,7 +164,7 @@ jobs: ../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 --test -g -O0 --threads 1 --target macos-x64 examples/constants.c3 - name: Build testproject run: | cd resources/testproject diff --git a/CMakeLists.txt b/CMakeLists.txt index b00fd6571..3af47df21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,19 +25,24 @@ set(CMAKE_CXX_STANDARD 17) if(MSVC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2 /EHsc") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /O2 /EHsc") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /EHsc") - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Od /Zi /EHsc") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /EHa") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Od /Zi /EHa") else() -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -fno-exceptions") -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gdwarf-3 -fno-exceptions") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -gdwarf-3 -O3 -fno-exceptions") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -gdwarf-3 -fno-exceptions") + if (true) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -fno-exceptions") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gdwarf-3 -fno-exceptions") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -gdwarf-3 -O3 -fno-exceptions") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -gdwarf-3 -fno-exceptions") + else() + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-3 -O3 -fsanitize=undefined -fno-exceptions") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gdwarf-3 -O1 -fsanitize=undefined -fno-exceptions") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -gdwarf-3 -O3 -fsanitize=undefined -fno-exceptions") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -gdwarf-3 -O1 -fsanitize=undefined -fno-exceptions") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fno-exceptions") + endif() endif() -#set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O1 -fsanitize=undefined") -#set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O1 -fsanitize=undefined") -#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -gdwarf-3 -O3 -fsanitize=undefined") -#set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -gdwarf-3 -fsanitize=undefined") -#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined") + + set(C3_LLVM_VERSION "auto" CACHE STRING "Use LLVM version [default: auto]") option(C3_USE_MIMALLOC "Use built-in mimalloc" OFF) @@ -377,9 +382,6 @@ else() target_link_options(c3c PRIVATE -pthread) target_compile_options(c3c PRIVATE -pthread -Wall -Werror -Wno-unknown-pragmas -Wno-unused-result -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter) - if (WIN32) - target_compile_definitions(c3c PRIVATE USE_PTHREAD=1) - endif() endif() diff --git a/resources/examples/constants.c3 b/resources/examples/constants.c3 new file mode 100644 index 000000000..72a34e696 --- /dev/null +++ b/resources/examples/constants.c3 @@ -0,0 +1,4 @@ +const char AA @private = 1; +const char BB = 200 ; +const uint CC @private = ~(uint)(0); +const FOO @private = ~(uint)(0); diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 49a880f14..9d3ef9917 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -3,7 +3,6 @@ // a copy of which can be found in the LICENSE file. #include "../utils/common.h" -#include "../utils/errors.h" #include "../utils/lib.h" #include "../build/build_options.h" #include "compiler.h" diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 637f00531..3835ed3e6 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -504,6 +504,8 @@ static void gencontext_verify_ir(GenContext *context) { if (*error) { + puts("IR integrity failure."); + LLVMDumpModule(context->module); error_exit("Could not verify IR: %s", error); } error_exit("Could not verify module IR."); diff --git a/src/compiler/number.c b/src/compiler/number.c index eb35e77b5..b1726984b 100644 --- a/src/compiler/number.c +++ b/src/compiler/number.c @@ -53,6 +53,7 @@ static inline bool compare_fps(Real left, Real right, BinaryOp op) bool expr_const_compare(const ExprConst *left, const ExprConst *right, BinaryOp op) { bool is_eq; + assert(left->const_kind == right->const_kind); switch (left->const_kind) { case CONST_BOOL: diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index d4bf5ecba..2faac2841 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -1772,6 +1772,7 @@ static void vector_const_initializer_convert_to_type(ConstInitializer *initializ if (is_neg_conversion) { bool is_true = initializer->init_value->const_expr.b; + initializer->init_value->const_expr.const_kind = CONST_INTEGER; initializer->init_value->const_expr.ixx = (Int) { .i = is_true ? (Int128) { UINT64_MAX, UINT64_MAX } : (Int128) { 0, 0 }, .type = to_flat->type_kind }; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index a228f0a6c..c417609bc 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -1022,7 +1022,7 @@ static inline bool sema_binary_promote_top_down(SemaContext *context, Expr *bina static inline bool sema_binary_analyse_subexpr(SemaContext *context, Expr *binary, Expr *left, Expr *right) { // Special handling of f = FOO_BAR - if (right->expr_kind == EXPR_IDENTIFIER && right->identifier_expr.is_const) + if (right->resolve_status != RESOLVE_DONE && right->expr_kind == EXPR_IDENTIFIER && right->identifier_expr.is_const) { if (!sema_analyse_expr(context, left)) return false; if (type_flatten(left->type)->type_kind == TYPE_ENUM) @@ -1031,7 +1031,7 @@ static inline bool sema_binary_analyse_subexpr(SemaContext *context, Expr *binar } } // Special handling of f = FOO_BAR - if (left->expr_kind == EXPR_IDENTIFIER && left->identifier_expr.is_const) + if (left->resolve_status != RESOLVE_DONE && left->expr_kind == EXPR_IDENTIFIER && left->identifier_expr.is_const) { if (!sema_analyse_expr(context, right)) return false; if (type_flatten(right->type)->type_kind == TYPE_ENUM) diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index f91a0cacf..460be5667 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -2083,7 +2083,9 @@ static inline bool sema_check_value_case(SemaContext *context, Type *switch_type { Ast *other = cases[i]; if (other->ast_kind != AST_CASE_STMT) continue; - ExprConst *other_const = &exprptr(other->case_stmt.expr)->const_expr; + Expr *other_expr = exprptr(other->case_stmt.expr); + if (!expr_is_const(other_expr)) continue; + ExprConst *other_const = &other_expr->const_expr; ExprConst *other_to_const = other->case_stmt.to_expr ? &exprptr(other->case_stmt.to_expr)->const_expr : other_const; if (expr_const_in_range(const_expr, other_const, other_to_const)) { diff --git a/src/utils/common.h b/src/utils/common.h index 8e6728e79..92c5d477c 100644 --- a/src/utils/common.h +++ b/src/utils/common.h @@ -11,7 +11,7 @@ #include #include #include -#include "errors.h" +#include #include #define NO_ARENA 0 @@ -64,10 +64,60 @@ #define __unused #endif -#ifdef __GNUC__ + +#if (defined(__GNUC__) && __GNUC__ >= 7) || defined(__clang__) #define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) +#define FALLTHROUGH __attribute__ ((fallthrough)) +#define UNUSED __attribute__((unused)) +#define NORETURN __attribute__((noreturn)) +#define INLINE __attribute__((always_inline)) static inline +#elif defined(_MSC_VER) +#define FALLTHROUGH ((void)0) +#define INLINE static __forceinline +#define NORETURN __declspec(noreturn) +#define UNUSED +#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop)) +#else +#define PACK(__Declaration__) __Declaration__ +#define INLINE static inline +#define FALLTHROUGH ((void)0) +#define UNUSED +#define NORETURN #endif -#ifdef _MSC_VER -#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop)) -#endif \ No newline at end of file +#define INFO_LOG(_string, ...) \ + do { \ + if (!debug_log) break; \ + printf("-- INFO: "); printf(_string, ##__VA_ARGS__); printf("\n"); \ + } while (0) +#ifdef NDEBUG +#define REMINDER(_string, ...) do {} while (0) +#define DEBUG_LOG(_string, ...) do {} while(0) +#else +#define REMINDER(_string, ...) do { if (!debug_log) break; printf("TODO: %s -> in %s @ %s:%d\n", _string, __func__, __FILE__, __LINE__ , ##__VA_ARGS__); } while(0) +#define DEBUG_LOG(_string, ...) \ + do { \ + if (!debug_log) break; \ + printf("-- DEBUG: "); printf(_string, ##__VA_ARGS__); printf("\n"); \ + } while (0) +#endif + +#define FATAL_ERROR(_string, ...) do { error_exit("FATAL ERROR %s -> in %s @ in %s:%d ", _string, __func__, __FILE__, __LINE__, ##__VA_ARGS__); } while(0) + +#define ASSERT(_condition, _string, ...) while (!(_condition)) { FATAL_ERROR(_string, ##__VA_ARGS__); } + +#define UNREACHABLE FATAL_ERROR("Should be unreachable"); + +#define TODO FATAL_ERROR("TODO reached"); +#define UNSUPPORTED do { error_exit("Unsupported functionality"); } while (0) + +#define TEST_ASSERT(condition_, string_) while (!(condition_)) { FATAL_ERROR(string_); } +#define TEST_ASSERTF(condition_, string_, ...) while (!(condition_)) { char* str_ = str_printf(string_, __VA_ARGS__); FATAL_ERROR(str_); } + +#define EXPECT(_string, _value, _expected) \ + do { long long __tempval1 = _value; long long __tempval2 = _expected; \ + TEST_ASSERT(__tempval1 == __tempval2, "Checking " _string ": expected %lld but was %lld.", __tempval2, __tempval1); } while(0) + +void evprintf(const char *format, va_list list); +void eprintf(const char *format, ...); +NORETURN void error_exit(const char *format, ...) ; diff --git a/src/utils/errors.c b/src/utils/errors.c index 6637f0270..69d5eb95f 100644 --- a/src/utils/errors.c +++ b/src/utils/errors.c @@ -2,7 +2,7 @@ // Use of this source code is governed by the GNU LGPLv3.0 license // a copy of which can be found in the LICENSE file. -#include "errors.h" +#include "common.h" #include "lib.h" #include diff --git a/src/utils/errors.h b/src/utils/errors.h deleted file mode 100644 index e7a073dff..000000000 --- a/src/utils/errors.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once - -// Copyright (c) 2019 Christoffer Lerno. All rights reserved. -// Use of this source code is governed by the GNU LGPLv3.0 license -// a copy of which can be found in the LICENSE file. - -#include -#include - - -#define INFO_LOG(_string, ...) \ - do { \ - if (!debug_log) break; \ - printf("-- INFO: "); printf(_string, ##__VA_ARGS__); printf("\n"); \ - } while (0) -#ifdef NDEBUG -#define REMINDER(_string, ...) do {} while (0) -#define DEBUG_LOG(_string, ...) do {} while(0) -#else -#define REMINDER(_string, ...) do { if (!debug_log) break; printf("TODO: %s -> in %s @ %s:%d\n", _string, __func__, __FILE__, __LINE__ , ##__VA_ARGS__); } while(0) -#define DEBUG_LOG(_string, ...) \ - do { \ - if (!debug_log) break; \ - printf("-- DEBUG: "); printf(_string, ##__VA_ARGS__); printf("\n"); \ - } while (0) -#endif - -#define FATAL_ERROR(_string, ...) do { error_exit("FATAL ERROR %s -> in %s @ in %s:%d ", _string, __func__, __FILE__, __LINE__, ##__VA_ARGS__); } while(0) - -#define ASSERT(_condition, _string, ...) while (!(_condition)) { FATAL_ERROR(_string, ##__VA_ARGS__); } - -#define UNREACHABLE FATAL_ERROR("Should be unreachable"); - -#if (defined(__GNUC__) && __GNUC__ >= 7) || defined(__clang__) -#define FALLTHROUGH __attribute__ ((fallthrough)) -#define UNUSED __attribute__((unused)) -#define NORETURN __attribute__((noreturn)) -#define INLINE __attribute__((always_inline)) static inline -#elif defined(_MSC_VER) -#define FALLTHROUGH ((void)0) -#define INLINE static __forceinline -#define NORETURN __declspec(noreturn) -#define UNUSED -#else -#define INLINE static inline -#define FALLTHROUGH ((void)0) -#define UNUSED -#define NORETURN -#endif - - - -#define TODO FATAL_ERROR("TODO reached"); -#define UNSUPPORTED do { error_exit("Unsupported functionality"); } while (0) - -#define TEST_ASSERT(condition_, string_) while (!(condition_)) { FATAL_ERROR(string_); } -#define TEST_ASSERTF(condition_, string_, ...) while (!(condition_)) { char* str_ = str_printf(string_, __VA_ARGS__); FATAL_ERROR(str_); } - -#define EXPECT(_string, _value, _expected) \ - do { long long __tempval1 = _value; long long __tempval2 = _expected; \ - TEST_ASSERT(__tempval1 == __tempval2, "Checking " _string ": expected %lld but was %lld.", __tempval2, __tempval1); } while(0) - -void evprintf(const char *format, va_list list); -void eprintf(const char *format, ...); -NORETURN void error_exit(const char *format, ...) ; diff --git a/src/utils/file_utils.c b/src/utils/file_utils.c index 83c3c110c..651b62d06 100644 --- a/src/utils/file_utils.c +++ b/src/utils/file_utils.c @@ -5,7 +5,6 @@ #include #include #include "common.h" -#include "errors.h" #include "lib.h" #if PLATFORM_WINDOWS diff --git a/src/utils/taskqueue.c b/src/utils/taskqueue.c index 1100bedaa..45bcd24d2 100644 --- a/src/utils/taskqueue.c +++ b/src/utils/taskqueue.c @@ -62,7 +62,7 @@ typedef struct TaskQueue_ Task **queue; } TaskQueue; -static DWORD WINAPI taskqueue_thread(LPVOID lpParam) +static unsigned WINAPI taskqueue_thread(LPVOID lpParam) { TaskQueue *task_queue = (TaskQueue *)lpParam; bool is_active = false; diff --git a/src/utils/vmem.c b/src/utils/vmem.c index 7587ce63b..e3ec5538e 100644 --- a/src/utils/vmem.c +++ b/src/utils/vmem.c @@ -9,8 +9,8 @@ #include #endif -#if defined(WIN32) -#include +#if PLATFORM_WINDOWS +#include #define COMMIT_PAGE_SIZE 0x10000 #endif diff --git a/src/utils/whereami.c b/src/utils/whereami.c index 28700d7e4..e4fe9480e 100644 --- a/src/utils/whereami.c +++ b/src/utils/whereami.c @@ -4,12 +4,13 @@ // Code based off Gregory Pakosz's whereami. -#if defined(WIN32) +#include "whereami.h" +#include "common.h" + +#if PLATFORM_WINDOWS #include #endif -#include "whereami.h" - #include #ifndef NOINLINE @@ -30,7 +31,7 @@ #error unsupported compiler #endif -#if defined(_WIN32) +#if PLATFORM_WINDOWS #if defined(_MSC_VER) #pragma warning(push, 3)