diff --git a/doc/html/boost_config/boost_macro_reference.html b/doc/html/boost_config/boost_macro_reference.html index 3240ba59..9d18217a 100644 --- a/doc/html/boost_config/boost_macro_reference.html +++ b/doc/html/boost_config/boost_macro_reference.html @@ -3382,6 +3382,54 @@ + +

+ BOOST_FALLTHROUGH +

+ + +

+ The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through + between switch labels: +

+
switch (x) {
+case 40:
+case 41:
+   if (truth_is_out_there) {
+      ++x;
+      BOOST_FALLTHROUGH;  // Use instead of/along with annotations in 
+      // comments. 
+   } else {
+     return x;
+   }
+   case 42:
+      ...
+
+

+ As shown in the example above, the BOOST_FALLTHROUGH macro should + be followed by a semicolon. It is designed to mimic control-flow + statements like 'break;', so it can be placed in most places where + 'break;' can, but only if there are no statements on the execution + path between it and the next switch label. +

+

+ When compiled with Clang >3.2 in C++11 mode, the BOOST_FALLTHROUGH + macro is expanded to [[clang::fallthrough]] + attribute, which is analysed when performing switch labels fall-through + diagnostic ('-Wimplicit-fallthrough'). See clang documentation + on language extensions for details. +

+

+ When used with unsupported compilers, the BOOST_FALLTHROUGH macro + has no effect on diagnostics. +

+

+ In either case this macro has no effect on runtime behavior and + performance of code. +

+ + +

BOOST_EXPLICIT_TEMPLATE_TYPE(t) BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t,v) BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t,v) diff --git a/doc/html/index.html b/doc/html/index.html index bdf89c1b..a30cd0fd 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -951,7 +951,7 @@ - +

Last revised: February 19, 2013 at 16:25:18 GMT

Last revised: April 18, 2013 at 17:44:14 GMT


diff --git a/doc/macro_reference.qbk b/doc/macro_reference.qbk index 6b424546..a96a16c9 100644 --- a/doc/macro_reference.qbk +++ b/doc/macro_reference.qbk @@ -862,6 +862,41 @@ struct foo{ Normally evaluates to nothing, but evaluates to return x; if the compiler requires a return, even when it can never be reached. ]] +[[`BOOST_FALLTHROUGH`][ +The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through +between switch labels: +`` + switch (x) { + case 40: + case 41: + if (truth_is_out_there) { + ++x; + BOOST_FALLTHROUGH; // Use instead of/along with annotations in + // comments. + } else { + return x; + } + case 42: + ... +`` +As shown in the example above, the BOOST_FALLTHROUGH macro should be +followed by a semicolon. It is designed to mimic control-flow statements +like 'break;', so it can be placed in most places where 'break;' can, but +only if there are no statements on the execution path between it and the +next switch label. + +When compiled with Clang >3.2 in C++11 mode, the BOOST_FALLTHROUGH macro is +expanded to `[[clang::fallthrough]]` attribute, which is analysed when +performing switch labels fall-through diagnostic ('-Wimplicit-fallthrough'). +See clang [@http://clang.llvm.org/docs/LanguageExtensions.html#clang__fallthrough +documentation on language extensions for details.] + +When used with unsupported compilers, the BOOST_FALLTHROUGH macro has no +effect on diagnostics. + +In either case this macro has no effect on runtime behavior and performance +of code. +]] [[`BOOST_EXPLICIT_TEMPLATE_TYPE(t)` `BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t,v)` `BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t)` diff --git a/include/boost/config/compiler/clang.hpp b/include/boost/config/compiler/clang.hpp index 209c9007..4bc4feeb 100644 --- a/include/boost/config/compiler/clang.hpp +++ b/include/boost/config/compiler/clang.hpp @@ -38,6 +38,16 @@ # define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) #endif +// +// The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through +// between switch labels. +// +#if __cplusplus >= 201103L && defined(__has_warning) +# if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +# define BOOST_FALLTHROUGH [[clang::fallthrough]] +# endif +#endif + #if !__has_feature(cxx_auto_type) # define BOOST_NO_CXX11_AUTO_DECLARATIONS # define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS diff --git a/include/boost/config/suffix.hpp b/include/boost/config/suffix.hpp index d4524812..c0928dde 100644 --- a/include/boost/config/suffix.hpp +++ b/include/boost/config/suffix.hpp @@ -883,6 +883,16 @@ namespace std{ using ::type_info; } # define BOOST_NOEXCEPT_IF(Predicate) noexcept((Predicate)) # define BOOST_NOEXCEPT_EXPR(Expression) noexcept((Expression)) #endif +// +// Helper macro BOOST_FALLTHROUGH +// Fallback definition of BOOST_FALLTHROUGH macro used to mark intended +// fall-through between case labels in a switch statement. We use a definition +// that requires a semicolon after it to avoid at least one type of misuse even +// on unsupported compilers. +// +#ifndef BOOST_FALLTHROUGH +# define BOOST_FALLTHROUGH ((void)0) +#endif // // constexpr workarounds diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 314ab4bd..ba8f7804 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -65,4 +65,5 @@ test-suite config ] [ compile-fail threads/test_thread_fail1.cpp ] [ compile-fail threads/test_thread_fail2.cpp ] + [ compile boost_fallthrough_test.cpp : clang:"-std=c++11 -Wimplicit-fallthrough" on all ] ; diff --git a/test/boost_fallthrough_test.cpp b/test/boost_fallthrough_test.cpp new file mode 100644 index 00000000..3fabe351 --- /dev/null +++ b/test/boost_fallthrough_test.cpp @@ -0,0 +1,20 @@ +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +int test(int n) +{ + switch (n) + { + case 0: + n++; + BOOST_FALLTHROUGH; + case 1: + n++; + break; + } + return n; +} + diff --git a/test/config_info.cpp b/test/config_info.cpp index 7381bd30..b4b435d1 100644 --- a/test/config_info.cpp +++ b/test/config_info.cpp @@ -1100,27 +1100,6 @@ void print_boost_macros() PRINT_MACRO(BOOST_NO_USING_TEMPLATE); PRINT_MACRO(BOOST_NO_VOID_RETURNS); - - - - - - - - - - - - - - - - - - - - - // END GENERATED BLOCK PRINT_MACRO(BOOST_INTEL); @@ -1132,6 +1111,7 @@ void print_boost_macros() PRINT_MACRO(BOOST_STATIC_CONSTEXPR); PRINT_MACRO(BOOST_NOEXCEPT); PRINT_MACRO(BOOST_FORCEINLINE); + PRINT_MACRO(BOOST_FALLTHROUGH); } void print_separator()