This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH RFA: Better warnings for CONST_DOUBLE
- From: Richard Henderson <rth at redhat dot com>
- To: Geoffrey Keating <geoffk at apple dot com>, Ian Lance Taylor <ian at airs dot com>, gcc-patches at gcc dot gnu dot org
- Date: Mon, 1 Aug 2005 14:18:30 -0700
- Subject: Re: PATCH RFA: Better warnings for CONST_DOUBLE
- References: <m3vf2vaj16.fsf@gossamer.airs.com> <20050728003925.GA13702@redhat.com> <m3iryu98ma.fsf@gossamer.airs.com> <20050729055533.GA17775@redhat.com> <BB51417A-F221-4D01-BB1E-20D1483D8AC3@apple.com> <20050729204547.GA20140@redhat.com>
Given that this finds real bugs, and the fact that it is disabled
by default and so will not affect anyone that does not proactively
turn on rtl checking, I've committed the following.
Tested with --enable-checking=rtl on ia64, alpha, i686 and x86_64 linux.
r~
* Makefile.in (RTL_BASE_H): Add real.h.
* real.h (REAL_VALUE_FROM_CONST_DOUBLE): Use structure copy
instead of memcpy.
* emit-rtl.c (const_double_from_real_value): Likewise; use rtx.u.rv
directly.
* rtl.c (rtl_check_failed_code_mode): New.
* rtl.h (struct rtx_def): Add u.rv.
(XCMWINT, XCNMPRV): New.
(CONST_DOUBLE_LOW, CONST_DOUBLE_HIGH): Use XCMWINT.
(CONST_DOUBLE_REAL_VALUE): Use XCNMPRV; constify.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1532
diff -u -p -d -r1.1532 Makefile.in
--- Makefile.in 1 Aug 2005 07:41:48 -0000 1.1532
+++ Makefile.in 1 Aug 2005 21:09:02 -0000
@@ -716,7 +716,7 @@ HOSTHOOKS_DEF_H = hosthooks-def.h $(HOOK
LANGHOOKS_DEF_H = langhooks-def.h $(HOOKS_H)
TARGET_DEF_H = target-def.h $(HOOKS_H)
RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H) reg-notes.def insn-notes.def \
- input.h statistics.h
+ input.h real.h statistics.h
RTL_H = $(RTL_BASE_H) genrtl.h
PARAMS_H = params.h params.def
TREE_H = tree.h tree.def $(MACHMODE_H) tree-check.h builtins.def \
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v
retrieving revision 1.445
diff -u -p -d -r1.445 emit-rtl.c
--- emit-rtl.c 26 Jul 2005 14:58:43 -0000 1.445
+++ emit-rtl.c 1 Aug 2005 21:09:05 -0000
@@ -426,7 +426,7 @@ const_double_from_real_value (REAL_VALUE
rtx real = rtx_alloc (CONST_DOUBLE);
PUT_MODE (real, mode);
- memcpy (&CONST_DOUBLE_LOW (real), &value, sizeof (REAL_VALUE_TYPE));
+ real->u.rv = value;
return lookup_const_double (real);
}
Index: real.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/real.h,v
retrieving revision 1.84
diff -u -p -d -r1.84 real.h
--- real.h 25 Jun 2005 02:00:50 -0000 1.84
+++ real.h 1 Aug 2005 21:09:06 -0000
@@ -364,7 +364,7 @@ REAL_VALUE_TYPE real_value_from_int_cst
/* Given a CONST_DOUBLE in FROM, store into TO the value it represents. */
#define REAL_VALUE_FROM_CONST_DOUBLE(to, from) \
- memcpy (&(to), &CONST_DOUBLE_LOW ((from)), sizeof (REAL_VALUE_TYPE))
+ ((to) = *CONST_DOUBLE_REAL_VALUE (from))
/* Return a CONST_DOUBLE with value R and mode M. */
#define CONST_DOUBLE_FROM_REAL_VALUE(r, m) \
Index: rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.c,v
retrieving revision 1.155
diff -u -p -d -r1.155 rtl.c
--- rtl.c 25 Jun 2005 02:00:58 -0000 1.155
+++ rtl.c 1 Aug 2005 21:09:06 -0000
@@ -515,6 +515,21 @@ rtl_check_failed_code2 (rtx r, enum rtx_
func, trim_filename (file), line);
}
+void
+rtl_check_failed_code_mode (rtx r, enum rtx_code code, enum machine_mode mode,
+ bool not_mode, const char *file, int line,
+ const char *func)
+{
+ internal_error ((not_mode
+ ? ("RTL check: expected code '%s' and not mode '%s', "
+ "have code '%s' and mode '%s' in %s, at %s:%d")
+ : ("RTL check: expected code '%s' and mode '%s', "
+ "have code '%s' and mode '%s' in %s, at %s:%d")),
+ GET_RTX_NAME (code), GET_MODE_NAME (mode),
+ GET_RTX_NAME (GET_CODE (r)), GET_MODE_NAME (GET_MODE (r)),
+ func, trim_filename (file), line);
+}
+
/* XXX Maybe print the vector? */
void
rtvec_check_failed_bounds (rtvec r, int n, const char *file, int line,
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.556
diff -u -p -d -r1.556 rtl.h
--- rtl.h 5 Jul 2005 16:20:14 -0000 1.556
+++ rtl.h 1 Aug 2005 21:09:06 -0000
@@ -25,6 +25,7 @@ Software Foundation, 51 Franklin Street,
#include "statistics.h"
#include "machmode.h"
#include "input.h"
+#include "real.h"
#undef FFS /* Some systems predefine this symbol; don't let it interfere. */
#undef FLOAT /* Likewise. */
@@ -249,6 +250,7 @@ struct rtx_def GTY((chain_next ("RTX_NEX
union u {
rtunion fld[1];
HOST_WIDE_INT hwint[1];
+ struct real_value rv;
} GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u;
};
@@ -454,6 +456,20 @@ struct rtvec_def GTY(()) {
__FUNCTION__); \
&_rtx->u.hwint[N]; }))
+#define XCMWINT(RTX, N, C, M) __extension__ \
+(*({ rtx const _rtx = (RTX); \
+ if (GET_CODE (_rtx) != (C) || GET_MODE (_rtx) != (M)) \
+ rtl_check_failed_code_mode (_rtx, (C), (M), false, __FILE__, \
+ __LINE__, __FUNCTION__); \
+ &_rtx->u.hwint[N]; }))
+
+#define XCNMPRV(RTX, C, M) __extension__ \
+({ rtx const _rtx = (RTX); \
+ if (GET_CODE (_rtx) != (C) || GET_MODE (_rtx) == (M)) \
+ rtl_check_failed_code_mode (_rtx, (C), (M), true, __FILE__, \
+ __LINE__, __FUNCTION__); \
+ &_rtx->u.rv; })
+
extern void rtl_check_failed_bounds (rtx, int, const char *, int,
const char *)
ATTRIBUTE_NORETURN;
@@ -469,6 +485,9 @@ extern void rtl_check_failed_code1 (rtx,
extern void rtl_check_failed_code2 (rtx, enum rtx_code, enum rtx_code,
const char *, int, const char *)
ATTRIBUTE_NORETURN;
+extern void rtl_check_failed_code_mode (rtx, enum rtx_code, enum machine_mode,
+ bool, const char *, int, const char *)
+ ATTRIBUTE_NORETURN;
extern void rtvec_check_failed_bounds (rtvec, int, const char *, int,
const char *)
ATTRIBUTE_NORETURN;
@@ -482,6 +501,9 @@ extern void rtvec_check_failed_bounds (r
#define RTVEC_ELT(RTVEC, I) ((RTVEC)->elem[I])
#define XWINT(RTX, N) ((RTX)->u.hwint[N])
#define XCWINT(RTX, N, C) ((RTX)->u.hwint[N])
+#define XCMWINT(RTX, N, C, M) ((RTX)->u.hwint[N])
+#define XCNMWINT(RTX, N, C, M) ((RTX)->u.hwint[N])
+#define XCNMPRV(RTX, C, M) (&(RTX)->u.rv)
#endif
@@ -916,9 +938,10 @@ enum label_kind
low-order word and ..._HIGH the high-order.
For a float, there is a REAL_VALUE_TYPE structure, and
CONST_DOUBLE_REAL_VALUE(r) is a pointer to it. */
-#define CONST_DOUBLE_LOW(r) XCWINT (r, 0, CONST_DOUBLE)
-#define CONST_DOUBLE_HIGH(r) XCWINT (r, 1, CONST_DOUBLE)
-#define CONST_DOUBLE_REAL_VALUE(r) ((struct real_value *)&CONST_DOUBLE_LOW(r))
+#define CONST_DOUBLE_LOW(r) XCMWINT (r, 0, CONST_DOUBLE, VOIDmode)
+#define CONST_DOUBLE_HIGH(r) XCMWINT (r, 1, CONST_DOUBLE, VOIDmode)
+#define CONST_DOUBLE_REAL_VALUE(r) \
+ ((const struct real_value *) XCNMPRV (r, CONST_DOUBLE, VOIDmode))
/* For a CONST_VECTOR, return element #n. */
#define CONST_VECTOR_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR)