base: Check for static_assert support and provide fallback
C++11 has support for static_asserts to provide compile-time assertion checking. This is very useful when testing, for example, structure sizes to make sure that the compiler got the right alignment or vector sizes.
This commit is contained in:
parent
6598241f2c
commit
4544f3def4
2 changed files with 49 additions and 2 deletions
21
SConstruct
21
SConstruct
|
@ -684,17 +684,34 @@ def CheckLeading(context):
|
||||||
context.Result(ret)
|
context.Result(ret)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
# Test for the presence of C++11 static asserts. If the compiler lacks
|
||||||
|
# support for static asserts, base/compiler.hh enables a macro that
|
||||||
|
# removes any static asserts in the code.
|
||||||
|
def CheckStaticAssert(context):
|
||||||
|
context.Message("Checking for C++11 static_assert support...")
|
||||||
|
ret = context.TryCompile('''
|
||||||
|
static_assert(1, "This assert is always true");
|
||||||
|
''', extension=".cc")
|
||||||
|
context.env.Append(HAVE_STATIC_ASSERT=ret)
|
||||||
|
context.Result(ret)
|
||||||
|
return ret
|
||||||
|
|
||||||
# Platform-specific configuration. Note again that we assume that all
|
# Platform-specific configuration. Note again that we assume that all
|
||||||
# builds under a given build root run on the same host platform.
|
# builds under a given build root run on the same host platform.
|
||||||
conf = Configure(main,
|
conf = Configure(main,
|
||||||
conf_dir = joinpath(build_root, '.scons_config'),
|
conf_dir = joinpath(build_root, '.scons_config'),
|
||||||
log_file = joinpath(build_root, 'scons_config.log'),
|
log_file = joinpath(build_root, 'scons_config.log'),
|
||||||
custom_tests = { 'CheckLeading' : CheckLeading })
|
custom_tests = { 'CheckLeading' : CheckLeading,
|
||||||
|
'CheckStaticAssert' : CheckStaticAssert,
|
||||||
|
})
|
||||||
|
|
||||||
# Check for leading underscores. Don't really need to worry either
|
# Check for leading underscores. Don't really need to worry either
|
||||||
# way so don't need to check the return code.
|
# way so don't need to check the return code.
|
||||||
conf.CheckLeading()
|
conf.CheckLeading()
|
||||||
|
|
||||||
|
# Check for C++11 features we want to use if they exist
|
||||||
|
conf.CheckStaticAssert()
|
||||||
|
|
||||||
# Check if we should compile a 64 bit binary on Mac OS X/Darwin
|
# Check if we should compile a 64 bit binary on Mac OS X/Darwin
|
||||||
try:
|
try:
|
||||||
import platform
|
import platform
|
||||||
|
@ -923,7 +940,7 @@ sticky_vars.AddVariables(
|
||||||
# These variables get exported to #defines in config/*.hh (see src/SConscript).
|
# These variables get exported to #defines in config/*.hh (see src/SConscript).
|
||||||
export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP',
|
export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP',
|
||||||
'TARGET_ISA', 'CP_ANNOTATE', 'USE_POSIX_CLOCK', 'PROTOCOL',
|
'TARGET_ISA', 'CP_ANNOTATE', 'USE_POSIX_CLOCK', 'PROTOCOL',
|
||||||
]
|
'HAVE_STATIC_ASSERT']
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
#
|
#
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#ifndef __BASE_COMPILER_HH__
|
#ifndef __BASE_COMPILER_HH__
|
||||||
#define __BASE_COMPILER_HH__
|
#define __BASE_COMPILER_HH__
|
||||||
|
|
||||||
|
#include "config/have_static_assert.hh"
|
||||||
|
|
||||||
//http://msdn2.microsoft.com/en-us/library/ms937669.aspx
|
//http://msdn2.microsoft.com/en-us/library/ms937669.aspx
|
||||||
//http://msdn2.microsoft.com/en-us/library/aa448724.aspx
|
//http://msdn2.microsoft.com/en-us/library/aa448724.aspx
|
||||||
//http://docs.sun.com/source/819-3688/sun.specific.html#marker-998278
|
//http://docs.sun.com/source/819-3688/sun.specific.html#marker-998278
|
||||||
|
@ -56,4 +58,32 @@
|
||||||
#error "Need to define compiler options in base/compiler.hh"
|
#error "Need to define compiler options in base/compiler.hh"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define a compatibility macro that emulates the behavior of
|
||||||
|
* static_assert using template magic if the compiler doesn't have
|
||||||
|
* native support.
|
||||||
|
*/
|
||||||
|
#if !HAVE_STATIC_ASSERT
|
||||||
|
|
||||||
|
template<bool>
|
||||||
|
struct static_assert_failure;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct static_assert_failure<false> {};
|
||||||
|
|
||||||
|
/* The following macro causes the compiler to evaluate the size of the
|
||||||
|
* static_assert_failure struct. The templates are designed so that
|
||||||
|
* only static_assert_failure<false> evaluates to a proper size, while
|
||||||
|
* static_assert_failure<true> generates a compile time error.
|
||||||
|
*/
|
||||||
|
#define static_assert(expr, msg) \
|
||||||
|
namespace ns_static_assert { \
|
||||||
|
enum { \
|
||||||
|
static_assert_ ## __LINE__ = \
|
||||||
|
sizeof(static_assert_failure<!(expr)>) \
|
||||||
|
}; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // __BASE_COMPILER_HH__
|
#endif // __BASE_COMPILER_HH__
|
||||||
|
|
Loading…
Reference in a new issue