Skip to content

Commit

Permalink
🔀 Enable /W4 and /WX for MSVC
Browse files Browse the repository at this point in the history
MSVC is challenging to work with for its C++ comprehension and its
remarkably poor diagnostics. Enabling the highest warning level and
having the confidence to treat those warnings as errors is a complicated
task -- but is often useful if done correctly, since it provides
better confidence that consumers using this compiler will not experience
warnings (or errors) in their own code.

MSVC 2015 is beyond challenged. It emits numerous false diagnostics
about code being "unreachable", when it is, or for arguments not being
used, when they are. MSVC, an intellectual, even likes to emit warnings
for `__forceinline`d functions not being inlined **at the end of the
translation unit being compiled**. That literally means you cannot
disable the diagnostic with a push/pop pair. Other diagnostics exist
purely for the sake of attempting to use standard C++ functions that
MSVC arbitrarily chooses to **deprecate**.

👏 ... 👏 ... 👏

MSVC represents the true diversity of compilers on the market. I, for
one, think it's beautiful that we allow a challenged piece of software
work in a professional world. Good for Microsoft for not discriminating
based on quality and for exploring compiler diversity.

-----------------------------------------------------------------------

All code emitting the diagnostics have been addressed either by
suppressing the warnings directly, or rewriting the surrounding code.

/W4 and /WX is now on for both the build server and for any MSVC
compilation target -- so hopefully this will provide a reasonably
equivalent C++ experience to any consumer using this with MSVC.
  • Loading branch information
bitwizeshift committed Jul 19, 2020
2 parents d441d86 + 3ca0cd5 commit 6d82dc6
Show file tree
Hide file tree
Showing 38 changed files with 351 additions and 4 deletions.
9 changes: 8 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
cmake_minimum_required(VERSION 3.5)

# Disable defaulting the warning flags for MSVC
# this isn't bad, it's just inconvenient
cmake_policy(SET CMP0092 NEW)

if (PROJECT_NAME)
set(IS_SUBPROJECT TRUE)
endif ()
Expand Down Expand Up @@ -69,6 +73,9 @@ set(header_files
"include/bpstd/variant.hpp"
)

include(SourceGroup)
source_group_tree("include" PREFIX "Header Files" FILES ${header_files})

add_library(${PROJECT_NAME} INTERFACE)
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})

Expand All @@ -93,7 +100,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" )
add_compile_options(-Wall -Werror -Wextra -pedantic -pedantic-errors)
elseif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" )
# TODO: Determine MSVC necessary compiler flags
add_compile_options(/W4 /WX)
endif ()

# Header Self-Containment Tests
Expand Down
109 changes: 109 additions & 0 deletions cmake/SourceGroup.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Copyright (c) Matthew Rodusek
# Distributed under the OSI-approved MIT License. See accompanying
# file LICENSE.txt or https://opensource.org/licenses/MIT for details.

#.rst:
# SourceGroup
# -----------
#
# This module defines additional source_group functionality that is
# compatible with older versions of CMake

if (CMAKE_VERSION VERSION_LESS 3.5.0)
include(CMakeParseArguments)
endif ()

#.rst
# .. command:: source_group_tree
#
# This command defines a grouping for source files in IDE project
# generation.
#
# This function is not supported in CMake 3.7 or before, and is
# added here for compatibility.
#
# If this is executed in CMake 3.8 or later, it defaults to
# source_group(TREE ...) instead to preserve functionality.
#
# .. code-block:: cmake
#
# source_group_tree(<root> [PREFIX <prefix>] [FILES <src>])
#
# Creates groups recursively based on the specified ``<root>``
# along with their relative paths to the given source files.
#
# The options are:
#
# ``PREFIX``
# Source group and files located directly in <root> path, will
# be placed in <prefix> source groups.
#
# ``FILES``
# Any source file specified explicitly will be placed in group
# made up of the relative path between ``<root>`` and the file.
# Relative paths are interpreted with respect to the
# current source directory.
# It is an error if any ``<src>`` is not prefixed by ``<prefix>``
function(source_group_tree root)

cmake_parse_arguments(
SOURCE_GROUP_TREE # Prefix
"" # Option args
PREFIX # Single args
FILES # Multi args
${ARGN}
)

if (SOURCE_GROUP_TREE_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "source_group: Unknown arguments specified: ${SOURCE_GROUP_TREE_UNPARSED_ARGUMENTS}")
endif ()

if (IS_ABSOLUTE "${root}")
set(root_path "${root}")
else ()
set(root_path "${CMAKE_CURRENT_SOURCE_DIR}/${root}")
get_filename_component(root_path "${root_path}" ABSOLUTE)
endif ()

# source_group(TREE ...) introduced in 3.8
if (CMAKE_VERSION VERSION_GREATER 3.8)
set(args)
if (SOURCE_GROUP_TREE_PREFIX)
set(args PREFIX "${SOURCE_GROUP_TREE_PREFIX}" ${args})
endif ()
if (SOURCE_GROUP_TREE_FILES)
set(args FILES "${SOURCE_GROUP_TREE_FILES}" ${args})
endif ()
source_group( TREE "${root_path}" ${args} )
else ()
foreach (file IN LISTS SOURCE_GROUP_TREE_FILES)
if (SOURCE_GROUP_TREE_PREFIX)
set(group "${SOURCE_GROUP_TREE_PREFIX}")
else ()
set(group)
endif ()

if (IS_ABSOLUTE "${file}")
set(absolute_file "${file}")
else ()
# All relative paths should be relative to the source directory
set(absolute_file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
get_filename_component(absolute_file "${absolute_file}" ABSOLUTE)
endif ()

file(RELATIVE_PATH group_suffix "${root_path}" "${absolute_file}")
if (group_suffix MATCHES "(\\.\\.).*")
message(FATAL_ERROR "source_group ROOT: ${root_path} is not a prefix of file ${absolute_file}")
endif ()
get_filename_component(group_suffix "${group_suffix}" DIRECTORY)
string(REPLACE "/" "\\" group_suffix "${group_suffix}")

if (group AND group_suffix)
set(group "${SOURCE_GROUP_TREE_PREFIX}\\${group_suffix}")
elseif (group_suffix)
set(group "${group_suffix}")
endif ()
source_group("${group}" FILES "${absolute_file}")
endforeach ()
endif ()
endfunction()
4 changes: 4 additions & 0 deletions include/bpstd/any.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
#include <new> // placement-new
#include <cassert> // assert

BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE

namespace bpstd {

class any;
Expand Down Expand Up @@ -928,4 +930,6 @@ const T* bpstd::any_cast(const any* operand)
return static_cast<const T*>(p);
}

BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE

#endif /* BPSTD_ANY_HPP */
3 changes: 3 additions & 0 deletions include/bpstd/chrono.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include <chrono> // std::chrono::duration, std::chrono::system_clock, etc
#include <cstdint> // std::int32_t

BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE

namespace bpstd {
namespace chrono {

Expand Down Expand Up @@ -182,5 +184,6 @@ bpstd::chrono::duration<double, std::nano>
return chrono::duration<double, std::nano>{x};
}

BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE

#endif /* BPSTD_CHRONO_HPP */
3 changes: 3 additions & 0 deletions include/bpstd/complex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@

#include <complex>

BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE

namespace bpstd {

//============================================================================
Expand Down Expand Up @@ -115,5 +117,6 @@ bpstd::complex<float>
return complex<float>{0, static_cast<float>(i)};
}

BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE

#endif /* BPSTD_COMPLEX_HPP */
6 changes: 6 additions & 0 deletions include/bpstd/cstddef.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
#include <type_traits> // std::is_integral
#include <cstddef> // __cpp_lib_byte, and to proxy API

BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE

// The below implementation is based on GSL's implementation of 'gsl::byte'

// VS2017 15.8 added support for the __cpp_lib_byte definition
// To do: drop _HAS_STD_BYTE when support for pre 15.8 expires
#if defined(_MSC_VER)
Expand Down Expand Up @@ -249,4 +253,6 @@ Integer bpstd::to_integer(byte b)
return static_cast<Integer>(b);
}

BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE

#endif /* BPSTD_CSTDDEF_HPP */
16 changes: 16 additions & 0 deletions include/bpstd/detail/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,20 @@
# define BPSTD_INLINE_VISIBILITY
#endif

#if defined(_MSC_VER)
# define BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE \
__pragma(warning(push)) \
__pragma(warning(disable:4714)) \
__pragma(warning(disable:4100))
#else
# define BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
#endif

#if defined(_MSC_VER)
# define BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE \
__pragma(warning(pop))
#else
# define BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
#endif

#endif /* BPSTD_DETAIL_CONFIG_HPP */
4 changes: 4 additions & 0 deletions include/bpstd/detail/invoke.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@

#include <utility>

BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE

namespace bpstd {
namespace detail {

Expand Down Expand Up @@ -181,4 +183,6 @@ namespace bpstd {
} // namespace detail
} // namespace bpstd

BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE

#endif /* BPSTD_DETAIL_INVOKE_HPP */
4 changes: 4 additions & 0 deletions include/bpstd/detail/move.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@

#include <type_traits>

BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE

namespace bpstd {

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -108,4 +110,6 @@ typename std::remove_reference<T>::type&& bpstd::move(T&& x)
return static_cast<T&&>(x);
}

BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE

#endif /* BPSTD_DETAIL_MOVE_HPP */
3 changes: 3 additions & 0 deletions include/bpstd/detail/proxy_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
#include "config.hpp"
#include <iterator>

BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE

namespace bpstd {
namespace detail {

Expand Down Expand Up @@ -443,5 +445,6 @@ inline BPSTD_CPP14_CONSTEXPR bpstd::detail::proxy_iterator<Iterator,U>
return proxy_iterator<Iterator,U>{lhs} -= rhs;
}

BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE

#endif /* BPSTD_DETAIL_PROXY_ITERATOR_HPP */
15 changes: 14 additions & 1 deletion include/bpstd/detail/variant_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#include <cstddef> // std::size_t
#include <utility> // std::forward

BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE

namespace bpstd {
namespace detail {

Expand Down Expand Up @@ -188,17 +190,26 @@ bpstd::detail::variant_base<false,Types...>::variant_base()

}

#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable:4702)
#endif

template <typename...Types>
template <std::size_t N, typename...Args>
inline BPSTD_INLINE_VISIBILITY constexpr
bpstd::detail::variant_base<false,Types...>::variant_base(variant_index_tag<N>,
Args&&...args)
Args&&...args)
: m_union{variant_index_tag<N>{}, std::forward<Args>(args)...},
m_index{N}
{

}

#if defined(_MSC_VER)
# pragma warning(pop)
#endif

//------------------------------------------------------------------------------

template <typename...Types>
Expand All @@ -224,4 +235,6 @@ void bpstd::detail::variant_base<false,Types...>::destroy_active_object()
m_index = static_cast<std::size_t>(-1);
}

BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE

#endif /* BPSTD_DETAIL_VARIANT_BASE_HPP */
5 changes: 5 additions & 0 deletions include/bpstd/detail/variant_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@
#ifndef BPSTD_DETAIL_VARIANT_TRAITS_HPP
#define BPSTD_DETAIL_VARIANT_TRAITS_HPP

#include "config.hpp"
#include "variant_fwds.hpp"
#include "invoke.hpp" // invoke_result

BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE

namespace bpstd {
namespace detail {

Expand Down Expand Up @@ -104,4 +107,6 @@ namespace bpstd {
} // namespace detail
} // namespace bpstd

BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE

#endif /* BPSTD_DETAIL_VARIANT_TRAITS_HPP */
4 changes: 4 additions & 0 deletions include/bpstd/detail/variant_union.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#include <type_traits> // std::decay
#include <initializer_list>

BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE

namespace bpstd {
namespace detail {

Expand Down Expand Up @@ -573,4 +575,6 @@ const bpstd::detail::nth_type_t<N,Types...>&&
return bpstd::move(do_union_get(variant_index_tag<N>{}, u));
}

BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE

#endif /* BPSTD_DETAIL_VARIANT_UNION_HPP */
4 changes: 4 additions & 0 deletions include/bpstd/detail/variant_visitors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#include <new> // placement new
#include <utility> // std::swap

BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE

namespace bpstd {
namespace detail {

Expand Down Expand Up @@ -188,4 +190,6 @@ namespace bpstd {
} // namespace detail
} // namespace bpstd

BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE

#endif /* BPSTD_DETAIL_VARIANT_VISITORS_HPP */
4 changes: 4 additions & 0 deletions include/bpstd/exception.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@

#include <exception>

BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE

// The large #if/endif block below, and the definition of
// bpstd::uncaught_exceptions is taken from boost:
// https://beta.boost.org/doc/libs/develop/boost/core/uncaught_exceptions.hpp
Expand Down Expand Up @@ -192,4 +194,6 @@ int bpstd::uncaught_exceptions()
#endif
}

BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE

#endif /* BPSTD_EXCEPTION_HPP */
Loading

0 comments on commit 6d82dc6

Please sign in to comment.