[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]
[PATCH] Not silently casting away constness in SV macros
Change #34600 fixed an erroneously consted SV*. I think it's not
the first time this happened.
The reason why such errors remain unnoticed for a long time is
that a lot of macros (like SvREFCNT_dec()) simply cast away the
constness of the argument, thus inhibiting any compiler warnings.
I've been thinking about a way to do the cast, but nonetheless
get a warning, and the attached patch is what I came up with.
It defines a MUTABLESV() macro like this:
#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
# define MUTABLESV(sv) ({ void *_svm = sv; (SV*) _svm; })
#else
# define MUTABLESV(sv) ((SV*) (sv))
#endif
So, this macro can be used as a replacement for the (SV*) cast.
When using gcc, before actually doing the cast, the argument
is assigned to a void*, which is always possible without an
explicit cast (even in C++). But: if the sv argument is a const
pointer, the compiler will issue a warning for this assignment.
I've tested that it catches the problem fixed with #34600, but
I haven't found any other issues.
I wonder if something like this has been tried before, and if
not, whether this would be useful to apply?
Marcus
--
Machines have less problems. I'd like to be a machine.
-- Andy Warhol
--- sv.h.orig 2008-10-26 02:47:39.000000000 +0100
+++ sv.h 2008-10-26 03:10:45.000000000 +0100
@@ -218,6 +218,12 @@
=cut
*/
+#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+# define MUTABLESV(sv) ({ void *_svm = sv; (SV*) _svm; })
+#else
+# define MUTABLESV(sv) ((SV*) (sv))
+#endif
+
#define SvANY(sv) (sv)->sv_any
#define SvFLAGS(sv) (sv)->sv_flags
#define SvREFCNT(sv) (sv)->sv_refcnt
@@ -225,7 +231,7 @@
#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
# define SvREFCNT_inc(sv) \
({ \
- SV * const _sv = (SV*)(sv); \
+ SV * const _sv = MUTABLESV(sv); \
if (_sv) \
(SvREFCNT(_sv))++; \
_sv; \
@@ -238,13 +244,13 @@
})
# define SvREFCNT_inc_NN(sv) \
({ \
- SV * const _sv = (SV*)(sv); \
+ SV * const _sv = MUTABLESV(sv); \
SvREFCNT(_sv)++; \
_sv; \
})
# define SvREFCNT_inc_void(sv) \
({ \
- SV * const _sv = (SV*)(sv); \
+ SV * const _sv = MUTABLESV(sv); \
if (_sv) \
(void)(SvREFCNT(_sv)++); \
})
@@ -268,7 +274,7 @@
#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
# define SvREFCNT_dec(sv) \
({ \
- SV * const _sv = (SV*)(sv); \
+ SV * const _sv = MUTABLESV(sv); \
if (_sv) { \
if (SvREFCNT(_sv)) { \
if (--(SvREFCNT(_sv)) == 0) \
@@ -965,21 +971,21 @@
#define SvEVALED_off(sv) (SvFLAGS(sv) &= ~SVrepl_EVAL)
#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
-# define SvVALID(sv) ({ SV *const _svvalid = (SV *) (sv); \
+# define SvVALID(sv) ({ const SV *const _svvalid = (const SV *) (sv); \
if (SvFLAGS(_svvalid) & SVpbm_VALID) \
assert(!isGV_with_GP(_svvalid)); \
(SvFLAGS(_svvalid) & SVpbm_VALID); \
})
-# define SvVALID_on(sv) ({ SV *const _svvalid = (SV *) (sv); \
+# define SvVALID_on(sv) ({ SV *const _svvalid = MUTABLESV(sv); \
assert(!isGV_with_GP(_svvalid)); \
(SvFLAGS(_svvalid) |= SVpbm_VALID); \
})
-# define SvVALID_off(sv) ({ SV *const _svvalid = (SV *) (sv); \
+# define SvVALID_off(sv) ({ SV *const _svvalid = MUTABLESV(sv); \
assert(!isGV_with_GP(_svvalid)); \
(SvFLAGS(_svvalid) &= ~SVpbm_VALID); \
})
-# define SvTAIL(sv) ({ SV *const _svtail = (SV *) (sv); \
+# define SvTAIL(sv) ({ const SV *const _svtail = (const SV *) (sv); \
assert(SvTYPE(_svtail) != SVt_PVAV); \
assert(SvTYPE(_svtail) != SVt_PVHV); \
(SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID)) \
@@ -1008,17 +1014,17 @@
#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
# define SvPAD_TYPED_on(sv) ({ \
- SV *const _svpad = (SV *) (sv); \
+ SV *const _svpad = MUTABLESV(sv); \
assert(SvTYPE(_svpad) == SVt_PVMG); \
(SvFLAGS(_svpad) |= SVpad_NAME|SVpad_TYPED); \
})
#define SvPAD_OUR_on(sv) ({ \
- SV *const _svpad = (SV *) (sv); \
+ SV *const _svpad = MUTABLESV(sv); \
assert(SvTYPE(_svpad) == SVt_PVMG); \
(SvFLAGS(_svpad) |= SVpad_NAME|SVpad_OUR); \
})
#define SvPAD_STATE_on(sv) ({ \
- SV *const _svpad = (SV *) (sv); \
+ SV *const _svpad = MUTABLESV(sv); \
assert(SvTYPE(_svpad) == SVt_PVNV || SvTYPE(_svpad) == SVt_PVMG); \
(SvFLAGS(_svpad) |= SVpad_NAME|SVpad_STATE); \
})
signature.asc
- Follow-Ups from:
-
Nicholas Clark <nick@ccl4.org>
[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]