Add _COGL_STATIC_ASSERT macro
This adds a _COGL_STATIC_ASSERT macro that can be used for compile time assertions in C code. If supported by the compiler this macro uses _Static_assert so that a message can be printed out if the assertion fails. Reviewed-by: Neil Roberts <neil@linux.intel.com> (cherry picked from commit 465b39a764f2720e77678cafa56acb0e69007ffd)
This commit is contained in:
parent
eaf29af7ee
commit
097d282b32
@ -37,7 +37,10 @@
|
|||||||
|
|
||||||
/* This code assumes that we can cast an unsigned long to a pointer
|
/* This code assumes that we can cast an unsigned long to a pointer
|
||||||
and back without losing any data */
|
and back without losing any data */
|
||||||
G_STATIC_ASSERT (sizeof (unsigned long) <= sizeof (void *));
|
_COGL_STATIC_ASSERT (sizeof (unsigned long) <= sizeof (void *),
|
||||||
|
"This toolchain breaks Cogl's assumption that it can "
|
||||||
|
"safely cast an unsigned long to a pointer without "
|
||||||
|
"loosing data");
|
||||||
|
|
||||||
#define ARRAY_INDEX(bit_num) \
|
#define ARRAY_INDEX(bit_num) \
|
||||||
((bit_num) / (sizeof (unsigned long) * 8))
|
((bit_num) / (sizeof (unsigned long) * 8))
|
||||||
|
@ -2590,8 +2590,13 @@ _cogl_pipeline_init_layer_state_hash_functions (void)
|
|||||||
layer_state_hash_functions[_index] =
|
layer_state_hash_functions[_index] =
|
||||||
_cogl_pipeline_layer_hash_fragment_snippets_state;
|
_cogl_pipeline_layer_hash_fragment_snippets_state;
|
||||||
|
|
||||||
|
{
|
||||||
/* So we get a big error if we forget to update this code! */
|
/* So we get a big error if we forget to update this code! */
|
||||||
g_assert (COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT == 10);
|
_COGL_STATIC_ASSERT (COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT == 10,
|
||||||
|
"Don't forget to install a hash function for new "
|
||||||
|
"pipeline state and update assert at end of "
|
||||||
|
"_cogl_pipeline_init_state_hash_functions");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -2697,8 +2702,13 @@ _cogl_pipeline_init_state_hash_functions (void)
|
|||||||
state_hash_functions[COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX] =
|
state_hash_functions[COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX] =
|
||||||
_cogl_pipeline_hash_fragment_snippets_state;
|
_cogl_pipeline_hash_fragment_snippets_state;
|
||||||
|
|
||||||
|
{
|
||||||
/* So we get a big error if we forget to update this code! */
|
/* So we get a big error if we forget to update this code! */
|
||||||
g_assert (COGL_PIPELINE_STATE_SPARSE_COUNT == 16);
|
_COGL_STATIC_ASSERT (COGL_PIPELINE_STATE_SPARSE_COUNT == 16,
|
||||||
|
"Make sure to install a hash function for "
|
||||||
|
"newly added pipeline state and update assert "
|
||||||
|
"in _cogl_pipeline_init_state_hash_functions");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
|
@ -34,6 +34,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Double check that config.h has been included */
|
||||||
|
#if !defined (GETTEXT_PACKAGE) && !defined (_COGL_IN_TEST_BITMASK)
|
||||||
|
#error "config.h must be included before including cogl-util.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* When compiling with Visual Studio, symbols that represent data that
|
/* When compiling with Visual Studio, symbols that represent data that
|
||||||
are exported out of the DLL need to be marked with the dllexport
|
are exported out of the DLL need to be marked with the dllexport
|
||||||
attribute. */
|
attribute. */
|
||||||
@ -227,4 +232,50 @@ _cogl_util_pixel_format_from_masks (unsigned long r_mask,
|
|||||||
int depth, int bpp,
|
int depth, int bpp,
|
||||||
int byte_order);
|
int byte_order);
|
||||||
|
|
||||||
|
/* Since we can't rely on _Static_assert always being available for
|
||||||
|
* all compilers we have limited static assert that can be used in
|
||||||
|
* C code but not in headers.
|
||||||
|
*/
|
||||||
|
#define _COGL_TYPEDEF_ASSERT(EXPRESSION) \
|
||||||
|
typedef struct { char Compile_Time_Assertion[(EXPRESSION) ? 1 : -1]; } \
|
||||||
|
G_PASTE (_GStaticAssert_, __LINE__)
|
||||||
|
|
||||||
|
/* _COGL_STATIC_ASSERT:
|
||||||
|
* @expression: An expression to assert evaluates to true at compile
|
||||||
|
* time.
|
||||||
|
* @message: A message to print to the console if the assertion fails
|
||||||
|
* at compile time.
|
||||||
|
*
|
||||||
|
* Allows you to assert that an expression evaluates to true at
|
||||||
|
* compile time and aborts compilation if not. If possible message
|
||||||
|
* will also be printed if the assertion fails.
|
||||||
|
*
|
||||||
|
* Note: Only Gcc >= 4.6 supports the c11 _Static_assert which lets us
|
||||||
|
* print a nice message if the compile time assertion fails.
|
||||||
|
*
|
||||||
|
* Note: this assertion macro can only be used in C code where it is
|
||||||
|
* valid to use a typedef. This macro should not be used in headers
|
||||||
|
* because we can't guarantee a unique name for the typedef due to
|
||||||
|
* the name being based on the line number of the file it's used in.
|
||||||
|
*
|
||||||
|
* Although we can remove this limitation if the compiler supports
|
||||||
|
* _Static_assert we currently choose to maintain the limitation in
|
||||||
|
* any case to help ensure we don't accidentally create code that
|
||||||
|
* doesn't compile on some toolchains because we forgot about this
|
||||||
|
* limitation.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_STATIC_ASSERT
|
||||||
|
#define _COGL_STATIC_ASSERT(EXPRESSION, MESSAGE) \
|
||||||
|
_Static_assert (EXPRESSION, MESSAGE); \
|
||||||
|
_COGL_TYPEDEF_ASSERT(EXPRESSION)
|
||||||
|
#else
|
||||||
|
#define _COGL_STATIC_ASSERT(EXPRESSION, MESSAGE) \
|
||||||
|
_COGL_TYPEDEF_ASSERT(EXPRESSION)
|
||||||
|
|
||||||
|
/* So that we can safely use _Static_assert() if we want to add
|
||||||
|
* assertions to internal headers we define it to a NOP here
|
||||||
|
* if it's not supported by the compiler. */
|
||||||
|
#define _Static_assert(EXPRESSION, MESSAGE)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __COGL_UTIL_H */
|
#endif /* __COGL_UTIL_H */
|
||||||
|
13
configure.ac
13
configure.ac
@ -935,6 +935,19 @@ AM_PROG_CC_C_O
|
|||||||
AC_ISC_POSIX
|
AC_ISC_POSIX
|
||||||
AC_C_CONST
|
AC_C_CONST
|
||||||
|
|
||||||
|
dnl ============================================================
|
||||||
|
dnl Compiler features
|
||||||
|
dnl ============================================================
|
||||||
|
AC_TRY_COMPILE([],
|
||||||
|
[
|
||||||
|
_Static_assert (1, "");
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[AC_DEFINE([HAVE_STATIC_ASSERT], [1], [Whether _Static_assert can be used or not])])
|
||||||
|
|
||||||
dnl ================================================================
|
dnl ================================================================
|
||||||
dnl Libtool stuff.
|
dnl Libtool stuff.
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
within Cogl. Cogl doesn't export the symbols for this data type so
|
within Cogl. Cogl doesn't export the symbols for this data type so
|
||||||
we just directly include the source instead */
|
we just directly include the source instead */
|
||||||
|
|
||||||
|
#define _COGL_IN_TEST_BITMASK
|
||||||
#include <cogl/cogl-bitmask.h>
|
#include <cogl/cogl-bitmask.h>
|
||||||
#include <cogl/cogl-bitmask.c>
|
#include <cogl/cogl-bitmask.c>
|
||||||
#define _COGL_IN_TEST_BITMASK
|
|
||||||
#include <cogl/cogl-util.c>
|
#include <cogl/cogl-util.c>
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
Loading…
Reference in New Issue
Block a user