| author | |
| committer | |
| log | 212e2354b8ab631995b0c25f7cf1d9a3e01fac57 |
| tree | b5d42acd5308378b995bc97b191c8a4efd240a43 |
| parent | 0f1f56bb69610ea424ac311db72510b474249095 |
Make fallthrough an error when compiler supports it. This requires a new
macro that is defined with such compilers to be used as a statement, at
all fallthrough sites:
switch (...) {
case 0:
...
ZIG_FALLTHROUGH;
case 1:
...
break;
default:
...
break;
}
If we ever move to C++17 as minimal requirement, then the macro can be
replaced with `[[fallthrough]];` at statement sites.8 files changed, 28 insertions(+), 7 deletions(-)
CMakeLists.txt+1-1| ... | @@ -325,7 +325,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") | ... | @@ -325,7 +325,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") |
| 325 | if(MSVC) | 325 | if(MSVC) |
| 326 | set(EXE_CFLAGS "${EXE_CFLAGS} /w") | 326 | set(EXE_CFLAGS "${EXE_CFLAGS} /w") |
| 327 | else() | 327 | else() |
| 328 | set(EXE_CFLAGS "${EXE_CFLAGS} -Werror -Wall") | 328 | set(EXE_CFLAGS "${EXE_CFLAGS} -Werror -Wall -Werror=implicit-fallthrough") |
| 329 | endif() | 329 | endif() |
| 330 | endif() | 330 | endif() |
| 331 | 331 |
src/analyze.cpp+2| ... | @@ -363,6 +363,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) { | ... | @@ -363,6 +363,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) { |
| 363 | case ResolveStatusLLVMFull: | 363 | case ResolveStatusLLVMFull: |
| 364 | return type_entry->llvm_type != nullptr; | 364 | return type_entry->llvm_type != nullptr; |
| 365 | } | 365 | } |
| 366 | zig_unreachable(); | ||
| 366 | case ZigTypeIdOpaque: | 367 | case ZigTypeIdOpaque: |
| 367 | return status < ResolveStatusSizeKnown; | 368 | return status < ResolveStatusSizeKnown; |
| 368 | case ZigTypeIdPointer: | 369 | case ZigTypeIdPointer: |
| ... | @@ -381,6 +382,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) { | ... | @@ -381,6 +382,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) { |
| 381 | case ResolveStatusLLVMFull: | 382 | case ResolveStatusLLVMFull: |
| 382 | return type_entry->llvm_type != nullptr; | 383 | return type_entry->llvm_type != nullptr; |
| 383 | } | 384 | } |
| 385 | zig_unreachable(); | ||
| 384 | case ZigTypeIdMetaType: | 386 | case ZigTypeIdMetaType: |
| 385 | case ZigTypeIdVoid: | 387 | case ZigTypeIdVoid: |
| 386 | case ZigTypeIdBool: | 388 | case ZigTypeIdBool: |
src/codegen.cpp+2-1| ... | @@ -3954,8 +3954,9 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) { | ... | @@ -3954,8 +3954,9 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) { |
| 3954 | if (var->did_the_decl_codegen) { | 3954 | if (var->did_the_decl_codegen) { |
| 3955 | render_decl_var(g, var); | 3955 | render_decl_var(g, var); |
| 3956 | } | 3956 | } |
| 3957 | // fallthrough | ||
| 3958 | } | 3957 | } |
| 3958 | ZIG_FALLTHROUGH; | ||
| 3959 | |||
| 3959 | case ScopeIdDecls: | 3960 | case ScopeIdDecls: |
| 3960 | case ScopeIdBlock: | 3961 | case ScopeIdBlock: |
| 3961 | case ScopeIdDefer: | 3962 | case ScopeIdDefer: |
src/dump_analysis.cpp+2-2| ... | @@ -80,7 +80,7 @@ static void jw_array_elem(JsonWriter *jw) { | ... | @@ -80,7 +80,7 @@ static void jw_array_elem(JsonWriter *jw) { |
| 80 | zig_unreachable(); | 80 | zig_unreachable(); |
| 81 | case JsonWriterStateArray: | 81 | case JsonWriterStateArray: |
| 82 | fprintf(jw->f, ","); | 82 | fprintf(jw->f, ","); |
| 83 | // fallthrough | 83 | ZIG_FALLTHROUGH; |
| 84 | case JsonWriterStateArrayStart: | 84 | case JsonWriterStateArrayStart: |
| 85 | jw->state[jw->state_index] = JsonWriterStateArray; | 85 | jw->state[jw->state_index] = JsonWriterStateArray; |
| 86 | jw_push_state(jw, JsonWriterStateValue); | 86 | jw_push_state(jw, JsonWriterStateValue); |
| ... | @@ -134,7 +134,7 @@ static void jw_object_field(JsonWriter *jw, const char *name) { | ... | @@ -134,7 +134,7 @@ static void jw_object_field(JsonWriter *jw, const char *name) { |
| 134 | zig_unreachable(); | 134 | zig_unreachable(); |
| 135 | case JsonWriterStateObject: | 135 | case JsonWriterStateObject: |
| 136 | fprintf(jw->f, ","); | 136 | fprintf(jw->f, ","); |
| 137 | // fallthrough | 137 | ZIG_FALLTHROUGH; |
| 138 | case JsonWriterStateObjectStart: | 138 | case JsonWriterStateObjectStart: |
| 139 | jw->state[jw->state_index] = JsonWriterStateObject; | 139 | jw->state[jw->state_index] = JsonWriterStateObject; |
| 140 | jw_push_state(jw, JsonWriterStateValue); | 140 | jw_push_state(jw, JsonWriterStateValue); |
src/ir.cpp+2| ... | @@ -19949,6 +19949,7 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr, | ... | @@ -19949,6 +19949,7 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr, |
| 19949 | buf_sprintf("the specified modifier requires a comptime-known function")); | 19949 | buf_sprintf("the specified modifier requires a comptime-known function")); |
| 19950 | return ira->codegen->invalid_inst_gen; | 19950 | return ira->codegen->invalid_inst_gen; |
| 19951 | } | 19951 | } |
| 19952 | ZIG_FALLTHROUGH; | ||
| 19952 | default: | 19953 | default: |
| 19953 | break; | 19954 | break; |
| 19954 | } | 19955 | } |
| ... | @@ -28169,6 +28170,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val) | ... | @@ -28169,6 +28170,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val) |
| 28169 | return; | 28170 | return; |
| 28170 | } | 28171 | } |
| 28171 | } | 28172 | } |
| 28173 | zig_unreachable(); | ||
| 28172 | case ZigTypeIdOptional: | 28174 | case ZigTypeIdOptional: |
| 28173 | zig_panic("TODO buf_write_value_bytes maybe type"); | 28175 | zig_panic("TODO buf_write_value_bytes maybe type"); |
| 28174 | case ZigTypeIdFn: | 28176 | case ZigTypeIdFn: |
src/target.cpp+5| ... | @@ -624,6 +624,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { | ... | @@ -624,6 +624,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 624 | case CIntTypeCount: | 624 | case CIntTypeCount: |
| 625 | zig_unreachable(); | 625 | zig_unreachable(); |
| 626 | } | 626 | } |
| 627 | zig_unreachable(); | ||
| 627 | default: | 628 | default: |
| 628 | switch (id) { | 629 | switch (id) { |
| 629 | case CIntTypeShort: | 630 | case CIntTypeShort: |
| ... | @@ -642,6 +643,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { | ... | @@ -642,6 +643,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 642 | zig_unreachable(); | 643 | zig_unreachable(); |
| 643 | } | 644 | } |
| 644 | } | 645 | } |
| 646 | zig_unreachable(); | ||
| 645 | case OsLinux: | 647 | case OsLinux: |
| 646 | case OsMacOSX: | 648 | case OsMacOSX: |
| 647 | case OsFreeBSD: | 649 | case OsFreeBSD: |
| ... | @@ -666,6 +668,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { | ... | @@ -666,6 +668,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 666 | case CIntTypeCount: | 668 | case CIntTypeCount: |
| 667 | zig_unreachable(); | 669 | zig_unreachable(); |
| 668 | } | 670 | } |
| 671 | zig_unreachable(); | ||
| 669 | case OsUefi: | 672 | case OsUefi: |
| 670 | case OsWindows: | 673 | case OsWindows: |
| 671 | switch (id) { | 674 | switch (id) { |
| ... | @@ -683,6 +686,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { | ... | @@ -683,6 +686,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 683 | case CIntTypeCount: | 686 | case CIntTypeCount: |
| 684 | zig_unreachable(); | 687 | zig_unreachable(); |
| 685 | } | 688 | } |
| 689 | zig_unreachable(); | ||
| 686 | case OsIOS: | 690 | case OsIOS: |
| 687 | switch (id) { | 691 | switch (id) { |
| 688 | case CIntTypeShort: | 692 | case CIntTypeShort: |
| ... | @@ -699,6 +703,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { | ... | @@ -699,6 +703,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 699 | case CIntTypeCount: | 703 | case CIntTypeCount: |
| 700 | zig_unreachable(); | 704 | zig_unreachable(); |
| 701 | } | 705 | } |
| 706 | zig_unreachable(); | ||
| 702 | case OsAnanas: | 707 | case OsAnanas: |
| 703 | case OsCloudABI: | 708 | case OsCloudABI: |
| 704 | case OsKFreeBSD: | 709 | case OsKFreeBSD: |
src/tokenizer.cpp+4-3| ... | @@ -840,6 +840,7 @@ void tokenize(Buf *buf, Tokenization *out) { | ... | @@ -840,6 +840,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 840 | t.state = TokenizeStateStart; | 840 | t.state = TokenizeStateStart; |
| 841 | continue; | 841 | continue; |
| 842 | } | 842 | } |
| 843 | break; | ||
| 843 | case TokenizeStateSawSlash: | 844 | case TokenizeStateSawSlash: |
| 844 | switch (c) { | 845 | switch (c) { |
| 845 | case '/': | 846 | case '/': |
| ... | @@ -1209,7 +1210,7 @@ void tokenize(Buf *buf, Tokenization *out) { | ... | @@ -1209,7 +1210,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 1209 | t.is_trailing_underscore = false; | 1210 | t.is_trailing_underscore = false; |
| 1210 | t.state = TokenizeStateNumber; | 1211 | t.state = TokenizeStateNumber; |
| 1211 | } | 1212 | } |
| 1212 | // fall through | 1213 | ZIG_FALLTHROUGH; |
| 1213 | case TokenizeStateNumber: | 1214 | case TokenizeStateNumber: |
| 1214 | { | 1215 | { |
| 1215 | if (c == '_') { | 1216 | if (c == '_') { |
| ... | @@ -1291,7 +1292,7 @@ void tokenize(Buf *buf, Tokenization *out) { | ... | @@ -1291,7 +1292,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 1291 | t.is_trailing_underscore = false; | 1292 | t.is_trailing_underscore = false; |
| 1292 | t.state = TokenizeStateFloatFraction; | 1293 | t.state = TokenizeStateFloatFraction; |
| 1293 | } | 1294 | } |
| 1294 | // fall through | 1295 | ZIG_FALLTHROUGH; |
| 1295 | case TokenizeStateFloatFraction: | 1296 | case TokenizeStateFloatFraction: |
| 1296 | { | 1297 | { |
| 1297 | if (c == '_') { | 1298 | if (c == '_') { |
| ... | @@ -1350,7 +1351,7 @@ void tokenize(Buf *buf, Tokenization *out) { | ... | @@ -1350,7 +1351,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 1350 | t.is_trailing_underscore = false; | 1351 | t.is_trailing_underscore = false; |
| 1351 | t.state = TokenizeStateFloatExponentNumber; | 1352 | t.state = TokenizeStateFloatExponentNumber; |
| 1352 | } | 1353 | } |
| 1353 | // fall through | 1354 | ZIG_FALLTHROUGH; |
| 1354 | case TokenizeStateFloatExponentNumber: | 1355 | case TokenizeStateFloatExponentNumber: |
| 1355 | { | 1356 | { |
| 1356 | if (c == '_') { | 1357 | if (c == '_') { |
src/util_base.hpp+10| ... | @@ -64,4 +64,14 @@ static inline void zig_assert(bool ok, const char *file, int line, const char *f | ... | @@ -64,4 +64,14 @@ static inline void zig_assert(bool ok, const char *file, int line, const char *f |
| 64 | #undef assert | 64 | #undef assert |
| 65 | #define assert(ok) zig_assert(ok, __FILE__, __LINE__, __func__) | 65 | #define assert(ok) zig_assert(ok, __FILE__, __LINE__, __func__) |
| 66 | 66 | ||
| 67 | #if defined(_MSC_VER) | ||
| 68 | #define ZIG_FALLTHROUGH | ||
| 69 | #elif defined(__clang__) | ||
| 70 | #define ZIG_FALLTHROUGH [[clang::fallthrough]] | ||
| 71 | #elif defined(__GNUC__) | ||
| 72 | #define ZIG_FALLTHROUGH __attribute__((fallthrough)) | ||
| 73 | #else | ||
| 74 | #define ZIG_FALLTHROUGH | ||
| 75 | #endif | ||
| 76 | |||
| 67 | #endif | 77 | #endif |