bug-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: evaluating "&&" order with div by zero in subsequent part.


From: Ed Morton
Subject: Re: evaluating "&&" order with div by zero in subsequent part.
Date: Sun, 14 Aug 2022 10:23:02 -0500
User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.1.0

On 8/14/2022 10:07 AM, arnold@skeeve.com wrote:
Hi Ed.

Ed Morton<mortoneccc@comcast.net>  wrote:

There's some inconsistency in the following division by zero treatment
(gawk 5.1.1 on cygwin):

...

but then if we swap denominator $0 which has value 0 with literal 0:

     $ echo 0 | awk '{ print (0 && (4/0)) }'
     awk: cmd. line:1: error: division by zero attempted

and if we then put parens around the numerator 4 and leave the
denominator 0:

     $ echo 0 | awk '{ print (0 && ((4)/0)) }'
     0
OK. This has do with gawk's "optimization" which involves VERY simple
constant folding.  Gawk turns something like `x = 3 * 15' into `x = 15'
(except when pretty printing).

In the first case, both sides of the `/' are constant, and it checks
that the denominator of `/' is zero and produces an error.

In the second case, `(4)' is an expression, not a constant, and it
simply generated code to do the division, without checking for zero.

The patch below fixes that; now no matter what the numerator, if the
denominator of `/' or `%' is zero, it will produce an error.

As to the fact that `0 && ...' guards the division, gawk isn't that
smart.  There are lots of optimization techniques known in the compiler
world that gawk doesn't implement, since they're complicated and not
worth the trouble, such as dead code elimination:

        if (0)
                stuff1
        else
                stuff2

Optmizing compilers would only generate code for `stuff2' in such
a case.

This fix will make it's way into Git shortly.

Thanks,

Arnold
-----------------------------------------------------
diff --git a/awkgram.y b/awkgram.y
index 36cac704..e2a3d21b 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -5533,9 +5533,21 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION 
*op)
                                op->opcode = Op_times_i;
                                break;
                        case Op_quotient:
+                               if (ip2->memory->numbr == 0.0) {
+                                       /* don't fatalize, allow parsing rest 
of the input */
+                                       error_ln(op->source_line, _("division by 
zero attempted"));
+                                       goto regular;
+                               }
+
                                op->opcode = Op_quotient_i;
                                break;
                        case Op_mod:
+                               if (ip2->memory->numbr == 0.0) {
+                                       /* don't fatalize, allow parsing rest 
of the input */
+                                       error_ln(op->source_line, _("division by 
zero attempted in `%%'"));
+                                       goto regular;
+                               }
+
                                op->opcode = Op_mod_i;
                                break;
                        case Op_plus:


Arnold - sounds good, thanks!

    Ed.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]