Commit 212e2354b8

Michael Dusan <michael.dusan@gmail.com>
2020-04-01 18:47:50
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.
1 parent 0f1f56b
src/analyze.cpp
@@ -363,6 +363,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
                 case ResolveStatusLLVMFull:
                     return type_entry->llvm_type != nullptr;
             }
+            zig_unreachable();
         case ZigTypeIdOpaque:
             return status < ResolveStatusSizeKnown;
         case ZigTypeIdPointer:
@@ -381,6 +382,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
                 case ResolveStatusLLVMFull:
                     return type_entry->llvm_type != nullptr;
             }
+            zig_unreachable();
         case ZigTypeIdMetaType:
         case ZigTypeIdVoid:
         case ZigTypeIdBool:
src/codegen.cpp
@@ -3954,8 +3954,9 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) {
                 if (var->did_the_decl_codegen) {
                     render_decl_var(g, var);
                 }
-                // fallthrough
             }
+            ZIG_FALLTHROUGH;
+
             case ScopeIdDecls:
             case ScopeIdBlock:
             case ScopeIdDefer:
src/dump_analysis.cpp
@@ -80,7 +80,7 @@ static void jw_array_elem(JsonWriter *jw) {
             zig_unreachable();
         case JsonWriterStateArray:
             fprintf(jw->f, ",");
-            // fallthrough
+            ZIG_FALLTHROUGH;
         case JsonWriterStateArrayStart:
             jw->state[jw->state_index] = JsonWriterStateArray;
             jw_push_state(jw, JsonWriterStateValue);
@@ -134,7 +134,7 @@ static void jw_object_field(JsonWriter *jw, const char *name) {
             zig_unreachable();
         case JsonWriterStateObject:
             fprintf(jw->f, ",");
-            // fallthrough
+            ZIG_FALLTHROUGH;
         case JsonWriterStateObjectStart:
             jw->state[jw->state_index] = JsonWriterStateObject;
             jw_push_state(jw, JsonWriterStateValue);
src/ir.cpp
@@ -19949,6 +19949,7 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr,
                     buf_sprintf("the specified modifier requires a comptime-known function"));
                 return ira->codegen->invalid_inst_gen;
             }
+            ZIG_FALLTHROUGH;
         default:
             break;
     }
@@ -28169,6 +28170,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val)
                     return;
                 }
             }
+            zig_unreachable();
         case ZigTypeIdOptional:
             zig_panic("TODO buf_write_value_bytes maybe type");
         case ZigTypeIdFn:
src/target.cpp
@@ -624,6 +624,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
                         case CIntTypeCount:
                             zig_unreachable();
                     }
+                    zig_unreachable();
                 default:
                     switch (id) {
                         case CIntTypeShort:
@@ -642,6 +643,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
                             zig_unreachable();
                     }
             }
+            zig_unreachable();
         case OsLinux:
         case OsMacOSX:
         case OsFreeBSD:
@@ -666,6 +668,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
                 case CIntTypeCount:
                     zig_unreachable();
             }
+            zig_unreachable();
         case OsUefi:
         case OsWindows:
             switch (id) {
@@ -683,6 +686,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
                 case CIntTypeCount:
                     zig_unreachable();
             }
+            zig_unreachable();
         case OsIOS:
             switch (id) {
                 case CIntTypeShort:
@@ -699,6 +703,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
                 case CIntTypeCount:
                     zig_unreachable();
             }
+            zig_unreachable();
         case OsAnanas:
         case OsCloudABI:
         case OsKFreeBSD:
src/tokenizer.cpp
@@ -840,6 +840,7 @@ void tokenize(Buf *buf, Tokenization *out) {
                         t.state = TokenizeStateStart;
                         continue;
                 }
+                break;
             case TokenizeStateSawSlash:
                 switch (c) {
                     case '/':
@@ -1209,7 +1210,7 @@ void tokenize(Buf *buf, Tokenization *out) {
                     t.is_trailing_underscore = false;
                     t.state = TokenizeStateNumber;
                 }
-                // fall through
+                ZIG_FALLTHROUGH;
             case TokenizeStateNumber:
                 {
                     if (c == '_') {
@@ -1291,7 +1292,7 @@ void tokenize(Buf *buf, Tokenization *out) {
                     t.is_trailing_underscore = false;
                     t.state = TokenizeStateFloatFraction;
                 }
-                // fall through
+                ZIG_FALLTHROUGH;
             case TokenizeStateFloatFraction:
                 {
                     if (c == '_') {
@@ -1350,7 +1351,7 @@ void tokenize(Buf *buf, Tokenization *out) {
                     t.is_trailing_underscore = false;
                     t.state = TokenizeStateFloatExponentNumber;
                 }
-                // fall through
+                ZIG_FALLTHROUGH;
             case TokenizeStateFloatExponentNumber:
                 {
                     if (c == '_') {
src/util_base.hpp
@@ -64,4 +64,14 @@ static inline void zig_assert(bool ok, const char *file, int line, const char *f
 #undef assert
 #define assert(ok) zig_assert(ok, __FILE__, __LINE__, __func__)
 
+#if defined(_MSC_VER)
+#define ZIG_FALLTHROUGH
+#elif defined(__clang__)
+#define ZIG_FALLTHROUGH [[clang::fallthrough]]
+#elif defined(__GNUC__)
+#define ZIG_FALLTHROUGH __attribute__((fallthrough))
+#else
+#define ZIG_FALLTHROUGH
+#endif
+
 #endif
CMakeLists.txt
@@ -325,7 +325,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
     if(MSVC)
         set(EXE_CFLAGS "${EXE_CFLAGS} /w")
     else()
-        set(EXE_CFLAGS "${EXE_CFLAGS} -Werror -Wall")
+        set(EXE_CFLAGS "${EXE_CFLAGS} -Werror -Wall -Werror=implicit-fallthrough")
     endif()
 endif()