[
https://issues.apache.org/jira/browse/GROOVY-7656?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Shil Sinha reopened GROOVY-7656:
--------------------------------
> Spread safe method calls on list literals result in the list expression being
> evaluated twice (SC)
> --------------------------------------------------------------------------------------------------
>
> Key: GROOVY-7656
> URL: https://issues.apache.org/jira/browse/GROOVY-7656
> Project: Groovy
> Issue Type: Bug
> Components: Static compilation
> Affects Versions: 2.4.5
> Reporter: Shil Sinha
> Assignee: Shil Sinha
> Priority: Critical
> Fix For: 2.4.6
>
>
> When a list literal is the receiver for a statically compiled spread safe
> method call expression, the instructions to create the list are included
> twice. Example:
> {code}
> @groovy.transform.CompileStatic
> void test() {
> ['a']*.size()
> }
> {code}
> The bytecode for the method above is:
> {code}
> L0
> LINENUMBER 3 L0
> NEW java/util/ArrayList
> DUP
> INVOKESPECIAL java/util/ArrayList.<init> ()V
> ASTORE 1
> L1
> ALOAD 1
> POP
> ICONST_1
> ANEWARRAY java/lang/Object
> DUP
> ICONST_0
> LDC "a"
> AASTORE
> INVOKESTATIC org/codehaus/groovy/runtime/ScriptBytecodeAdapter.createList
> ([Ljava/lang/Object;)Ljava/util/List;
> IFNULL L2
> ACONST_NULL
> ASTORE 2
> L3
> ICONST_1
> ANEWARRAY java/lang/Object
> DUP
> ICONST_0
> LDC "a"
> AASTORE
> INVOKESTATIC org/codehaus/groovy/runtime/ScriptBytecodeAdapter.createList
> ([Ljava/lang/Object;)Ljava/util/List;
> INVOKEINTERFACE java/util/List.iterator ()Ljava/util/Iterator;
> ASTORE 3
> L4
> ALOAD 3
> INVOKEINTERFACE java/util/Iterator.hasNext ()Z
> IFEQ L2
> ALOAD 3
> INVOKEINTERFACE java/util/Iterator.next ()Ljava/lang/Object;
> ASTORE 2
> ALOAD 1
> ALOAD 2
> DUP
> ASTORE 4
> IFNULL L5
> ALOAD 4
> INVOKESTATIC
> org/codehaus/groovy/runtime/typehandling/ShortTypeHandling.castToString
> (Ljava/lang/Object;)Ljava/lang/String;
> CHECKCAST java/lang/String
> INVOKESTATIC org/codehaus/groovy/runtime/StringGroovyMethods.size
> (Ljava/lang/String;)I
> INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
> GOTO L6
> L5
> ACONST_NULL
> L6
> INVOKEVIRTUAL java/util/ArrayList.add (Ljava/lang/Object;)Z
> POP
> GOTO L4
> L2
> ALOAD 1
> POP
> {code}
> If the list expression contains method calls that have side effects, this can
> cause serious problems. The example below is trivial, but shows the general
> case:
> {code}
> @groovy.transform.CompileStatic
> void test() {
> def list = ['abc']
> def lengths = [list.removeAt(0)]*.length() // throws
> IndexOutOfBoundsException
> }
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)