| author | |
| committer | |
| log | 7c81cd30de876f8bc56a4c689372e4d388b8608c |
| tree | 792c0783c39807575e40abd2d467e64e17d5d889 |
| parent | 373785ae8d49d0ae3785020f05573763268ee9e1 |
17 files changed, 238 insertions(+), 60 deletions(-)
CMakeLists.txt+26-10| ... | ... | @@ -130,16 +130,21 @@ else() |
| 130 | 130 | add_library(embedded_lld_lib ${EMBEDDED_LLD_LIB_SOURCES}) |
| 131 | 131 | add_library(embedded_lld_elf ${EMBEDDED_LLD_ELF_SOURCES}) |
| 132 | 132 | add_library(embedded_lld_coff ${EMBEDDED_LLD_COFF_SOURCES}) |
| 133 | if(MINGW) | |
| 134 | set(UNIQUE_COMPILE_FLAGS "-fno-exceptions -fno-rtti -Wno-comment") | |
| 135 | elseif(MSVC) | |
| 136 | set(UNIQUE_COMPILE_FLAGS "-D_MSVC") | |
| 137 | endif() | |
| 133 | 138 | set_target_properties(embedded_lld_lib PROPERTIES |
| 134 | COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment" | |
| 139 | COMPILE_FLAGS "-std=c++11 ${UNIQUE_COMPILE_FLAGS}" | |
| 135 | 140 | LINK_FLAGS " " |
| 136 | 141 | ) |
| 137 | 142 | set_target_properties(embedded_lld_elf PROPERTIES |
| 138 | COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment" | |
| 143 | COMPILE_FLAGS "-std=c++11 ${UNIQUE_COMPILE_FLAGS}" | |
| 139 | 144 | LINK_FLAGS " " |
| 140 | 145 | ) |
| 141 | 146 | set_target_properties(embedded_lld_coff PROPERTIES |
| 142 | COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment" | |
| 147 | COMPILE_FLAGS "-std=c++11 ${UNIQUE_COMPILE_FLAGS}" | |
| 143 | 148 | LINK_FLAGS " " |
| 144 | 149 | ) |
| 145 | 150 | target_include_directories(embedded_lld_lib PUBLIC |
| ... | ... | @@ -211,14 +216,17 @@ include_directories( |
| 211 | 216 | "${CMAKE_SOURCE_DIR}/src" |
| 212 | 217 | ) |
| 213 | 218 | |
| 214 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -Wall") | |
| 215 | ||
| 216 | ||
| 219 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") | |
| 217 | 220 | if(MINGW) |
| 218 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-error=format= -Wno-error=format -Wno-error=format-extra-args") | |
| 221 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Werror -Wno-error=format= -Wno-error=format -Wno-error=format-extra-args") | |
| 219 | 222 | endif() |
| 220 | 223 | |
| 221 | set(EXE_CFLAGS "-std=c++11 -fno-exceptions -fno-rtti -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Werror=strict-prototypes -Werror=old-style-definition -Werror=type-limits -Wno-missing-braces") | |
| 224 | set(EXE_CFLAGS "-std=c++11") | |
| 225 | if(MINGW) | |
| 226 | set(EXE_CFLAGS "${EXE_CFLAGS} -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE -fno-exceptions -fno-rtti -Werror=strict-prototypes -Werror=old-style-definition -Werror=type-limits -Wno-missing-braces") | |
| 227 | elseif(MSVC) | |
| 228 | set(EXE_CFLAGS "${EXE_CFLAGS} -D_MSVC") | |
| 229 | endif() | |
| 222 | 230 | set(EXE_LDFLAGS " ") |
| 223 | 231 | if(ZIG_TEST_COVERAGE) |
| 224 | 232 | set(EXE_CFLAGS "${EXE_CFLAGS} -fprofile-arcs -ftest-coverage") |
| ... | ... | @@ -230,16 +238,23 @@ set_target_properties(zig PROPERTIES |
| 230 | 238 | COMPILE_FLAGS ${EXE_CFLAGS} |
| 231 | 239 | LINK_FLAGS ${EXE_LDFLAGS} |
| 232 | 240 | ) |
| 241 | ||
| 242 | if(MINGW) | |
| 243 | set(PLATFORM_LIBRARIES quadmath) | |
| 244 | endif() | |
| 233 | 245 | target_link_libraries(zig LINK_PUBLIC |
| 234 | 246 | ${CLANG_LIBRARIES} |
| 235 | 247 | ${LLD_LIBRARIES} |
| 236 | 248 | ${LLVM_LIBRARIES} |
| 237 | 249 | ${CMAKE_THREAD_LIBS_INIT} |
| 238 | quadmath | |
| 250 | ${PLATFORM_LIBRARIES} | |
| 239 | 251 | ) |
| 240 | if(MINGW) | |
| 252 | if(MINGW OR MSVC) | |
| 241 | 253 | target_link_libraries(zig LINK_PUBLIC version) |
| 242 | 254 | endif() |
| 255 | if(MSVC) | |
| 256 | target_link_libraries(zig LINK_PUBLIC "C:/Program Files (x86)/Microsoft Visual Studio 14.0/DIA SDK/lib/diaguids.lib") | |
| 257 | endif() | |
| 243 | 258 | install(TARGETS zig DESTINATION bin) |
| 244 | 259 | |
| 245 | 260 | install(FILES "${CMAKE_SOURCE_DIR}/c_headers/__clang_cuda_builtin_vars.h" DESTINATION "${C_HEADERS_DEST}") |
| ... | ... | @@ -455,3 +470,4 @@ if (ZIG_TEST_COVERAGE) |
| 455 | 470 | COMMAND rm coverage.info coverage.info.cleaned |
| 456 | 471 | ) |
| 457 | 472 | endif() |
| 473 |
cmake/Findclang.cmake+7-1| ... | ... | @@ -8,14 +8,20 @@ |
| 8 | 8 | |
| 9 | 9 | find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h |
| 10 | 10 | PATHS |
| 11 | ${LLVM_INSTALL_PREFIX}/include | |
| 11 | 12 | /usr/lib/llvm/5/include |
| 12 | 13 | /usr/lib/llvm-5.0/include |
| 13 | 14 | /mingw64/include) |
| 14 | 15 | |
| 15 | macro(FIND_AND_ADD_CLANG_LIB _libname_) | |
| 16 | if(NOT CLANG_INCLUDE_DIRS) | |
| 17 | message(FATAL_ERROR "Failed to find CLANG header files") | |
| 18 | endif() | |
| 19 | ||
| 20 | macro(FIND_AND_ADD_CLANG_LIB _libname_) | |
| 16 | 21 | string(TOUPPER ${_libname_} _prettylibname_) |
| 17 | 22 | find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_} |
| 18 | 23 | PATHS |
| 24 | ${LLVM_INSTALL_PREFIX}/lib | |
| 19 | 25 | /usr/lib/llvm/5/lib |
| 20 | 26 | /usr/lib/llvm-5.0/lib |
| 21 | 27 | /mingw64/lib |
cmake/Findllvm.cmake+35-10| ... | ... | @@ -2,28 +2,53 @@ |
| 2 | 2 | # This file is MIT licensed. |
| 3 | 3 | # See http://opensource.org/licenses/MIT |
| 4 | 4 | |
| 5 | # LLVM_FOUND | |
| 6 | 5 | # LLVM_INCLUDE_DIR |
| 7 | 6 | # LLVM_LIBRARIES |
| 8 | 7 | # LLVM_LIBDIRS |
| 9 | 8 | |
| 10 | find_program(LLVM_CONFIG_EXE | |
| 11 | NAMES llvm-config-5.0 llvm-config | |
| 12 | PATHS | |
| 13 | "/mingw64/bin" | |
| 14 | "/c/msys64/mingw64/bin" | |
| 15 | "c:/msys64/mingw64/bin" | |
| 16 | "C:/Libraries/llvm-5.0.0/bin") | |
| 9 | if(LLVM_INSTALL_PREFIX) | |
| 10 | find_program(LLVM_CONFIG_EXE | |
| 11 | NAMES llvm-config-5.0 llvm-config | |
| 12 | PATHS ${LLVM_INSTALL_PREFIX}/bin | |
| 13 | NO_DEFAULT_PATH) | |
| 14 | if(NOT LLVM_CONFIG_EXE) | |
| 15 | message(FATAL_ERROR "Invalid LLVM_INSTALL_PREFIX \"${LLVM_INSTALL_PREFIX}\", could not find llvm-config") | |
| 16 | endif() | |
| 17 | else() | |
| 18 | find_program(LLVM_CONFIG_EXE | |
| 19 | NAMES llvm-config-5.0 llvm-config | |
| 20 | PATHS | |
| 21 | "/mingw64/bin" | |
| 22 | "/c/msys64/mingw64/bin" | |
| 23 | "c:/msys64/mingw64/bin" | |
| 24 | "C:/Libraries/llvm-5.0.0/bin") | |
| 25 | if(NOT LLVM_CONFIG_EXE) | |
| 26 | message(FATAL_ERROR "Could not find llvm-config, use -DLLVM_INSTALL_PREFIX to specify the install path") | |
| 27 | endif() | |
| 28 | execute_process( | |
| 29 | COMMAND ${LLVM_CONFIG_EXE} --prefix | |
| 30 | OUTPUT_VARIABLE LLVM_INSTALL_PREFIX | |
| 31 | OUTPUT_STRIP_TRAILING_WHITESPACE) | |
| 32 | endif() | |
| 33 | ||
| 34 | if(${LLVM_INSTALL_PREFIX} MATCHES "^.* ") | |
| 35 | # NOTE: this is a limitation due to llvm-config. If the path contains spaces then there's | |
| 36 | # no way to tell from the output of llvm-config whether a space is seperating a filename, or | |
| 37 | # just a space in the path name. | |
| 38 | message(FATAL_ERROR "The LLVM install path \"${LLVM_INSTALL_PREFIX}\" cannot contain spaces") | |
| 39 | endif() | |
| 17 | 40 | |
| 18 | 41 | execute_process( |
| 19 | 42 | COMMAND ${LLVM_CONFIG_EXE} --libs |
| 20 | OUTPUT_VARIABLE LLVM_LIBRARIES | |
| 43 | OUTPUT_VARIABLE LLVM_LIBRARIES_STRING | |
| 21 | 44 | OUTPUT_STRIP_TRAILING_WHITESPACE) |
| 45 | string(REPLACE " " ";" LLVM_LIBRARIES ${LLVM_LIBRARIES_STRING}) | |
| 22 | 46 | |
| 23 | 47 | execute_process( |
| 24 | 48 | COMMAND ${LLVM_CONFIG_EXE} --system-libs |
| 25 | OUTPUT_VARIABLE LLVM_SYSTEM_LIBS | |
| 49 | OUTPUT_VARIABLE LLVM_SYSTEM_LIBS_STRING | |
| 26 | 50 | OUTPUT_STRIP_TRAILING_WHITESPACE) |
| 51 | string(REPLACE " " ";" LLVM_SYSTEM_LIBS ${LLVM_SYSTEM_LIBS_STRING}) | |
| 27 | 52 | |
| 28 | 53 | execute_process( |
| 29 | 54 | COMMAND ${LLVM_CONFIG_EXE} --libdir |
src/analyze.cpp+1-1| ... | ... | @@ -163,7 +163,7 @@ static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *so |
| 163 | 163 | } |
| 164 | 164 | |
| 165 | 165 | static uint8_t log2_u64(uint64_t x) { |
| 166 | return (63 - __builtin_clzll(x)); | |
| 166 | return (63 - clzll(x)); | |
| 167 | 167 | } |
| 168 | 168 | |
| 169 | 169 | static uint8_t bits_needed_for_unsigned(uint64_t x) { |
src/bigfloat.hpp+8| ... | ... | @@ -13,6 +13,14 @@ |
| 13 | 13 | #include <stdint.h> |
| 14 | 14 | #include <stddef.h> |
| 15 | 15 | |
| 16 | #if defined(_MSVC) | |
| 17 | /* | |
| 18 | * For now this is a placeholder until a better solution comes along to | |
| 19 | * support 128-bit floats with MSVC. | |
| 20 | */ | |
| 21 | typedef long double __float128; | |
| 22 | #endif | |
| 23 | ||
| 16 | 24 | struct BigFloat { |
| 17 | 25 | __float128 value; |
| 18 | 26 | }; |
src/bigint.cpp+44-8| ... | ... | @@ -141,7 +141,7 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) { |
| 141 | 141 | dest->is_negative = false; |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | void bigint_init_u128(BigInt *dest, unsigned __int128 x) { | |
| 144 | void bigint_init_u128(BigInt *dest, uint128_t x) { | |
| 145 | 145 | uint64_t low = (uint64_t)(x & UINT64_MAX); |
| 146 | 146 | uint64_t high = (uint64_t)(x >> 64); |
| 147 | 147 | |
| ... | ... | @@ -201,9 +201,9 @@ void bigint_init_bigint(BigInt *dest, const BigInt *src) { |
| 201 | 201 | |
| 202 | 202 | void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) { |
| 203 | 203 | if (op->value >= 0) { |
| 204 | bigint_init_u128(dest, (unsigned __int128)(op->value)); | |
| 204 | bigint_init_u128(dest, (uint128_t)(op->value)); | |
| 205 | 205 | } else { |
| 206 | bigint_init_u128(dest, (unsigned __int128)(-op->value)); | |
| 206 | bigint_init_u128(dest, (uint128_t)(-op->value)); | |
| 207 | 207 | dest->is_negative = true; |
| 208 | 208 | } |
| 209 | 209 | } |
| ... | ... | @@ -377,6 +377,41 @@ void bigint_read_twos_complement(BigInt *dest, const uint8_t *buf, size_t bit_co |
| 377 | 377 | } |
| 378 | 378 | } |
| 379 | 379 | |
| 380 | #if defined(_MSVC) | |
| 381 | /* | |
| 382 | * Inneficient implmentations for now | |
| 383 | */ | |
| 384 | static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { | |
| 385 | *result = op1 + op2; | |
| 386 | if(*result - op2 != op1) { | |
| 387 | return true; // overflow | |
| 388 | } | |
| 389 | return false; // no overflow | |
| 390 | } | |
| 391 | ||
| 392 | static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { | |
| 393 | *result = op1 - op2; | |
| 394 | if(*result > op1) | |
| 395 | { | |
| 396 | return true; // overflow | |
| 397 | } | |
| 398 | return false; // no overflow | |
| 399 | } | |
| 400 | ||
| 401 | bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { | |
| 402 | *result = op1 * op2; | |
| 403 | if(op1 <= op2) { | |
| 404 | if(*result / op1 != op2) { | |
| 405 | return true; // overflow | |
| 406 | } | |
| 407 | } else { | |
| 408 | if(*result / op2 != op1) { | |
| 409 | return true; // overflow | |
| 410 | } | |
| 411 | } | |
| 412 | return false; // no overflow | |
| 413 | } | |
| 414 | #else | |
| 380 | 415 | static bool add_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { |
| 381 | 416 | return __builtin_uaddll_overflow((unsigned long long)op1, (unsigned long long)op2, |
| 382 | 417 | (unsigned long long *)result); |
| ... | ... | @@ -387,10 +422,11 @@ static bool sub_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { |
| 387 | 422 | (unsigned long long *)result); |
| 388 | 423 | } |
| 389 | 424 | |
| 390 | static bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { | |
| 425 | bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result) { | |
| 391 | 426 | return __builtin_umulll_overflow((unsigned long long)op1, (unsigned long long)op2, |
| 392 | 427 | (unsigned long long *)result); |
| 393 | 428 | } |
| 429 | #endif | |
| 394 | 430 | |
| 395 | 431 | void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) { |
| 396 | 432 | if (op1->digit_count == 0) { |
| ... | ... | @@ -404,7 +440,7 @@ void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) { |
| 404 | 440 | |
| 405 | 441 | const uint64_t *op1_digits = bigint_ptr(op1); |
| 406 | 442 | const uint64_t *op2_digits = bigint_ptr(op2); |
| 407 | uint64_t overflow = add_u64_overflow(op1_digits[0], op2_digits[0], &dest->data.digit); | |
| 443 | bool overflow = add_u64_overflow(op1_digits[0], op2_digits[0], &dest->data.digit); | |
| 408 | 444 | if (overflow == 0 && op1->digit_count == 1 && op2->digit_count == 1) { |
| 409 | 445 | dest->digit_count = 1; |
| 410 | 446 | bigint_normalize(dest); |
| ... | ... | @@ -534,9 +570,9 @@ static void mul_overflow(uint64_t x, uint64_t y, uint64_t *result, uint64_t *car |
| 534 | 570 | return; |
| 535 | 571 | } |
| 536 | 572 | |
| 537 | unsigned __int128 big_x = x; | |
| 538 | unsigned __int128 big_y = y; | |
| 539 | unsigned __int128 big_result = big_x * big_y; | |
| 573 | uint128_t big_x = x; | |
| 574 | uint128_t big_y = y; | |
| 575 | uint128_t big_result = big_x * big_y; | |
| 540 | 576 | *carry = big_result >> 64; |
| 541 | 577 | } |
| 542 | 578 |
src/bigint.hpp+12-1| ... | ... | @@ -11,6 +11,15 @@ |
| 11 | 11 | #include <stdint.h> |
| 12 | 12 | #include <stddef.h> |
| 13 | 13 | |
| 14 | #if defined(_MSVC) | |
| 15 | // TEMPORARY WORKAROUND FOR MSVC NOT SUPPORTING __int128 | |
| 16 | typedef long long int128_t; | |
| 17 | typedef unsigned long long uint128_t; | |
| 18 | #else | |
| 19 | typedef __int128 int128_t; | |
| 20 | typedef unsigned __int128 uint128_t; | |
| 21 | #endif | |
| 22 | ||
| 14 | 23 | struct BigInt { |
| 15 | 24 | size_t digit_count; |
| 16 | 25 | union { |
| ... | ... | @@ -30,7 +39,7 @@ enum Cmp { |
| 30 | 39 | }; |
| 31 | 40 | |
| 32 | 41 | void bigint_init_unsigned(BigInt *dest, uint64_t x); |
| 33 | void bigint_init_u128(BigInt *dest, unsigned __int128 x); | |
| 42 | void bigint_init_u128(BigInt *dest, uint128_t x); | |
| 34 | 43 | void bigint_init_signed(BigInt *dest, int64_t x); |
| 35 | 44 | void bigint_init_bigint(BigInt *dest, const BigInt *src); |
| 36 | 45 | void bigint_init_bigfloat(BigInt *dest, const BigFloat *op); |
| ... | ... | @@ -89,4 +98,6 @@ size_t bigint_bits_needed(const BigInt *op); |
| 89 | 98 | // convenience functions |
| 90 | 99 | Cmp bigint_cmp_zero(const BigInt *op); |
| 91 | 100 | |
| 101 | bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result); | |
| 102 | ||
| 92 | 103 | #endif |
src/buffer.hpp+2-2| ... | ... | @@ -24,7 +24,7 @@ struct Buf { |
| 24 | 24 | }; |
| 25 | 25 | |
| 26 | 26 | Buf *buf_sprintf(const char *format, ...) |
| 27 | __attribute__ ((format (printf, 1, 2))); | |
| 27 | ATTRIBUTE_FORMAT(printf, 1, 2); | |
| 28 | 28 | Buf *buf_vprintf(const char *format, va_list ap); |
| 29 | 29 | |
| 30 | 30 | static inline size_t buf_len(Buf *buf) { |
| ... | ... | @@ -124,7 +124,7 @@ static inline void buf_append_char(Buf *buf, uint8_t c) { |
| 124 | 124 | } |
| 125 | 125 | |
| 126 | 126 | void buf_appendf(Buf *buf, const char *format, ...) |
| 127 | __attribute__ ((format (printf, 2, 3))); | |
| 127 | ATTRIBUTE_FORMAT(printf, 2, 3); | |
| 128 | 128 | |
| 129 | 129 | static inline bool buf_eql_mem(Buf *buf, const char *mem, size_t mem_len) { |
| 130 | 130 | assert(buf->list.length); |
src/codegen.cpp+14-1| ... | ... | @@ -5194,7 +5194,19 @@ void codegen_add_object(CodeGen *g, Buf *object_path) { |
| 5194 | 5194 | g->link_objects.append(object_path); |
| 5195 | 5195 | } |
| 5196 | 5196 | |
| 5197 | ||
| 5197 | #if defined(_MSVC) | |
| 5198 | // MSVC doesn't seem to support "designators" for array initialization | |
| 5199 | static const char *c_int_type_names[] = { | |
| 5200 | "short", | |
| 5201 | "unsigned short", | |
| 5202 | "int", | |
| 5203 | "unsigned int", | |
| 5204 | "long", | |
| 5205 | "unsigned long", | |
| 5206 | "long long", | |
| 5207 | "unsigned long long", | |
| 5208 | }; | |
| 5209 | #else | |
| 5198 | 5210 | static const char *c_int_type_names[] = { |
| 5199 | 5211 | [CIntTypeShort] = "short", |
| 5200 | 5212 | [CIntTypeUShort] = "unsigned short", |
| ... | ... | @@ -5205,6 +5217,7 @@ static const char *c_int_type_names[] = { |
| 5205 | 5217 | [CIntTypeLongLong] = "long long", |
| 5206 | 5218 | [CIntTypeULongLong] = "unsigned long long", |
| 5207 | 5219 | }; |
| 5220 | #endif | |
| 5208 | 5221 | |
| 5209 | 5222 | static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) { |
| 5210 | 5223 | assert(type_entry); |
src/ir.cpp+3-4| ... | ... | @@ -6500,9 +6500,9 @@ static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) { |
| 6500 | 6500 | break; |
| 6501 | 6501 | case 128: |
| 6502 | 6502 | if (const_val->data.x_f128 >= 0) { |
| 6503 | bigint_init_u128(bigint, (unsigned __int128)(const_val->data.x_f128)); | |
| 6503 | bigint_init_u128(bigint, (uint128_t)(const_val->data.x_f128)); | |
| 6504 | 6504 | } else { |
| 6505 | bigint_init_u128(bigint, (unsigned __int128)(-const_val->data.x_f128)); | |
| 6505 | bigint_init_u128(bigint, (uint128_t)(-const_val->data.x_f128)); | |
| 6506 | 6506 | bigint->is_negative = true; |
| 6507 | 6507 | } |
| 6508 | 6508 | break; |
| ... | ... | @@ -9731,8 +9731,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp |
| 9731 | 9731 | uint64_t old_array_len = array_type->data.array.len; |
| 9732 | 9732 | uint64_t new_array_len; |
| 9733 | 9733 | |
| 9734 | if (__builtin_umulll_overflow((unsigned long long)old_array_len, (unsigned long long)mult_amt, | |
| 9735 | (unsigned long long*)&new_array_len)) | |
| 9734 | if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len)) | |
| 9736 | 9735 | { |
| 9737 | 9736 | ir_add_error(ira, &instruction->base, buf_sprintf("operation results in overflow")); |
| 9738 | 9737 | return ira->codegen->builtin_types.entry_invalid; |
src/os.cpp+7-5| ... | ... | @@ -25,6 +25,8 @@ |
| 25 | 25 | |
| 26 | 26 | #include <windows.h> |
| 27 | 27 | #include <io.h> |
| 28 | ||
| 29 | typedef SSIZE_T ssize_t; | |
| 28 | 30 | #else |
| 29 | 31 | #define ZIG_OS_POSIX |
| 30 | 32 | |
| ... | ... | @@ -620,7 +622,7 @@ int os_get_cwd(Buf *out_cwd) { |
| 620 | 622 | |
| 621 | 623 | bool os_stderr_tty(void) { |
| 622 | 624 | #if defined(ZIG_OS_WINDOWS) |
| 623 | return _isatty(STDERR_FILENO) != 0; | |
| 625 | return _isatty(_fileno(stderr)) != 0; | |
| 624 | 626 | #elif defined(ZIG_OS_POSIX) |
| 625 | 627 | return isatty(STDERR_FILENO) != 0; |
| 626 | 628 | #else |
| ... | ... | @@ -777,12 +779,12 @@ int os_make_path(Buf *path) { |
| 777 | 779 | |
| 778 | 780 | int os_make_dir(Buf *path) { |
| 779 | 781 | #if defined(ZIG_OS_WINDOWS) |
| 780 | if (mkdir(buf_ptr(path)) == -1) { | |
| 781 | if (errno == EEXIST) | |
| 782 | if (!CreateDirectory(buf_ptr(path), NULL)) { | |
| 783 | if (GetLastError() == ERROR_ALREADY_EXISTS) | |
| 782 | 784 | return ErrorPathAlreadyExists; |
| 783 | if (errno == ENOENT) | |
| 785 | if (GetLastError() == ERROR_PATH_NOT_FOUND) | |
| 784 | 786 | return ErrorFileNotFound; |
| 785 | if (errno == EACCES) | |
| 787 | if (GetLastError() == ERROR_ACCESS_DENIED) | |
| 786 | 788 | return ErrorAccess; |
| 787 | 789 | return ErrorUnexpected; |
| 788 | 790 | } |
src/parsec.cpp+1-1| ... | ... | @@ -56,7 +56,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); |
| 56 | 56 | static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl); |
| 57 | 57 | |
| 58 | 58 | |
| 59 | __attribute__ ((format (printf, 3, 4))) | |
| 59 | ATTRIBUTE_FORMAT(printf, 3, 4) | |
| 60 | 60 | static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) { |
| 61 | 61 | if (!c->warnings_on) { |
| 62 | 62 | return; |
src/parser.cpp+5-5| ... | ... | @@ -24,8 +24,8 @@ struct ParseContext { |
| 24 | 24 | Buf *void_buf; |
| 25 | 25 | }; |
| 26 | 26 | |
| 27 | __attribute__ ((format (printf, 4, 5))) | |
| 28 | __attribute__ ((noreturn)) | |
| 27 | ATTRIBUTE_FORMAT(printf, 4, 5) | |
| 28 | LLVM_ATTRIBUTE_NORETURN | |
| 29 | 29 | static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const char *format, ...) { |
| 30 | 30 | assert(node->type == NodeTypeAsmExpr); |
| 31 | 31 | |
| ... | ... | @@ -46,8 +46,8 @@ static void ast_asm_error(ParseContext *pc, AstNode *node, size_t offset, const |
| 46 | 46 | exit(EXIT_FAILURE); |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | __attribute__ ((format (printf, 3, 4))) | |
| 50 | __attribute__ ((noreturn)) | |
| 49 | ATTRIBUTE_FORMAT(printf, 3, 4) | |
| 50 | LLVM_ATTRIBUTE_NORETURN | |
| 51 | 51 | static void ast_error(ParseContext *pc, Token *token, const char *format, ...) { |
| 52 | 52 | va_list ap; |
| 53 | 53 | va_start(ap, format); |
| ... | ... | @@ -205,7 +205,7 @@ static void ast_buf_from_token(ParseContext *pc, Token *token, Buf *buf) { |
| 205 | 205 | } |
| 206 | 206 | } |
| 207 | 207 | |
| 208 | __attribute__ ((noreturn)) | |
| 208 | LLVM_ATTRIBUTE_NORETURN | |
| 209 | 209 | static void ast_invalid_token_error(ParseContext *pc, Token *token) { |
| 210 | 210 | Buf token_value = BUF_INIT; |
| 211 | 211 | ast_buf_from_token(pc, token, &token_value); |
src/parser.hpp+1-1| ... | ... | @@ -12,7 +12,7 @@ |
| 12 | 12 | #include "tokenizer.hpp" |
| 13 | 13 | #include "errmsg.hpp" |
| 14 | 14 | |
| 15 | __attribute__ ((format (printf, 2, 3))) | |
| 15 | ATTRIBUTE_FORMAT(printf, 2, 3) | |
| 16 | 16 | void ast_token_error(Token *token, const char *format, ...); |
| 17 | 17 | |
| 18 | 18 |
src/quadmath.hpp+34| ... | ... | @@ -8,12 +8,46 @@ |
| 8 | 8 | #ifndef ZIG_QUADMATH_HPP |
| 9 | 9 | #define ZIG_QUADMATH_HPP |
| 10 | 10 | |
| 11 | #if defined(_MSVC) | |
| 12 | #include <stdlib.h> | |
| 13 | #include <stdio.h> | |
| 14 | #include <stdarg.h> | |
| 15 | #include <cmath> | |
| 16 | #endif | |
| 17 | ||
| 11 | 18 | extern "C" { |
| 19 | #if defined(_MSVC) | |
| 20 | static __float128 fmodq(__float128 a, __float128 b) | |
| 21 | { | |
| 22 | return fmod(a, b); | |
| 23 | } | |
| 24 | static __float128 ceilq(__float128 a) | |
| 25 | { | |
| 26 | return ceil(a); | |
| 27 | } | |
| 28 | static __float128 floorq(__float128 a) | |
| 29 | { | |
| 30 | return floor(a); | |
| 31 | } | |
| 32 | static __float128 strtoflt128(const char *s, char **sp) | |
| 33 | { | |
| 34 | return strtold(s, sp); | |
| 35 | } | |
| 36 | static int quadmath_snprintf(char *s, size_t size, const char *format, ...) | |
| 37 | { | |
| 38 | va_list args; | |
| 39 | va_start(format, args); | |
| 40 | int result = vsnprintf(s, size, format, args); | |
| 41 | va_end(args); | |
| 42 | return result; | |
| 43 | } | |
| 44 | #else | |
| 12 | 45 | __float128 fmodq(__float128 a, __float128 b); |
| 13 | 46 | __float128 ceilq(__float128 a); |
| 14 | 47 | __float128 floorq(__float128 a); |
| 15 | 48 | __float128 strtoflt128 (const char *s, char **sp); |
| 16 | 49 | int quadmath_snprintf (char *s, size_t size, const char *format, ...); |
| 50 | #endif | |
| 17 | 51 | } |
| 18 | 52 | |
| 19 | 53 | #endif |
src/tokenizer.cpp+2-2| ... | ... | @@ -234,7 +234,7 @@ struct Tokenize { |
| 234 | 234 | BigInt significand; |
| 235 | 235 | }; |
| 236 | 236 | |
| 237 | __attribute__ ((format (printf, 2, 3))) | |
| 237 | ATTRIBUTE_FORMAT(printf, 2, 3) | |
| 238 | 238 | static void tokenize_error(Tokenize *t, const char *format, ...) { |
| 239 | 239 | t->state = TokenizeStateError; |
| 240 | 240 | |
| ... | ... | @@ -331,7 +331,7 @@ static void end_float_token(Tokenize *t) { |
| 331 | 331 | if (t->radix == 10) { |
| 332 | 332 | zig_panic("TODO: decimal floats"); |
| 333 | 333 | } else { |
| 334 | int significand_magnitude_in_bin = __builtin_clzll(1) - __builtin_clzll(significand); | |
| 334 | int significand_magnitude_in_bin = clzll(1) - clzll(significand); | |
| 335 | 335 | t->exponent_in_bin_or_dec += significand_magnitude_in_bin; |
| 336 | 336 | if (!(-1022 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec <= 1023)) { |
| 337 | 337 | t->cur_tok->data.float_lit.overflow = true; |
src/util.hpp+36-8| ... | ... | @@ -12,24 +12,52 @@ |
| 12 | 12 | #include <stdint.h> |
| 13 | 13 | #include <string.h> |
| 14 | 14 | #include <assert.h> |
| 15 | #include <llvm/Support/Compiler.h> | |
| 15 | 16 | |
| 16 | 17 | #include <new> |
| 17 | 18 | |
| 19 | #if defined(_MSVC) | |
| 20 | #define ATTRIBUTE_COLD | |
| 21 | #define ATTRIBUTE_FORMAT(args) | |
| 22 | static inline uint32_t popcnt(unsigned long long x) | |
| 23 | { | |
| 24 | x -= ((x >> 1) & 0x55555555); | |
| 25 | x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); | |
| 26 | x = (((x >> 4) + x) & 0x0f0f0f0f); | |
| 27 | x += (x >> 8); | |
| 28 | x += (x >> 16); | |
| 29 | return x & 0x0000003f; | |
| 30 | } | |
| 31 | static inline uint32_t clzll(unsigned long long x) | |
| 32 | { | |
| 33 | x |= (x >> 1); | |
| 34 | x |= (x >> 2); | |
| 35 | x |= (x >> 4); | |
| 36 | x |= (x >> 8); | |
| 37 | x |= (x >> 16); | |
| 38 | return 32 - popcnt(x); | |
| 39 | } | |
| 40 | #else | |
| 41 | #define ATTRIBUTE_COLD __attribute__((cold)) | |
| 42 | #define ATTRIBUTE_FORMAT(args) __attribute__((format (args))) | |
| 43 | #define clzll(x) __builtin_clzll(x) | |
| 44 | #endif | |
| 45 | ||
| 18 | 46 | #define BREAKPOINT __asm("int $0x03") |
| 19 | 47 | |
| 20 | void zig_panic(const char *format, ...) | |
| 21 | __attribute__((cold)) | |
| 22 | __attribute__ ((noreturn)) | |
| 23 | __attribute__ ((format (printf, 1, 2))); | |
| 48 | LLVM_ATTRIBUTE_NOINLINE | |
| 49 | ATTRIBUTE_COLD | |
| 50 | ATTRIBUTE_FORMAT(printf, 1, 2) | |
| 51 | void zig_panic(const char *format, ...); | |
| 24 | 52 | |
| 25 | __attribute__((cold)) | |
| 26 | __attribute__ ((noreturn)) | |
| 53 | ATTRIBUTE_COLD | |
| 54 | LLVM_ATTRIBUTE_NOINLINE | |
| 27 | 55 | static inline void zig_unreachable(void) { |
| 28 | 56 | zig_panic("unreachable"); |
| 29 | 57 | } |
| 30 | 58 | |
| 31 | 59 | template<typename T> |
| 32 | __attribute__((malloc)) static inline T *allocate_nonzero(size_t count) { | |
| 60 | LLVM_ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) { | |
| 33 | 61 | T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T))); |
| 34 | 62 | if (!ptr) |
| 35 | 63 | zig_panic("allocation failed"); |
| ... | ... | @@ -37,7 +65,7 @@ __attribute__((malloc)) static inline T *allocate_nonzero(size_t count) { |
| 37 | 65 | } |
| 38 | 66 | |
| 39 | 67 | template<typename T> |
| 40 | __attribute__((malloc)) static inline T *allocate(size_t count) { | |
| 68 | LLVM_ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) { | |
| 41 | 69 | T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T))); |
| 42 | 70 | if (!ptr) |
| 43 | 71 | zig_panic("allocation failed"); |