implemented -Wdiv-by-zero
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 11 Sep 2008 23:58:37 +0000 (23:58 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 11 Sep 2008 23:58:37 +0000 (23:58 +0000)
[r21866]

parser.c
parsetest/should_warn/div_by_zero.c [new file with mode: 0644]
warning.c
warning.h

index 7f93106..ff2db11 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -7302,6 +7302,18 @@ static void semantic_binexpr_arithmetic(binary_expression_t *expression)
        expression->base.type = arithmetic_type;
 }
 
+/**
+ * Check the semantic restrictions for a div/mod expression.
+ */
+static void semantic_divmod_arithmetic(binary_expression_t *expression) {
+       semantic_binexpr_arithmetic(expression);
+       if (warning.div_by_zero && is_type_integer(expression->base.type)) {
+               if (is_constant_expression(expression->right) &&
+                   fold_constant(expression->right) == 0)
+                       warningf(&expression->base.source_position, "division by zero");
+       }
+}
+
 static void semantic_shift_op(binary_expression_t *expression)
 {
        expression_t *const left            = expression->left;
@@ -7573,6 +7585,16 @@ static void semantic_arithmetic_assign(binary_expression_t *expression)
        expression->base.type   = type_left;
 }
 
+static void semantic_divmod_assign(binary_expression_t *expression)
+{
+       semantic_arithmetic_assign(expression);
+       if (warning.div_by_zero && is_type_integer(expression->base.type)) {
+               if (is_constant_expression(expression->right) &&
+                   fold_constant(expression->right) == 0)
+                       warningf(&expression->base.source_position, "division by zero");
+       }
+}
+
 static void semantic_arithmetic_addsubb_assign(binary_expression_t *expression)
 {
        expression_t *const left            = expression->left;
@@ -7812,8 +7834,8 @@ static expression_t *parse_##binexpression_type(unsigned precedence,      \
 
 CREATE_BINEXPR_PARSER(',', EXPR_BINARY_COMMA,    semantic_comma, 1)
 CREATE_BINEXPR_PARSER('*', EXPR_BINARY_MUL,      semantic_binexpr_arithmetic, 1)
-CREATE_BINEXPR_PARSER('/', EXPR_BINARY_DIV,      semantic_binexpr_arithmetic, 1)
-CREATE_BINEXPR_PARSER('%', EXPR_BINARY_MOD,      semantic_binexpr_arithmetic, 1)
+CREATE_BINEXPR_PARSER('/', EXPR_BINARY_DIV,      semantic_divmod_arithmetic, 1)
+CREATE_BINEXPR_PARSER('%', EXPR_BINARY_MOD,      semantic_divmod_arithmetic, 1)
 CREATE_BINEXPR_PARSER('+', EXPR_BINARY_ADD,      semantic_add, 1)
 CREATE_BINEXPR_PARSER('-', EXPR_BINARY_SUB,      semantic_sub, 1)
 CREATE_BINEXPR_PARSER('<', EXPR_BINARY_LESS,     semantic_comparison, 1)
@@ -7850,9 +7872,9 @@ CREATE_BINEXPR_PARSER(T_MINUSEQUAL, EXPR_BINARY_SUB_ASSIGN,
 CREATE_BINEXPR_PARSER(T_ASTERISKEQUAL, EXPR_BINARY_MUL_ASSIGN,
                       semantic_arithmetic_assign, 0)
 CREATE_BINEXPR_PARSER(T_SLASHEQUAL, EXPR_BINARY_DIV_ASSIGN,
-                      semantic_arithmetic_assign, 0)
+                      semantic_divmod_assign, 0)
 CREATE_BINEXPR_PARSER(T_PERCENTEQUAL, EXPR_BINARY_MOD_ASSIGN,
-                      semantic_arithmetic_assign, 0)
+                      semantic_divmod_assign, 0)
 CREATE_BINEXPR_PARSER(T_LESSLESSEQUAL, EXPR_BINARY_SHIFTLEFT_ASSIGN,
                       semantic_arithmetic_assign, 0)
 CREATE_BINEXPR_PARSER(T_GREATERGREATEREQUAL, EXPR_BINARY_SHIFTRIGHT_ASSIGN,
diff --git a/parsetest/should_warn/div_by_zero.c b/parsetest/should_warn/div_by_zero.c
new file mode 100644 (file)
index 0000000..1196d29
--- /dev/null
@@ -0,0 +1,5 @@
+float NaN = 0.0/0.0;
+
+int main(int argc, char *argv[]) {
+       return argc / 0;
+}
index bb00d94..623ab2c 100644 (file)
--- a/warning.c
+++ b/warning.c
@@ -26,6 +26,7 @@ warning_t warning = {
        .char_subscripts               = true,
        .declaration_after_statement   = false,
        .deprecated_declarations       = true,
+       .div_by_zero                   = true,
        .empty_statement               = false,
        .fatal_errors                  = false,
        .float_equal                   = false,
@@ -104,6 +105,7 @@ void set_warning_opt(const char *const opt)
        OPT("char-subscripts",               char_subscripts);
        OPT("declaration-after-statement",   declaration_after_statement);
        OPT("deprecated-declarations",       deprecated_declarations);
+       OPT("div_by_zero",                   div_by_zero);
        OPT("empty-statement",               empty_statement);
        OPT("error",                         s_are_errors);
        OPTX("extra") {
index cb3e2cf..e15b776 100644 (file)
--- a/warning.h
+++ b/warning.h
@@ -38,9 +38,7 @@ typedef struct warning_t {
 #endif
        bool declaration_after_statement:1;   /**< Warn when a declaration is found after a statement in a block */
        bool deprecated_declarations:1;       /* TODO implement for types */ /**< Warn about uses of functions, variables and types marked as deprecated by using the 'deprecated' attribute */
-#if 0 // TODO
        bool div_by_zero:1;                   /**< Warn about compile-time integer division by zero */
-#endif
        bool empty_statement:1;               /**< Warn about empty statements, i.e. lone ';'  */
 #if 0 // TODO
        bool endif_labels:1;                  /**< Warn whenever an '#else' or an '#endif' are followed by text */