-#define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv
-#define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv
-#define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_nv
-#define SvPVX(sv) ((sv)->sv_u.svu_pv)
-#define SvPVX_mutable(sv) SvPVX(sv)
-#define SvPVX_const(sv) ((const char*)SvPVX(sv))
-#define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur
-#define SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len
-#define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
-
-#ifdef DEBUGGING
-#define SvMAGIC(sv) (*(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*) SvANY(sv))->xmg_magic))
-#define SvSTASH(sv) (*(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*) SvANY(sv))->xmg_stash))
-#else
-#define SvMAGIC(sv) ((XPVMG*) SvANY(sv))->xmg_magic
-#define SvSTASH(sv) ((XPVMG*) SvANY(sv))->xmg_stash
+# define SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len
+# define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
+
+# if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+/* These get expanded inside other macros that already use a variable _sv */
+# define SvPVX(sv) \
+ (*({ SV *const _svi = (SV *) sv; \
+ assert(SvTYPE(_svi) >= SVt_PV); \
+ assert(SvTYPE(_svi) != SVt_PVAV); \
+ assert(SvTYPE(_svi) != SVt_PVHV); \
+ assert(!isGV_with_GP(_svi)); \
+ &((_svi)->sv_u.svu_pv); \
+ }))
+# define SvCUR(sv) \
+ (*({ SV *const _svi = (SV *) sv; \
+ assert(SvTYPE(_svi) >= SVt_PV); \
+ assert(SvTYPE(_svi) != SVt_PVAV); \
+ assert(SvTYPE(_svi) != SVt_PVHV); \
+ assert(!isGV_with_GP(_svi)); \
+ &(((XPV*) SvANY(_svi))->xpv_cur); \
+ }))
+# define SvIVX(sv) \
+ (*({ SV *const _svi = (SV *) sv; \
+ assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \
+ assert(SvTYPE(_svi) != SVt_PVAV); \
+ assert(SvTYPE(_svi) != SVt_PVHV); \
+ assert(SvTYPE(_svi) != SVt_PVCV); \
+ assert(!isGV_with_GP(_svi)); \
+ &(((XPVIV*) SvANY(_svi))->xiv_iv); \
+ }))
+# define SvUVX(sv) \
+ (*({ SV *const _svi = (SV *) sv; \
+ assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \
+ assert(SvTYPE(_svi) != SVt_PVAV); \
+ assert(SvTYPE(_svi) != SVt_PVHV); \
+ assert(SvTYPE(_svi) != SVt_PVCV); \
+ assert(!isGV_with_GP(_svi)); \
+ &(((XPVUV*) SvANY(_svi))->xuv_uv); \
+ }))
+# define SvNVX(sv) \
+ (*({ SV *const _svi = (SV *) sv; \
+ assert(SvTYPE(_svi) == SVt_NV || SvTYPE(_svi) >= SVt_PVNV); \
+ assert(SvTYPE(_svi) != SVt_PVAV); \
+ assert(SvTYPE(_svi) != SVt_PVHV); \
+ assert(SvTYPE(_svi) != SVt_PVFM); \
+ assert(!isGV_with_GP(_svi)); \
+ &(((XPVNV*) SvANY(_svi))->xnv_u.xnv_nv); \
+ }))
+# define SvMAGIC(sv) \
+ (*({ SV *const _svi = (SV *) sv; \
+ assert(SvTYPE(_svi) >= SVt_PVMG); \
+ if(SvTYPE(_svi) == SVt_PVMG) \
+ assert(!SvPAD_OUR(_svi)); \
+ &(((XPVMG*) SvANY(_svi))->xmg_u.xmg_magic); \
+ }))
+# define SvSTASH(sv) \
+ (*({ SV *const _svi = (SV *) sv; \
+ assert(SvTYPE(_svi) >= SVt_PVMG); \
+ &(((XPVMG*) SvANY(_svi))->xmg_stash); \
+ }))
+# else
+# define SvPVX(sv) ((sv)->sv_u.svu_pv)
+# define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur
+# define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv
+# define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv
+# define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv
+# define SvMAGIC(sv) ((XPVMG*) SvANY(sv))->xmg_u.xmg_magic
+# define SvSTASH(sv) ((XPVMG*) SvANY(sv))->xmg_stash
+# endif