Use static_assert where available
This commit is contained in:
parent
e784dd4357
commit
07877853ba
45
SConstruct
45
SConstruct
|
@ -81,7 +81,7 @@ class ConfigureTests:
|
||||||
context.sconf.Define(macro_name, self.comment_not_supported)
|
context.sconf.Define(macro_name, self.comment_not_supported)
|
||||||
def __compiler_test_already_done(self,context):
|
def __compiler_test_already_done(self,context):
|
||||||
pass
|
pass
|
||||||
def Compile(self,context,text,msg,ext='.cpp',successflags={},skipped=None,successmsg=None,failuremsg=None):
|
def Compile(self,context,text,msg,ext='.cpp',testflags={},successflags={},skipped=None,successmsg=None,failuremsg=None,expect_failure=False):
|
||||||
self.__automatic_compiler_tests.pop(ext, self.__compiler_test_already_done)(context)
|
self.__automatic_compiler_tests.pop(ext, self.__compiler_test_already_done)(context)
|
||||||
context.Message('%s: checking %s...' % (self.msgprefix, msg))
|
context.Message('%s: checking %s...' % (self.msgprefix, msg))
|
||||||
if skipped is not None:
|
if skipped is not None:
|
||||||
|
@ -97,15 +97,18 @@ class ConfigureTests:
|
||||||
if co_name[0:6] == 'check_':
|
if co_name[0:6] == 'check_':
|
||||||
forced = self._check_forced(context, co_name[6:])
|
forced = self._check_forced(context, co_name[6:])
|
||||||
if forced is not None:
|
if forced is not None:
|
||||||
context.Result('(forced){forced}'.format(forced='yes' if forced else 'no'))
|
if expect_failure:
|
||||||
|
forced = not forced
|
||||||
|
context.Result('(forced){inverted}{forced}'.format(forced='yes' if forced else 'no', inverted='(inverted)' if expect_failure else ''))
|
||||||
return forced
|
return forced
|
||||||
break
|
break
|
||||||
frame = frame.f_back
|
frame = frame.f_back
|
||||||
env_flags = {k: context.env[k][:] for k in successflags.keys()}
|
env_flags = {k: context.env[k][:] for k in successflags.keys() + testflags.keys()}
|
||||||
context.env.Append(**successflags)
|
context.env.Append(**successflags)
|
||||||
caller_modified_env_flags = {k: context.env[k][:] for k in self.__flags_Werror.keys()}
|
caller_modified_env_flags = {k: context.env[k][:] for k in self.__flags_Werror.keys() + testflags.keys()}
|
||||||
# Always pass -Werror
|
# Always pass -Werror
|
||||||
context.env.Append(**self.__flags_Werror)
|
context.env.Append(**self.__flags_Werror)
|
||||||
|
context.env.Append(**testflags)
|
||||||
# Force verbose output to sconf.log
|
# Force verbose output to sconf.log
|
||||||
cc_env_strings = {}
|
cc_env_strings = {}
|
||||||
for k in ['CXXCOMSTR']:
|
for k in ['CXXCOMSTR']:
|
||||||
|
@ -115,6 +118,8 @@ class ConfigureTests:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
r = context.TryCompile(text + '\n', ext)
|
r = context.TryCompile(text + '\n', ext)
|
||||||
|
if expect_failure:
|
||||||
|
r = not r
|
||||||
# Restore potential quiet build options
|
# Restore potential quiet build options
|
||||||
context.env.Replace(**cc_env_strings)
|
context.env.Replace(**cc_env_strings)
|
||||||
context.Result((successmsg if r else failuremsg) or r)
|
context.Result((successmsg if r else failuremsg) or r)
|
||||||
|
@ -238,6 +243,38 @@ auto f()->int;
|
||||||
'''
|
'''
|
||||||
if self.Compile(context, text=f, msg='for C++11 function declarator syntax', skipped=self.__skip_missing_cxx11(cxx11_check_result)):
|
if self.Compile(context, text=f, msg='for C++11 function declarator syntax', skipped=self.__skip_missing_cxx11(cxx11_check_result)):
|
||||||
context.sconf.Define('DXX_HAVE_CXX11_FUNCTION_AUTO')
|
context.sconf.Define('DXX_HAVE_CXX11_FUNCTION_AUTO')
|
||||||
|
def _check_static_assert_method(self,context,msg,f,testflags={},**kwargs):
|
||||||
|
return self.Compile(context, text=f % 'true', msg=msg % 'true', testflags=testflags, **kwargs) and \
|
||||||
|
self.Compile(context, text=f % 'false', msg=msg % 'false', expect_failure=True, successflags=testflags, **kwargs)
|
||||||
|
@_implicit_test
|
||||||
|
def check_boost_static_assert(self,context,f):
|
||||||
|
"""
|
||||||
|
help:assume Boost.StaticAssert works
|
||||||
|
"""
|
||||||
|
return self._check_static_assert_method(context, 'for Boost.StaticAssert when %s', f, testflags={'CPPDEFINES' : ['DXX_HAVE_BOOST_STATIC_ASSERT']})
|
||||||
|
@_implicit_test
|
||||||
|
def check_c_typedef_static_assert(self,context,f):
|
||||||
|
"""
|
||||||
|
help:assume C typedef-based static assertion works
|
||||||
|
"""
|
||||||
|
return self._check_static_assert_method(context, 'for C typedef static assertion when %s', f, testflags={'CPPDEFINES' : ['DXX_HAVE_C_TYPEDEF_STATIC_ASSERT']})
|
||||||
|
@__cxx11
|
||||||
|
@_implicit_test
|
||||||
|
def check_cxx11_static_assert(self,context,f,cxx11_check_result):
|
||||||
|
"""
|
||||||
|
help:assume compiler supports C++ intrinsic static_assert
|
||||||
|
"""
|
||||||
|
return self._check_static_assert_method(context, 'for C++ intrinsic static_assert when %s', f, skipped=self.__skip_missing_cxx11(cxx11_check_result))
|
||||||
|
@_custom_test
|
||||||
|
def _check_static_assert(self,context):
|
||||||
|
f = '''
|
||||||
|
#define DXX_WANT_STATIC_ASSERT
|
||||||
|
#include "compiler.h"
|
||||||
|
static_assert(%s, "");
|
||||||
|
'''
|
||||||
|
how = self.check_cxx11_static_assert(context,f) or self.check_boost_static_assert(context,f) or self.check_c_typedef_static_assert(context,f)
|
||||||
|
if not how:
|
||||||
|
raise SCons.Errors.StopError("C++ compiler does not support static_assert or Boost.StaticAssert or typedef-based static assertion.")
|
||||||
|
|
||||||
class LazyObjectConstructor:
|
class LazyObjectConstructor:
|
||||||
def __lazy_objects(self,name,source):
|
def __lazy_objects(self,name,source):
|
||||||
|
|
|
@ -38,3 +38,13 @@ static auto array_identity(T (&t)[N]) -> T(&)[N] { return t; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(DXX_WANT_STATIC_ASSERT) && !defined(DXX_INCLUDED_STATIC_ASSERT)
|
||||||
|
#define DXX_INCLUDED_STATIC_ASSERT
|
||||||
|
#if defined(DXX_HAVE_BOOST_STATIC_ASSERT)
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#define static_assert(C,M) BOOST_STATIC_ASSERT_MSG((C),M)
|
||||||
|
#elif defined(DXX_HAVE_C_TYPEDEF_STATIC_ASSERT)
|
||||||
|
#define static_assert(C,M) typedef int static_assertion_check[(C) ? 1 : -1];
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
|
@ -17,6 +17,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define DXX_WANT_STATIC_ASSERT
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -51,6 +52,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
||||||
#include "byteswap.h"
|
#include "byteswap.h"
|
||||||
#include "makesig.h"
|
#include "makesig.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
#include "compiler.h"
|
||||||
|
|
||||||
#if defined(DXX_BUILD_DESCENT_I)
|
#if defined(DXX_BUILD_DESCENT_I)
|
||||||
#include "custom.h"
|
#include "custom.h"
|
||||||
|
@ -171,9 +173,9 @@ typedef struct DiskBitmapHeader {
|
||||||
int offset;
|
int offset;
|
||||||
} __pack__ DiskBitmapHeader;
|
} __pack__ DiskBitmapHeader;
|
||||||
#if defined(DXX_BUILD_DESCENT_I)
|
#if defined(DXX_BUILD_DESCENT_I)
|
||||||
typedef char padding_check[sizeof(DiskBitmapHeader) == 0x11 ? 1 : -1];
|
static_assert(sizeof(DiskBitmapHeader) == 0x11, "sizeof(DiskBitmapHeader) must be 0x11");
|
||||||
#elif defined(DXX_BUILD_DESCENT_II)
|
#elif defined(DXX_BUILD_DESCENT_II)
|
||||||
typedef char padding_check[sizeof(DiskBitmapHeader) == 0x12 ? 1 : -1];
|
static_assert(sizeof(DiskBitmapHeader) == 0x12, "sizeof(DiskBitmapHeader) must be 0x12");
|
||||||
|
|
||||||
#define DISKBITMAPHEADER_D1_SIZE 17 // no wh_extra
|
#define DISKBITMAPHEADER_D1_SIZE 17 // no wh_extra
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue