From 0db42c2d683822e1252f17c2c81252a79e618d9c Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 25 Sep 2012 15:14:50 -0700 Subject: [PATCH] expressions: Fix coercion of numbers to booleans at top level. 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 | 19 +++++++++++-------- src/language/expressions/parse.c | 7 ++++--- tests/language/expressions/parse.at | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/language/expressions/operations.def b/src/language/expressions/operations.def index 207551b7ea..37af54a911 100644 --- a/src/language/expressions/operations.def +++ b/src/language/expressions/operations.def @@ -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; diff --git a/src/language/expressions/parse.c b/src/language/expressions/parse.c index 3124c100a1..24380e2819 100644 --- a/src/language/expressions/parse.c +++ b/src/language/expressions/parse.c @@ -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: diff --git a/tests/language/expressions/parse.at b/tests/language/expressions/parse.at index df8192b28e..31791a41da 100644 --- a/tests/language/expressions/parse.at +++ b/tests/language/expressions/parse.at @@ -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 -- 2.30.2