expressions: Fix coercion of numbers to booleans at top level.
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 25 Sep 2012 22:14:50 +0000 (15:14 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 25 Sep 2012 22:14:50 +0000 (15:14 -0700)
The check for the expected type in type_check() used the wrong
constant (a node type instead of an expression type) and so the
"if" test was never true.  Also, OP_NUM_TO_BOOLEAN is binary, not
unary, so fixing just the test caused an assertion failure.

This commit fixes both problems and adds a test.

Found by GCC 4.7 report of a type mismatch.

src/language/expressions/operations.def
src/language/expressions/parse.c
tests/language/expressions/parse.at

index 207551b7eaf9c16c39bc0cec1c48173b396e3c7f..37af54a9118abf8755fd0205cdaebdbe20021f46 100644 (file)
@@ -1,7 +1,7 @@
 // -*- c -*-
 //
 // PSPP - a program for statistical analysis.
-// Copyright (C) 2005, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2005, 2006, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 // 
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -654,14 +654,17 @@ boolean operator NUM_TO_BOOLEAN (x, string op_name)
 {
   if (x == 0. || x == 1. || x == SYSMIS)
     return x;
+
+  if (!ss_is_empty (op_name))
+    msg (SE, _("An operand of the %.*s operator was found to have a value "
+               "other than 0 (false), 1 (true), or the system-missing "
+               "value.  The result was forced to 0."),
+         (int) op_name.length, op_name.string);
   else
-    {
-      msg (SE, _("An operand of the %.*s operator was found to have a value "
-                 "other than 0 (false), 1 (true), or the system-missing "
-                 "value.  The result was forced to 0."),
-           (int) op_name.length, op_name.string);
-      return 0.;
-    }
+    msg (SE, _("A logical expression was found to have a value other than 0 "
+               "(false), 1 (true), or the system-missing value.  The result "
+               "was forced to 0."));
+  return 0.;
 }
 
 operator BOOLEAN_TO_NUM (boolean x) = x;
index 3124c100a19e4c8922916fcda501ec2c0db058b1..24380e28192f3c22274522db12db8f5d401ea32a 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2010, 2011, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -262,8 +262,9 @@ type_check (struct expression *e,
                atom_type_name (actual_type));
          return false;
        }
-      if (actual_type == OP_number && expected_type == OP_boolean)
-       *n = expr_allocate_unary (e, OP_NUM_TO_BOOLEAN, *n);
+      if (actual_type == OP_number && expected_type == EXPR_BOOLEAN)
+        *n = expr_allocate_binary (e, OP_NUM_TO_BOOLEAN, *n,
+                                   expr_allocate_string (e, ss_empty ()));
       break;
 
     case EXPR_STRING:
index df8192b28ed74d0d7978231b54052c34ddfe78b9..31791a41daa62072ab21c0c1a5736d537a8c919f 100644 (file)
@@ -21,3 +21,20 @@ parse.sps:10: error: IF: Unknown identifier y.
 parse.sps:11: error: Stopping syntax file processing here to avoid a cascade of dependent command failures.
 ])
 AT_CLEANUP
+
+AT_SETUP([parse expression with invalid logical expression])
+AT_DATA([parse.sps], [dnl
+INPUT PROGRAM.
+LOOP c=1 to 10.
+COMPUTE var1=NORMAL(100).
+END CASE.
+END LOOP.
+END FILE.
+END INPUT PROGRAM.
+
+SELECT IF 2.
+])
+AT_CHECK([pspp -O format=csv parse.sps], [1], [dnl
+"parse.sps:9: error: SELECT IF: A logical expression was found to have a value other than 0 (false), 1 (true), or the system-missing value.  The result was forced to 0."
+])
+AT_CLEANUP