-#define CvDEPTH(sv) ((XPVCV*)SvANY(sv))->xcv_depth
-#define CvPADLIST(sv) ((XPVCV*)SvANY(sv))->xcv_padlist
-#define CvOUTSIDE(sv) ((XPVCV*)SvANY(sv))->xcv_outside
-#define CvFLAGS(sv) ((XPVCV*)SvANY(sv))->xcv_flags
-#define CvOUTSIDE_SEQ(sv) ((XPVCV*)SvANY(sv))->xcv_outside_seq
+#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+# define CvDEPTH(sv) (*({const CV *const _cvdepth = (const CV *)sv; \
+ assert(SvTYPE(_cvdepth) == SVt_PVCV); \
+ &((XPVCV*)SvANY(_cvdepth))->xcv_depth; \
+ }))
+#else
+# define CvDEPTH(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_depth
+#endif
+#define CvPADLIST(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_padlist
+#define CvOUTSIDE(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_outside
+#define CvFLAGS(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_flags
+#define CvOUTSIDE_SEQ(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_outside_seq
+
+/* These two are sometimes called on non-CVs */
+#define CvPROTO(sv) \
+ ( \
+ SvPOK(sv) \
+ ? SvTYPE(sv) == SVt_PVCV && CvAUTOLOAD(sv) \
+ ? SvEND(sv)+1 : SvPVX_const(sv) \
+ : NULL \
+ )
+#define CvPROTOLEN(sv) \
+ ( \
+ SvPOK(sv) \
+ ? SvTYPE(sv) == SVt_PVCV && CvAUTOLOAD(sv) \
+ ? SvLEN(sv)-SvCUR(sv)-2 \
+ : SvCUR(sv) \
+ : 0 \
+ )