From: Neil Booth Date: Tue, 23 Oct 2001 18:14:31 +0000 (+0000) Subject: c-common.c (warn_div_by_zero): New. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6c36d76bf6521dd1cc09b8d7e379a02d138ffd53;p=gcc.git c-common.c (warn_div_by_zero): New. * c-common.c (warn_div_by_zero): New. * c-common.h (warn_div_by_zero): New. * c-decl.c (c_decode_option): Take it on the command line. * c-typeck.c (build_binary_op): Warn about division by zero. * doc/invoke.texi: Document the new command line option, fix documentation of -Wmultichar. * testsuite/gcc.dg/divbyzero.c: New tests. * testsuite/gcc.dg/noncompile/20010524-1.c: Update. From-SVN: r46439 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 39b5d61e909..a3b17b2c4e0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2001-10-22 Neil Booth + + * c-common.c (warn_div_by_zero): New. + * c-common.h (warn_div_by_zero): New. + * c-decl.c (c_decode_option): Take it on the command line. + * c-typeck.c (build_binary_op): Warn about division by zero. + * doc/invoke.texi: Document the new command line option, fix + documentation of -Wmultichar. + * testsuite/gcc.dg/divbyzero.c: New tests. + * testsuite/gcc.dg/noncompile/20010524-1.c: Update. + Tue Oct 23 15:30:23 CEST 2001 Jan Hubicka * i386.c (ix86_expand_int_movcc): Cleanup; use expand_simple_*op. diff --git a/gcc/c-common.c b/gcc/c-common.c index 6a4e1af48fc..bc81a1a3a01 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -194,6 +194,9 @@ int flag_short_wchar; int warn_sequence_point; +/* Nonzero means to warn about compile-time division by zero. */ +int warn_div_by_zero = 1; + /* The elements of `ridpointers' are identifier nodes for the reserved type names and storage classes. It is indexed by a RID_... value. */ tree *ridpointers; diff --git a/gcc/c-common.h b/gcc/c-common.h index 89a4ae7252f..0d45693531f 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -401,6 +401,9 @@ extern int warn_missing_format_attribute; extern int warn_pointer_arith; +/* Nonzero means to warn about compile-time division by zero. */ +extern int warn_div_by_zero; + /* Nonzero means do some things the same way PCC does. */ extern int flag_traditional; diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 45b923aae63..ad724f5de48 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -750,6 +750,10 @@ c_decode_option (argc, argv) warn_multichar = 1; else if (!strcmp (p, "-Wno-multichar")) warn_multichar = 0; + else if (!strcmp (p, "-Wdiv-by-zero")) + warn_div_by_zero = 1; + else if (!strcmp (p, "-Wno-div-by-zero")) + warn_div_by_zero = 0; else if (!strcmp (p, "-Wunknown-pragmas")) /* Set to greater than 1, so that even unknown pragmas in system headers will be warned about. */ diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index d2a7a8ccd9e..5dac4774f57 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -1973,6 +1973,11 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) case FLOOR_DIV_EXPR: case ROUND_DIV_EXPR: case EXACT_DIV_EXPR: + /* Floating point division by zero is a legitimate way to obtain + infinities and NaNs. */ + if (warn_div_by_zero && skip_evaluation == 0 && integer_zerop (op1)) + warning ("division by zero"); + if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) && (code1 == INTEGER_TYPE || code1 == REAL_TYPE @@ -2026,6 +2031,9 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) case TRUNC_MOD_EXPR: case FLOOR_MOD_EXPR: + if (warn_div_by_zero && skip_evaluation == 0 && integer_zerop (op1)) + warning ("division by zero"); + if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { /* Although it would be tempting to shorten always here, that loses diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 1054c2bf358..75b183cefa6 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -208,7 +208,7 @@ in the following sections. -fsyntax-only -pedantic -pedantic-errors @gol -w -W -Wall -Waggregate-return @gol -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment @gol --Wconversion -Wdisabled-optimization -Werror @gol +-Wconversion -Wdisabled-optimization -Wdiv-by-zero -Werror @gol -Wfloat-equal -Wformat -Wformat=2 @gol -Wformat-nonliteral -Wformat-security @gol -Wimplicit -Wimplicit-int @gol @@ -1868,12 +1868,6 @@ int a[2][2] = @{ 0, 1, 2, 3 @}; int b[2][2] = @{ @{ 0, 1 @}, @{ 2, 3 @} @}; @end smallexample -@item -Wmultichar -@opindex Wmultichar -Warn if a multicharacter constant (@samp{'FOOF'}) is used. Usually they -indicate a typo in the user's code, as they have implementation-defined -values, and should not be used in portable code. - @item -Wparentheses @opindex Wparentheses Warn if parentheses are omitted in certain contexts, such @@ -2129,6 +2123,22 @@ warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros. +@item -Wdiv-by-zero +@opindex Wno-div-by-zero +@opindex Wdiv-by-zero +Warn about compile-time integer division by zero. This is default. To +inhibit the warning messages, use @option{-Wno-div-by-zero}. Floating +point division by zero is not warned about, as it can be a legitimate +way of obtaining infinities and NaNs. + +@item -Wmultichar +@opindex Wno-multichar +@opindex Wmultichar +Warn if a multicharacter constant (@samp{'FOOF'}) is used. This is +default. To inhibit the warning messages, use @option{-Wno-multichar}. +Usually they indicate a typo in the user's code, as they have +implementation-defined values, and should not be used in portable code. + @item -Wsystem-headers @opindex Wsystem-headers @cindex warnings from system headers diff --git a/gcc/testsuite/gcc.dg/divbyzero.c b/gcc/testsuite/gcc.dg/divbyzero.c new file mode 100644 index 00000000000..607aa12d568 --- /dev/null +++ b/gcc/testsuite/gcc.dg/divbyzero.c @@ -0,0 +1,21 @@ +/* Copyright (C) 2001 Free Software Foundation, Inc. */ + +/* { dg-do compile } */ + +/* Source: Neil Booth, Oct 22 2001. PR 150 - warn about division by + zero. */ + +#define ZERO (4 - 6 + 2) + +int main (int argc, char *argv[]) +{ + int w = argc % ZERO; /* { dg-warning "division by zero" } */ + int x = argc / 0; /* { dg-warning "division by zero" } */ + int y = argc / ZERO; /* { dg-warning "division by zero" } */ + + double z = 0.0 / 0.0 ; /* { dg-bogus "division by zero" } */ + w = (ZERO ? y / ZERO : x); /* { dg-bogus "division by zero" } */ + x = (ZERO ? argc % ZERO: x); /* { dg-bogus "division by zero" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/noncompile/20010524-1.c b/gcc/testsuite/gcc.dg/noncompile/20010524-1.c index 754a38c147f..95c5db15d35 100644 --- a/gcc/testsuite/gcc.dg/noncompile/20010524-1.c +++ b/gcc/testsuite/gcc.dg/noncompile/20010524-1.c @@ -1,2 +1,2 @@ int i = 7 / 0; /* { dg-error "not constant" } */ - + /* { dg-warning "division by zero" "div by zero" { target *-*-* } 1 } */