From a61ff51c628975d1ce0dba666f2a6be4c648ddfe Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Mon, 2 Nov 2015 12:30:31 -0800 Subject: [PATCH] Bug 481274 - ArrayStoreException in parser Change-Id: I4ee9484794925efbb86d7621bbbf5f9932f31773 --- .../cdt/core/parser/tests/ArrayUtilTest.java | 17 ++++++++++++--- .../cdt/core/parser/util/ArrayUtil.java | 14 +++++++------ .../parser/cpp/semantics/EvalFunctionSet.java | 21 ++++++++++++++----- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ArrayUtilTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ArrayUtilTest.java index cdab81aa5d8..702c222638a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ArrayUtilTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ArrayUtilTest.java @@ -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() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java index 6c179ddeece..c9d26ccc610 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java index bae7071f614..25e757f0858 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java @@ -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()).