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
|
||||
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) \
|
||||
((bit_num) / (sizeof (unsigned long) * 8))
|
||||
|
@ -2590,8 +2590,13 @@ _cogl_pipeline_init_layer_state_hash_functions (void)
|
||||
layer_state_hash_functions[_index] =
|
||||
_cogl_pipeline_layer_hash_fragment_snippets_state;
|
||||
|
||||
{
|
||||
/* 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
|
||||
@ -2697,8 +2702,13 @@ _cogl_pipeline_init_state_hash_functions (void)
|
||||
state_hash_functions[COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX] =
|
||||
_cogl_pipeline_hash_fragment_snippets_state;
|
||||
|
||||
{
|
||||
/* 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
|
||||
|
@ -34,6 +34,11 @@
|
||||
#include <stdio.h>
|
||||
#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
|
||||
are exported out of the DLL need to be marked with the dllexport
|
||||
attribute. */
|
||||
@ -227,4 +232,50 @@ _cogl_util_pixel_format_from_masks (unsigned long r_mask,
|
||||
int depth, int bpp,
|
||||
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 */
|
||||
|
13
configure.ac
13
configure.ac
@ -935,6 +935,19 @@ AM_PROG_CC_C_O
|
||||
AC_ISC_POSIX
|
||||
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 Libtool stuff.
|
||||
|
@ -9,9 +9,9 @@
|
||||
within Cogl. Cogl doesn't export the symbols for this data type so
|
||||
we just directly include the source instead */
|
||||
|
||||
#define _COGL_IN_TEST_BITMASK
|
||||
#include <cogl/cogl-bitmask.h>
|
||||
#include <cogl/cogl-bitmask.c>
|
||||
#define _COGL_IN_TEST_BITMASK
|
||||
#include <cogl/cogl-util.c>
|
||||
|
||||
typedef struct
|
||||
|
Loading…
Reference in New Issue
Block a user