This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH for division by zero in template arguments
- To: Derrick Bass <derrick at tapir dot Caltech dot EDU>
- Subject: PATCH for division by zero in template arguments
- From: Mark Mitchell <mark at markmitchell dot com>
- Date: Tue, 16 Jun 1998 14:46:13 -0700
- Cc: Jason Merrill <jason at cygnus dot com>, egcs-patches at cygnus dot com
- Reply-to: mark at markmitchell dot com
Derrick --
Here's a fix for your problem. Jason, OK?
--
Mark Mitchell mark@markmitchell.com
Mark Mitchell Consulting http://www.markmitchell.com
1998-06-16 Mark Mitchell <mark@markmitchell.com>
* errfn.c (cp_thing): Handle the `%%' formatting sequence.
* typeck.c (build_binary_op_nodefault): Make dividing by a
constant zero an error, rather than a warning.
Index: testsuite/g++.old-deja/g++.pt/crash10.C
===================================================================
RCS file: crash10.C
diff -N crash10.C
*** /dev/null Mon Dec 31 20:00:00 1979
--- crash10.C Tue Jun 16 14:25:33 1998
***************
*** 0 ****
--- 1,11 ----
+ // Build don't link:
+
+ template<int M, int N>
+ class GCD {
+ public:
+ enum { val = (N == 0) ? M : GCD<N, M % N>::val };
+ };
+
+ main() {
+ GCD< 1, 0 >::val; // ERROR - division
+ }
Index: cp/typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.82
diff -c -p -r1.82 typeck.c
*** typeck.c 1998/06/13 23:43:33 1.82
--- typeck.c 1998/06/16 21:26:00
*************** build_binary_op_nodefault (code, orig_op
*** 3302,3312 ****
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|| code1 == COMPLEX_TYPE))
{
! if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1))
! cp_warning ("division by zero in `%E / 0'", op0);
! else if (TREE_CODE (op1) == REAL_CST && real_zerop (op1))
! cp_warning ("division by zero in `%E / 0.'", op0);
!
if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
resultcode = RDIV_EXPR;
else
--- 3302,3314 ----
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|| code1 == COMPLEX_TYPE))
{
! if ((TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1))
! || (TREE_CODE (op1) == REAL_CST && real_zerop (op1)))
! {
! cp_error ("division by zero in `%E / 0'", op0);
! return error_mark_node;
! }
!
if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
resultcode = RDIV_EXPR;
else
*************** build_binary_op_nodefault (code, orig_op
*** 3359,3368 ****
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
! if (code1 == INTEGER_TYPE && integer_zerop (op1))
! cp_warning ("division by zero in `%E % 0'", op0);
! else if (code1 == REAL_TYPE && real_zerop (op1))
! cp_warning ("division by zero in `%E % 0.'", op0);
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
--- 3361,3372 ----
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
! if ((code1 == INTEGER_TYPE && integer_zerop (op1))
! || (code1 == REAL_TYPE && real_zerop (op1)))
! {
! cp_error ("division by zero in `%E / 0'", op0);
! return error_mark_node;
! }
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
Index: cp/errfn.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/errfn.c,v
retrieving revision 1.12
diff -c -p -r1.12 errfn.c
*** errfn.c 1998/05/22 23:13:28 1.12
--- errfn.c 1998/06/16 21:26:19
*************** extern int cp_line_of PROTO((tree));
*** 50,56 ****
#define STRDUP(f) (ap = (char *) alloca (strlen (f) +1), strcpy (ap, (f)), ap)
! /* This function supports only `%s', `%d', and the C++ print codes. */
#ifdef __STDC__
static void
--- 50,57 ----
#define STRDUP(f) (ap = (char *) alloca (strlen (f) +1), strcpy (ap, (f)), ap)
! /* This function supports only `%s', `%d', `%%', and the C++ print
! codes. */
#ifdef __STDC__
static void
*************** cp_thing (errfn, atarg1, format, ap)
*** 151,156 ****
--- 152,172 ----
}
strcpy (buf + offset, p);
offset += plen;
+ }
+ else if (*f == '%')
+ {
+ /* A `%%' has occurred in the input string. Since the
+ string we produce here will be passed to vprintf we must
+ preserve both `%' characters. */
+
+ len += 2;
+ if (len > buflen)
+ {
+ buflen = len;
+ buf = xrealloc (buf, len);
+ }
+ strcpy (buf + offset, "%%");
+ offset += 2;
}
else
{