8029467: Widening of booleans causes bad results

Mon, 09 Dec 2013 10:52:05 +0100

author
attila
date
Mon, 09 Dec 2013 10:52:05 +0100
changeset 692
4706897b4dec
parent 690
752554d45a07
child 693
18edd7a1b166

8029467: Widening of booleans causes bad results
Reviewed-by: jlaskey, lagergren

src/jdk/nashorn/internal/codegen/Attr.java file | annotate | diff | comparison | revisions
test/script/basic/JDK-8029467.js file | annotate | diff | comparison | revisions
test/script/basic/JDK-8029467.js.EXPECTED file | annotate | diff | comparison | revisions
     1.1 --- a/src/jdk/nashorn/internal/codegen/Attr.java	Mon Dec 09 09:48:11 2013 +0530
     1.2 +++ b/src/jdk/nashorn/internal/codegen/Attr.java	Mon Dec 09 10:52:05 2013 +0100
     1.3 @@ -766,7 +766,7 @@
     1.4                  symbol.setType(Type.OBJECT);
     1.5              }
     1.6  
     1.7 -            returnType = Type.widest(returnTypes.pop(), symbol.getSymbolType());
     1.8 +            returnType = widestReturnType(returnTypes.pop(), symbol.getSymbolType());
     1.9          } else {
    1.10              returnType = Type.OBJECT; //undefined
    1.11          }
    1.12 @@ -1433,10 +1433,30 @@
    1.13          ensureTypeNotUnknown(trueExpr);
    1.14          ensureTypeNotUnknown(falseExpr);
    1.15  
    1.16 -        final Type type = Type.widest(trueExpr.getType(), falseExpr.getType());
    1.17 +        final Type type = widestReturnType(trueExpr.getType(), falseExpr.getType());
    1.18          return end(ensureSymbol(type, ternaryNode));
    1.19      }
    1.20  
    1.21 +    /**
    1.22 +     * When doing widening for return types of a function or a ternary operator, it is not valid to widen a boolean to
    1.23 +     * anything other than Object. Also, widening a numeric type to an object type must widen to Object proper and not
    1.24 +     * any more specific subclass (e.g. widest of int/long/double and String is Object).
    1.25 +     * @param t1 type 1
    1.26 +     * @param t2 type 2
    1.27 +     * @return wider of t1 and t2, except if one is boolean and the other is neither boolean nor unknown, or if one is
    1.28 +     * numeric and the other is neither numeric nor unknown in which case {@code Type.OBJECT} is returned.
    1.29 +     */
    1.30 +    private static Type widestReturnType(final Type t1, final Type t2) {
    1.31 +        if (t1.isUnknown()) {
    1.32 +            return t2;
    1.33 +        } else if (t2.isUnknown()) {
    1.34 +            return t1;
    1.35 +        } else if (t1.isBoolean() != t2.isBoolean() || t1.isNumeric() != t2.isNumeric()) {
    1.36 +            return Type.OBJECT;
    1.37 +        }
    1.38 +        return Type.widest(t1, t2);
    1.39 +    }
    1.40 +
    1.41      private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) {
    1.42          final Class<?> type = cc.type();
    1.43          // Must not call this method for constants with no explicit types; use the one with (..., Type) signature instead.
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/test/script/basic/JDK-8029467.js	Mon Dec 09 10:52:05 2013 +0100
     2.3 @@ -0,0 +1,34 @@
     2.4 +/*
     2.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + * 
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.
    2.11 + * 
    2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.15 + * version 2 for more details (a copy is included in the LICENSE file that
    2.16 + * accompanied this code).
    2.17 + * 
    2.18 + * You should have received a copy of the GNU General Public License version
    2.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.21 + * 
    2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.23 + * or visit www.oracle.com if you need additional information or have any
    2.24 + * questions.
    2.25 + */
    2.26 +
    2.27 +/**
    2.28 + * JDK-8029467: Widening of booleans causes bad results
    2.29 + *
    2.30 + * @test
    2.31 + * @run
    2.32 + */
    2.33 +
    2.34 +print((function (x) { return x ? true : 0 })(true))
    2.35 +print((function (x) { if(x) { return true } else { return 0 } })(true))
    2.36 +print(typeof (function (x) { return x ? 1 : "123" })(true) === "number")
    2.37 +print(typeof (function (x) { if(x) { return 1 } else { return "123" } })(true) === "number")
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/script/basic/JDK-8029467.js.EXPECTED	Mon Dec 09 10:52:05 2013 +0100
     3.3 @@ -0,0 +1,4 @@
     3.4 +true
     3.5 +true
     3.6 +true
     3.7 +true

mercurial