Add helper macro DXX_CONSTANT_TRUE

This commit is contained in:
Kp 2015-07-29 03:05:28 +00:00
parent cfd08b5d6c
commit 4d8ae44794
9 changed files with 23 additions and 27 deletions

View file

@ -484,6 +484,7 @@ static int a(int b){
if self.Link(context, text=f % 'c(b)', main=main, msg='whether compiler optimizes __builtin_constant_p'):
context.sconf.Define('DXX_HAVE_BUILTIN_CONSTANT_P')
context.sconf.Define('dxx_builtin_constant_p(A)', '__builtin_constant_p(A)')
context.sconf.Define('DXX_CONSTANT_TRUE(E)', '(__builtin_constant_p((E)) && (E))')
else:
self.Compile(context, text=f % '2', main=main, msg='whether compiler accepts __builtin_constant_p')
context.sconf.Define('dxx_builtin_constant_p(A)', '((void)(A),0)')

View file

@ -210,8 +210,8 @@ template <std::size_t N>
static inline void g3_draw_tmap(unsigned nv, const array<cg3s_point *, N> &pointlist, const array<g3s_uvl, N> &uvl_list, const array<g3s_lrgb, N> &light_rgb, grs_bitmap &bm)
{
static_assert(N <= MAX_POINTS_PER_POLY, "too many points in tmap");
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
if (__builtin_constant_p(nv > N) && nv > N)
#ifdef DXX_CONSTANT_TRUE
if (DXX_CONSTANT_TRUE(nv > N))
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_tmap_overread, "reading beyond array");
#endif
_g3_draw_tmap(nv, &pointlist[0], &uvl_list[0], &light_rgb[0], bm);

View file

@ -60,8 +60,8 @@ public:
template <std::size_t N>
std::size_t copy_if(std::size_t out_offset, const array<char, N> &i, std::size_t n = N)
{
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
if (__builtin_constant_p(n > N) && n > N)
#ifdef DXX_CONSTANT_TRUE
if (DXX_CONSTANT_TRUE(n > N))
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_overread, "read size exceeds array size");
#endif
return copy_if(out_offset, i.data(), n);
@ -76,8 +76,8 @@ public:
std::size_t copy_if(std::size_t offset, const char *i, std::size_t N)
{
const std::size_t d =
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
(__builtin_constant_p(i[N - 1]) && !i[N - 1]) ? N - 1 :
#ifdef DXX_CONSTANT_TRUE
(DXX_CONSTANT_TRUE(!i[N - 1])) ? N - 1 :
#endif
std::distance(i, std::find(i, i + N, terminator()));
return _copy_n(offset, i, d);

View file

@ -109,8 +109,8 @@ template <std::size_t N>
static inline void g3_draw_tmap_2(unsigned nv, const array<cg3s_point *, N> &pointlist, const array<g3s_uvl, N> &uvl_list, const array<g3s_lrgb, N> &light_rgb, grs_bitmap *bmbot, grs_bitmap *bm, int orient)
{
static_assert(N <= MAX_POINTS_PER_POLY, "too many points in tmap");
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
if (__builtin_constant_p(nv) && nv > N)
#ifdef DXX_CONSTANT_TRUE
if (DXX_CONSTANT_TRUE(nv > N))
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_tmap_overread, "reading beyond array");
#endif
_g3_draw_tmap_2(nv, &pointlist[0], &uvl_list[0], &light_rgb[0], bmbot, bm, orient);

View file

@ -163,7 +163,7 @@ static inline void check_range_bounds(const char (&file)[NF], unsigned line, con
* !DXX_HAVE_BUILTIN_CONSTANT_P and the macro expands to nothing.
*/
#define PARTIAL_RANGE_COMPILE_CHECK_BOUND(EXPR,S) \
(__builtin_constant_p(EXPR > d) && (EXPR > d) && (DXX_ALWAYS_ERROR_FUNCTION(partial_range_will_always_throw_##S, #S " will always throw"), 0))
(DXX_CONSTANT_TRUE(EXPR > d) && (DXX_ALWAYS_ERROR_FUNCTION(partial_range_will_always_throw_##S, #S " will always throw"), 0))
#else
#define PARTIAL_RANGE_COMPILE_CHECK_BOUND(EXPR,S) static_cast<void>(0)
#endif
@ -207,7 +207,7 @@ static inline partial_range_t<I> (unchecked_partial_range)(const char (&file)[NF
* happen, then the range is always empty, which likely indicates a
* bug.
*/
if (__builtin_constant_p(!(o < l)) && !(o < l))
if (DXX_CONSTANT_TRUE(!(o < l)))
DXX_ALWAYS_ERROR_FUNCTION(partial_range_is_always_empty, "offset never less than length");
#endif
#ifdef DXX_HAVE_BUILTIN_OBJECT_SIZE

View file

@ -42,7 +42,7 @@
#include "compiler-type_traits.h"
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
#define _DXX_PHYSFS_CHECK_SIZE_CONSTANT(S,v) (__builtin_constant_p((S) > v) && (S) > v)
#define _DXX_PHYSFS_CHECK_SIZE_CONSTANT(S,v) DXX_CONSTANT_TRUE((S) > (v))
#define _DXX_PHYSFS_CHECK_SIZE(S,C,v) _DXX_PHYSFS_CHECK_SIZE_CONSTANT(static_cast<size_t>(S) * static_cast<size_t>(C), v)
#define DXX_PHYSFS_CHECK_READ_SIZE_OBJECT_SIZE(S,C,v) \
(void)(__builtin_object_size(v, 1) != static_cast<size_t>(-1) && _DXX_PHYSFS_CHECK_SIZE(S,C,__builtin_object_size(v, 1)) && (DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_overwrite, "read size exceeds element size"), 0))

View file

@ -268,13 +268,11 @@ static inline vms_vector vm_vec_add (const vms_vector &src0, const vms_vector &s
vms_vector &_vm_vec_sub(vms_vector &dest, const vms_vector &src0, const vms_vector &src1);
static inline vms_vector &vm_vec_sub(vms_vector &dest, const vms_vector &src0, const vms_vector &src1)
{
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
#define vec_sub_constant_true(A) (__builtin_constant_p(A) && (A))
if (vec_sub_constant_true(&src0 == &src1))
#ifdef DXX_CONSTANT_TRUE
if (DXX_CONSTANT_TRUE(&src0 == &src1))
DXX_ALWAYS_ERROR_FUNCTION(vm_vec_sub_same_op, "vm_vec_sub with &src0 == &src1");
else if (vec_sub_constant_true(src0.x == src1.x && src0.y == src1.y && src0.z == src1.z))
else if (DXX_CONSTANT_TRUE(src0.x == src1.x && src0.y == src1.y && src0.z == src1.z))
DXX_ALWAYS_ERROR_FUNCTION(vm_vec_sub_same_values, "vm_vec_sub with equal value inputs");
#undef vec_sub_constant_true
#endif
return _vm_vec_sub(dest, src0, src1);
}

View file

@ -119,15 +119,12 @@ static inline void multi_send_data(ubyte *buf, unsigned len, int priority)
{
buf[0] = C;
unsigned expected = command_length<C>::value;
#ifdef DXX_CONSTANT_TRUE
if (DXX_CONSTANT_TRUE(len != expected))
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_multi_send_data, "wrong packet size");
#endif
if (len != expected)
{
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
/* Restate (len != expected) for <gcc-4.9. Otherwise it reports
* failure on valid inputs.
*/
if (__builtin_constant_p(len != expected) && len != expected)
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_multi_send_data, "wrong packet size");
#endif
Error("multi_send_data: Packet type %i length: %i, expected: %i\n", C, len, expected);
}
_multi_send_data(buf, len, priority);

View file

@ -945,12 +945,12 @@ static void multi_send_data_direct(ubyte *buf, unsigned len, const playernum_t p
{
buf[0] = C;
unsigned expected = command_length<C>::value;
#ifdef DXX_CONSTANT_TRUE
if (DXX_CONSTANT_TRUE(len != expected))
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_multi_send_data, "wrong packet size");
#endif
if (len != expected)
{
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
if (__builtin_constant_p(len) && __builtin_constant_p(len != expected))
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_multi_send_data, "wrong packet size");
#endif
Error("multi_send_data_direct: Packet type %i length: %i, expected: %i\n", C, len, expected);
}
_multi_send_data_direct(buf, len, pnum, priority);