Bug 481274 - ArrayStoreException in parser
authorSergey Prigogin <eclipse.sprigogin@gmail.com>
Mon, 2 Nov 2015 20:30:31 +0000 (12:30 -0800)
committerSergey Prigogin <eclipse.sprigogin@gmail.com>
Fri, 6 Nov 2015 22:46:36 +0000 (14:46 -0800)
Change-Id: I4ee9484794925efbb86d7621bbbf5f9932f31773

core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ArrayUtilTest.java
core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java
core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java

index cdab81a..702c222 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 2015 Wind River Systems, Inc. and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,13 +7,14 @@
  *
  * Contributors:
  *     Markus Schorn - initial API and implementation
+ *     Sergey Prigogin (Google)
  *******************************************************************************/ 
 package org.eclipse.cdt.core.parser.tests;
 
-import junit.framework.TestCase;
-
 import org.eclipse.cdt.core.parser.util.ArrayUtil;
 
+import junit.framework.TestCase;
+
 public class ArrayUtilTest extends TestCase {
        private final Object o1= new Object();
        private final Object o2= new Object();
@@ -134,6 +135,16 @@ public class ArrayUtilTest extends TestCase {
                assertEquals(o1, result[0]);
                assertEquals(o2, result[1]);
                assertSame(array1, result);
+
+               // Check that mismatched array types don't cause an ArrayStoreException.
+               // See http://bugs.eclipse.org/481274
+               array1= new Integer[] {1, 2};
+               array2= new String[] {"s"};
+               result= ArrayUtil.addAll(Object.class, array1, array2);
+               assertEquals(3, result.length);
+               assertEquals(1, result[0]);
+               assertEquals(2, result[1]);
+               assertEquals("s", result[2]);
        }
        
        public void testRemove() {
index 6c179dd..c9d26cc 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2014 IBM Corporation and others.
+ * Copyright (c) 2004, 2015 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -273,10 +273,10 @@ public abstract class ArrayUtil {
             return dest;
 
         int numToAdd = findFirstNull(source);
-        if (numToAdd <= 0) {
-               if (numToAdd == 0) {
-                       return dest;
-               }
+       if (numToAdd == 0) {
+               return dest;
+       }
+        if (numToAdd < 0) {
                numToAdd= source.length;
         }
 
@@ -295,7 +295,9 @@ public abstract class ArrayUtil {
             System.arraycopy(source, 0, dest, firstFree, numToAdd);
             return dest;
         }
-        dest = Arrays.copyOf(dest, firstFree + numToAdd);
+        T[] oldDest = dest;
+        dest = (T[]) Array.newInstance(c, firstFree + numToAdd);
+        System.arraycopy(oldDest, 0, dest, 0, firstFree);
         System.arraycopy(source, 0, dest, firstFree, numToAdd);
         return dest;
     }
index bae7071..25e757f 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Wind River Systems, Inc. and others.
+ * Copyright (c) 2012, 2015 Wind River Systems, Inc. and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
 import org.eclipse.cdt.core.dom.ast.IValue;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
@@ -33,6 +34,7 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
 import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
 import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
 import org.eclipse.cdt.internal.core.dom.parser.Value;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
 import org.eclipse.core.runtime.CoreException;
@@ -289,8 +291,8 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
                        data = new LookupData(fName, null, point);
                } else {
                        functions = fFunctionSet.getBindings();
-                       data = new LookupData(functions[0].getNameCharArray(),
-                                       fFunctionSet.getTemplateArguments(), point);
+                       data = new LookupData(functions[0].getNameCharArray(), fFunctionSet.getTemplateArguments(),
+                                       point);
                        data.foundItems = functions;
                }
                data.setFunctionArguments(false, args);
@@ -305,11 +307,20 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
                                Object[] foundItems = (Object[]) data.foundItems;
                                if (foundItems != null && (functions == null || foundItems.length > functions.length)) {
                                        // ADL found additional functions.
-                                       functions = Arrays.copyOf(foundItems, foundItems.length, ICPPFunction[].class);
+                                       int start = functions == null ? 0 : functions.length;
+                                       for (int i = start; i < foundItems.length; i++) {
+                                               Object obj = foundItems[i];
+                                               if (obj instanceof ICPPFunction) {
+                                                       functions = ArrayUtil.append(ICPPFunction.class, functions, (ICPPFunction) obj);
+                                               } else if (obj instanceof ICPPClassType) {
+                                                       functions = ArrayUtil.addAll(ICPPFunction.class, functions,
+                                                                       ClassTypeHelper.getConstructors((ICPPClassType) obj, point));
+                                               }
+                                       }
 
                                        // doKoenigLookup() may introduce duplicates into the result. These must be
                                        // eliminated to avoid resolveFunction() reporting an ambiguity. (Normally, when
-                                       // looukp() and doKoenigLookup() are called on the same LookupData object, the
+                                       // lookup() and doKoenigLookup() are called on the same LookupData object, the
                                        // two functions coordinate using data stored in that object to eliminate
                                        // duplicates, but in this case lookup() was called before with a different
                                        // LookupData object and now we are only calling doKoenigLookup()).