Repository: groovy Updated Branches: refs/heads/GROOVY_2_4_X b1896fead -> 9ff17a494
GROOVY-7876: ClassCastException when calling DefaultTypeTransformation#compareEqual (closes #368) Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/9ff17a49 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/9ff17a49 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/9ff17a49 Branch: refs/heads/GROOVY_2_4_X Commit: 9ff17a494381a7532f4aa337926dc3ff51f5fd75 Parents: b1896fe Author: paulk <pa...@asert.com.au> Authored: Tue Jul 19 22:02:01 2016 +1000 Committer: paulk <pa...@asert.com.au> Committed: Fri Jul 22 09:32:21 2016 +1000 ---------------------------------------------------------------------- .../typehandling/DefaultTypeTransformation.java | 9 ++++- src/test/groovy/bugs/Groovy7876Bug.groovy | 39 ++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/9ff17a49/src/main/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java b/src/main/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java index 95ddc00..bf9fe91 100644 --- a/src/main/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java +++ b/src/main/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java @@ -585,7 +585,14 @@ public class DefaultTypeTransformation { || (right.getClass() != Object.class && right.getClass().isAssignableFrom(left.getClass())) //GROOVY-4046 || (left instanceof GString && right instanceof String)) { Comparable comparable = (Comparable) left; - return comparable.compareTo(right); + // GROOVY-7876: when comparing for equality we try to only call compareTo when an assignable + // relationship holds but with a container/holder class and because of erasure, we might still end + // up with the prospect of a ClassCastException which we want to ignore but only if testing equality + try { + return comparable.compareTo(right); + } catch (ClassCastException cce) { + if (!equalityCheckOnly) throw cce; + } } } http://git-wip-us.apache.org/repos/asf/groovy/blob/9ff17a49/src/test/groovy/bugs/Groovy7876Bug.groovy ---------------------------------------------------------------------- diff --git a/src/test/groovy/bugs/Groovy7876Bug.groovy b/src/test/groovy/bugs/Groovy7876Bug.groovy new file mode 100644 index 0000000..5ec368e --- /dev/null +++ b/src/test/groovy/bugs/Groovy7876Bug.groovy @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package groovy.bugs + +class Groovy7876Bug extends GroovyTestCase { + void testClassCastExceptionsFromCompareToShouldNotLeakOutOfEqualityCheck() { + assertScript ''' + enum E1 {A, B, C} + enum E2 {D, E, F} + class Holder<T> implements Comparable<T> { + final T thing + Holder(T thing) { this.thing = thing } + int compareTo(T other) { thing.compareTo(other.thing) } + } + def a = new Holder<E1>(E1.A) + def d = new Holder<E2>(E2.D) + assert E1.A != E2.D // control + assert a != d // invokes compareTo + ''' + } +}