authorgravatar for michael.dusan@gmail.comMichael Dusan <michael.dusan@gmail.com> 2020-04-01 12:47:50-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-01 15:56:00-04:00
log212e2354b8ab631995b0c25f7cf1d9a3e01fac57
treeb5d42acd5308378b995bc97b191c8a4efd240a43
parent0f1f56bb69610ea424ac311db72510b474249095

stage1: make C++ switch fallthrough an error

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()
330endif()330endif()
331331
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 // fallthrough83 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 // fallthrough137 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 through1213 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 through1295 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 through1354 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 assert64#undef assert
65#define assert(ok) zig_assert(ok, __FILE__, __LINE__, __func__)65#define assert(ok) zig_assert(ok, __FILE__, __LINE__, __func__)
6666
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#endif77#endif