SvREFCNT_dec(kid->op_sv);
#ifdef USE_ITHREADS
/* XXX hack: dependence on sizeof(PADOP) <= sizeof(SVOP) */
- assert (sizeof(PADOP) <= sizeof(SVOP));
+ STATIC_ASSERT_STMT(sizeof(PADOP) <= sizeof(SVOP));
kPADOP->op_padix = pad_alloc(OP_GV, SVf_READONLY);
SvREFCNT_dec(PAD_SVl(kPADOP->op_padix));
PAD_SETSV(kPADOP->op_padix, MUTABLE_SV(SvREFCNT_inc_simple_NN(gv)));
# define __attribute__warn_unused_result__
#endif
-#if defined(DEBUGGING) && defined(I_ASSERT)
+#ifdef I_ASSERT
+# if !defined(DEBUGGING) && !defined(NDEBUG)
+# define NDEBUG 1
+# endif
# include <assert.h>
#endif
/* placeholder */
#endif
+#if defined(static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L)
+/* static_assert is a macro defined in <assert.h> in C11 or a compiler
+ builtin in C++11.
+*/
+# define STATIC_ASSERT_GLOBAL(COND) static_assert(COND, #COND)
+#else
+/* We use a bit-field instead of an array because gcc accepts
+ 'typedef char x[n]' where n is not a compile-time constant.
+ We want to enforce constantness.
+*/
+# define STATIC_ASSERT_2(COND, SUFFIX) \
+ typedef struct { \
+ unsigned int _static_assertion_failed_##SUFFIX : (COND) ? 1 : -1; \
+ } _static_assertion_failed_##SUFFIX PERL_UNUSED_DECL
+# define STATIC_ASSERT_1(COND, SUFFIX) STATIC_ASSERT_2(COND, SUFFIX)
+# define STATIC_ASSERT_GLOBAL(COND) STATIC_ASSERT_1(COND, __LINE__)
+#endif
+/* We need this wrapper even in C11 because 'case X: static_assert(...);' is an
+ error (static_assert is a declaration, and only statements can have labels).
+*/
+#define STATIC_ASSERT_STMT(COND) do { STATIC_ASSERT_GLOBAL(COND); } while (0)
#ifndef __has_builtin
# define __has_builtin(x) 0 /* not a clang style compiler */
/* simplest case shortcut */
/* turn off SVf_UTF8 in tmp flags if HINT_BYTES on*/
U32 svflags = (SvFLAGS(sv) ^ (in_bytes << 26)) & (SVf_POK|SVs_GMG|SVf_UTF8);
- assert(HINT_BYTES == 0x00000008 && SVf_UTF8 == 0x20000000 && (SVf_UTF8 == HINT_BYTES << 26));
+ STATIC_ASSERT_STMT(HINT_BYTES == 0x00000008 && SVf_UTF8 == 0x20000000 && (SVf_UTF8 == HINT_BYTES << 26));
SETs(TARG);
if(LIKELY(svflags == SVf_POK))
(base << (OPpPADRANGE_COUNTSHIFT + SAVE_TIGHT_SHIFT))
| (count << SAVE_TIGHT_SHIFT)
| SAVEt_CLEARPADRANGE);
- assert(OPpPADRANGE_COUNTMASK + 1 == (1 <<OPpPADRANGE_COUNTSHIFT));
+ STATIC_ASSERT_STMT(OPpPADRANGE_COUNTMASK + 1 == (1 << OPpPADRANGE_COUNTSHIFT));
assert((payload >> (OPpPADRANGE_COUNTSHIFT+SAVE_TIGHT_SHIFT)) == base);
{
dSS_ADD;
PERL_ARGS_ASSERT_TIED_METHOD;
/* Ensure that our flag bits do not overlap. */
- assert((TIED_METHOD_MORTALIZE_NOT_NEEDED & G_WANT) == 0);
- assert((TIED_METHOD_ARGUMENTS_ON_STACK & G_WANT) == 0);
- assert((TIED_METHOD_SAY & G_WANT) == 0);
+ STATIC_ASSERT_STMT((TIED_METHOD_MORTALIZE_NOT_NEEDED & G_WANT) == 0);
+ STATIC_ASSERT_STMT((TIED_METHOD_ARGUMENTS_ON_STACK & G_WANT) == 0);
+ STATIC_ASSERT_STMT((TIED_METHOD_SAY & G_WANT) == 0);
PUTBACK; /* sp is at *foot* of args, so this pops args from old stack */
PUSHSTACKi(PERLSI_MAGIC);
break;
case SVt_PV:
assert(new_type > SVt_PV);
- assert(SVt_IV < SVt_PV);
- assert(SVt_NV < SVt_PV);
+ STATIC_ASSERT_STMT(SVt_IV < SVt_PV);
+ STATIC_ASSERT_STMT(SVt_NV < SVt_PV);
break;
case SVt_PVIV:
break;
/* We're starting from SVt_NULL, so provided that's
* actual 0, we don't have to unset any SV type flags
* to promote to SVt_IV. */
- assert(SVt_NULL == 0);
+ STATIC_ASSERT_STMT(SVt_NULL == 0);
SET_SVANY_FOR_BODYLESS_IV(dstr);
SvFLAGS(dstr) |= SVt_IV;
break;
/* We're starting from SVt_FIRST, so provided that's
* actual 0, we don't have to unset any SV type flags
* to promote to SVt_IV. */
- assert(SVt_FIRST == 0);
+ STATIC_ASSERT_STMT(SVt_FIRST == 0);
SET_SVANY_FOR_BODYLESS_IV(sv);
SvFLAGS(sv) |= SVt_IV;
parser->bufend = parser->bufptr + SvCUR(parser->linestr);
parser->last_lop = parser->last_uni = NULL;
- assert(FITS_IN_8_BITS(LEX_IGNORE_UTF8_HINTS|LEX_EVALBYTES
+ STATIC_ASSERT_STMT(FITS_IN_8_BITS(LEX_IGNORE_UTF8_HINTS|LEX_EVALBYTES
|LEX_DONT_CLOSE_RSFP));
parser->lex_flags = (U8) (flags & (LEX_IGNORE_UTF8_HINTS|LEX_EVALBYTES
|LEX_DONT_CLOSE_RSFP));