Oscar N created GROOVY-11629:
--------------------------------
Summary: Redundant null check on @NullChecked parameter when
iterating on it
Key: GROOVY-11629
URL: https://issues.apache.org/jira/browse/GROOVY-11629
Project: Groovy
Issue Type: Bug
Affects Versions: 4.0.26, 3.0.24, 5.0.0-alpha-12
Reporter: Oscar N
When looping over a method parameter whose method is annotated with @NullCheck,
an additional null check performed before iterating. Here's a minimal example,
demonstrating the numbers parameter being checked for null twice:
{code:groovy}
import groovy.transform.CompileStatic
import groovy.transform.NullCheck
void main() {
listNumbers([1, 2, 3])
}
@CompileStatic
@NullCheck
void listNumbers(List<Number> numbers) {
for (number in numbers)
println number
}
{code}
Decompiled Java representation of the bytecode:
{code:java}
public void listNumbers(List<Number> numbers) {
if (numbers == null) {
throw (Throwable)(new IllegalArgumentException("numbers cannot be
null"));
} else {
Iterator var10000 = numbers != null ? numbers.iterator() : null;
Object number = null;
Iterator var4 = var10000;
if (var4 != null) {
while(var4.hasNext()) {
number = var4.next();
DefaultGroovyMethods.println(this, number);
Object var6 = null;
}
}
}
}
{code}
Bytecode:
{code:java}
// access flags 0x1
// signature (Ljava/util/List<Ljava/lang/Number;>;)V
// declaration: void listNumbers(java.util.List<java.lang.Number>)
public listNumbers(Ljava/util/List;)V
L0
ALOAD 1
IFNONNULL L1
ICONST_1
GOTO L2
L1
ICONST_0
L2
IFEQ L3
NEW java/lang/IllegalArgumentException
DUP
LDC "numbers cannot be null"
INVOKESPECIAL java/lang/IllegalArgumentException.<init> (Ljava/lang/String;)V
CHECKCAST java/lang/Throwable
ATHROW
L3
LINENUMBER 11 L3
ALOAD 1
DUP
ASTORE 2
IFNULL L4
ALOAD 2
INVOKEINTERFACE java/util/List.iterator ()Ljava/util/Iterator; (itf)
GOTO L5
L4
ACONST_NULL
L5
ACONST_NULL
ASTORE 3
L6
ASTORE 4
ALOAD 4
IFNULL L7
L8
ALOAD 4
INVOKEINTERFACE java/util/Iterator.hasNext ()Z (itf)
IFEQ L7
ALOAD 4
INVOKEINTERFACE java/util/Iterator.next ()Ljava/lang/Object; (itf)
ASTORE 3
L9
LINENUMBER 12 L9
ALOAD 0
ALOAD 3
INVOKESTATIC org/codehaus/groovy/runtime/DefaultGroovyMethods.println
(Ljava/lang/Object;Ljava/lang/Object;)V
ACONST_NULL
POP
GOTO L8
L7
LINENUMBER 13 L7
RETURN
LOCALVARIABLE this LRedundantNullCheck; L0 L7 0
LOCALVARIABLE numbers Ljava/util/List; L0 L7 1
LOCALVARIABLE number Ljava/lang/Object; L6 L7 3
MAXSTACK = 3
MAXLOCALS = 5
{code}
Note that this also happens in CompileDynamic mode.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)