1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

Amend list-initialization handling of class or aggregate

This commit is contained in:
Igor V. Kovalenko 2023-10-07 23:45:38 +03:00 committed by Jonah Graham
parent ae3a0adb81
commit 84322c30f4
11 changed files with 131 additions and 100 deletions

View file

@ -16,6 +16,7 @@ import java.util.TreeSet;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
@ -147,13 +148,24 @@ public final class CompositeValue implements IValue {
ICPPEvaluation[] values = new ICPPEvaluation[fields.length];
ICPPEvaluation[] clauses = initList.getClauses();
for (int i = 0; i < fields.length; i++) {
if (i == clauses.length)
break;
IField field = fields[i];
ICPPEvaluation eval = clauses[i];
IType fieldType = field.getType();
IValue value = getValue(fieldType, eval);
values[i] = new EvalFixed(fieldType, eval.getValueCategory(), value);
IValue value;
ValueCategory valueCategory;
if (i < clauses.length) {
ICPPEvaluation eval = clauses[i];
value = getValue(fieldType, eval);
valueCategory = eval.getValueCategory();
} else {
// (dcl.init.aggr-7) from brace-or-equal-initializer or from {}
value = field.getInitialValue();
// Writing IntegralValue.UNKNOWN to PDOM stores null, convert it back
if (value == null || value == IntegralValue.UNKNOWN) {
value = IntegralValue.create(0);
}
valueCategory = ValueCategory.PRVALUE;
}
values[i] = new EvalFixed(fieldType, valueCategory, value);
}
return new CompositeValue(initList, values);
}

View file

@ -99,7 +99,7 @@ class AggregateInitialization {
}
Cost costWithoutElision = Conversions.checkImplicitConversionSequence(nestedType, initializer.getType(),
initializer.getValueCategory(), UDCMode.ALLOWED, Context.ORDINARY);
initializer.getValueCategory(), UDCMode.ALLOWED, Context.ORDINARY, false);
if (costWithoutElision.converts()) {
// p3: The elements of the initializer list are taken as initializers for the elements
// of the aggregate, in order.

View file

@ -195,7 +195,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
ValueCategory valueCategory = argument.getValueCategory();
if (uqType instanceof ICPPClassType) {
Cost cost = Conversions.initializationByConversion(valueCategory, type, (ICPPClassType) uqType,
targetType, false, allowContextualConversion);
targetType, false, allowContextualConversion, false);
ICPPFunction conversion = cost.getUserDefinedConversion();
if (conversion != null) {
if (onlyConstexprConversion && !conversion.isConstexpr()) {
@ -210,7 +210,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
// Source type is not a class type, or is but a conversion operator wasn't used.
// Check for standard conversions.
Cost cost = Conversions.checkImplicitConversionSequence(targetType, type, valueCategory, UDCMode.FORBIDDEN,
Context.ORDINARY);
Context.ORDINARY, false);
if (!cost.converts()) {
return EvalFixed.INCOMPLETE;
} else if (cost.getRank() == Rank.CONVERSION) {

View file

@ -3169,7 +3169,14 @@ public class CPPSemantics {
if (potentialCosts != null) {
for (FunctionCost fnCost : potentialCosts) {
if (!fnCost.mustBeWorse(bestFnCost) && fnCost.performUDC()) {
if (!fnCost.mustBeWorse(bestFnCost) && fnCost.performUDC(data.fNoNarrowing)) {
if (data.fNoNarrowing) {
for (int i = 0; i < fnCost.getLength(); ++i) {
if (fnCost.getCost(i).isNarrowingConversion()) {
continue;
}
}
}
int cmp = fnCost.compareTo(tu, bestFnCost, data.getFunctionArgumentCount());
if (cmp < 0) {
bestFnCost = fnCost;
@ -3473,7 +3480,7 @@ public class CPPSemantics {
Context context = ftype.hasRefQualifier() ? Context.IMPLICIT_OBJECT_FOR_METHOD_WITH_REF_QUALIFIER
: Context.IMPLICIT_OBJECT_FOR_METHOD_WITHOUT_REF_QUALIFIER;
cost = Conversions.checkImplicitConversionSequence(implicitParameterType, impliedObjectType,
impliedObjectValueCategory, UDCMode.FORBIDDEN, context);
impliedObjectValueCategory, UDCMode.FORBIDDEN, context, data.fNoNarrowing);
if (cost.converts()) {
cost.setImpliedObject();
} else {
@ -3530,7 +3537,9 @@ public class CPPSemantics {
}
}
}
cost = Conversions.checkImplicitConversionSequence(paramType, argType, argValueCategory, udc, ctx);
cost = Conversions.checkImplicitConversionSequence(paramType, argType, argValueCategory, udc, ctx,
data.fNoNarrowing);
// TODO: see if isNarrowingConversion() is re-checked while performing UDC again later
if (data.fNoNarrowing && cost.isNarrowingConversion()) {
cost = Cost.NO_CONVERSION;
}
@ -4118,10 +4127,16 @@ public class CPPSemantics {
if (initializer == null) {
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier();
parent = parent.getParent();
if (parent instanceof IASTCompositeTypeSpecifier
// (c++11:class.base.init 12.6.2-8) [..no initializer..]
// if the entity is an anonymous union or a variant member, no initialization is performed
// otherwise the entity is default-initialized
// (c++11:dcl.init 8.5-7)
// if T is a (possibly cv-qualified) class type .. the default constructor for T is called
if ((parent instanceof IASTCompositeTypeSpecifier compositeType
&& compositeType.getKey() == ICompositeType.k_union)
|| declSpec.getStorageClass() == IASTDeclSpecifier.sc_extern) {
// No initialization is performed for class members and extern declarations
// without an initializer.
// No initialization is performed for class members which are of union type,
// and for extern declarations without an initializer.
return null;
}
}
@ -4182,6 +4197,20 @@ public class CPPSemantics {
return null;
}
public static IBinding findConstructorForDirectListInitialization(ICPPClassType type, EvalInitList eval,
IASTNode typeId) throws DOMException {
Cost c = Conversions.listInitializationSequence(eval, type, UDCMode.ALLOWED, true);
if (c.converts()) {
ICPPFunction f = c.getUserDefinedConversion();
if (f instanceof ICPPConstructor) {
return f;
}
} else {
return new ProblemBinding(null, typeId, ISemanticProblem.BINDING_NOT_FOUND, type.getConstructors());
}
return null;
}
private static IBinding findImplicitlyCalledConstructor(ICPPClassType type, IASTInitializer initializer,
IASTNode typeId) {
pushLookupPoint(typeId);
@ -4207,10 +4236,10 @@ public class CPPSemantics {
}
Cost c;
if (calculateInheritanceDepth(sourceType, type) >= 0) {
c = Conversions.copyInitializationOfClass(isLValue, sourceType, type, false);
c = Conversions.copyInitializationOfClass(isLValue, sourceType, type, false, false);
} else {
c = Conversions.checkImplicitConversionSequence(type, sourceType, isLValue, UDCMode.ALLOWED,
Context.ORDINARY);
Context.ORDINARY, false);
}
if (c.converts()) {
ICPPFunction f = c.getUserDefinedConversion();
@ -4225,7 +4254,7 @@ public class CPPSemantics {
} else if (initializer instanceof ICPPASTInitializerList) {
// List initialization.
ICPPEvaluation eval = ((ICPPASTInitializerClause) initializer).getEvaluation();
if (eval instanceof EvalInitList) {
if (eval instanceof EvalInitList evalInitList) {
if (CPPTemplates.isDependentType(eval.getType())) {
ICPPEvaluation[] clauses = ((EvalInitList) eval).getClauses();
IType[] tmp = new IType[clauses.length];
@ -4235,14 +4264,9 @@ public class CPPSemantics {
setTargetedFunctionsToUnknown(tmp);
return CPPDeferredFunction.createForCandidates(type.getConstructors());
}
Cost c = Conversions.listInitializationSequence((EvalInitList) eval, type, UDCMode.ALLOWED, true);
if (c.converts()) {
ICPPFunction f = c.getUserDefinedConversion();
if (f instanceof ICPPConstructor)
return f;
} else {
return new ProblemBinding(null, typeId, ISemanticProblem.BINDING_NOT_FOUND,
type.getConstructors());
IBinding b = findConstructorForDirectListInitialization(type, evalInitList, typeId);
if (b != null) {
return b;
}
}
} else if (initializer instanceof ICPPASTConstructorInitializer) {

View file

@ -2983,7 +2983,8 @@ public class CPPTemplates {
}
}
Cost cost = Conversions.checkImplicitConversionSequence(p, a, LVALUE, UDCMode.FORBIDDEN, Context.ORDINARY);
Cost cost = Conversions.checkImplicitConversionSequence(p, a, LVALUE, UDCMode.FORBIDDEN, Context.ORDINARY,
false);
if (cost == null || !cost.converts()) {
ICPPEvaluation eval = arg.getNonTypeEvaluation();
ICPPEvaluation newEval = CPPEvaluation.maybeApplyConversion(eval, p, false, true);

View file

@ -99,7 +99,7 @@ public class Conversions {
* @throws DOMException
*/
public static Cost checkImplicitConversionSequence(IType target, IType exprType, ValueCategory valueCat,
UDCMode udc, Context ctx) throws DOMException {
UDCMode udc, Context ctx, boolean noNarrowing) throws DOMException {
final boolean isImpliedObject = ctx == Context.IMPLICIT_OBJECT_FOR_METHOD_WITHOUT_REF_QUALIFIER
|| ctx == Context.IMPLICIT_OBJECT_FOR_METHOD_WITH_REF_QUALIFIER;
if (isImpliedObject)
@ -211,7 +211,7 @@ public class Conversions {
// 13.3.3.1.7 no temporary object when converting the implicit object parameter
if (!isImpliedObject && ctx != Context.REQUIRE_DIRECT_BINDING) {
Cost cost = nonReferenceConversion(valueCat, cv2T2, T1, udc);
Cost cost = nonReferenceConversion(valueCat, cv2T2, T1, udc, noNarrowing);
if (cost.converts()) {
cost.setReferenceBinding(refBindingType);
}
@ -232,7 +232,7 @@ public class Conversions {
}
// Non-reference binding
return nonReferenceConversion(valueCat, exprType, T1, udc);
return nonReferenceConversion(valueCat, exprType, T1, udc, noNarrowing);
}
/**
@ -297,8 +297,8 @@ public class Conversions {
/**
* 8.5-16
*/
private static Cost nonReferenceConversion(ValueCategory valueCat, IType source, IType target, UDCMode udc)
throws DOMException {
private static Cost nonReferenceConversion(ValueCategory valueCat, IType source, IType target, UDCMode udc,
boolean noNarrowing) throws DOMException {
if (source instanceof InitializerListType) {
return listInitializationSequence(((InitializerListType) source).getEvaluation(), target, udc, false);
}
@ -321,7 +321,8 @@ public class Conversions {
if (udc == UDCMode.FORBIDDEN)
return Cost.NO_CONVERSION;
return copyInitializationOfClass(valueCat, source, (ICPPClassType) uqTarget, udc == UDCMode.DEFER);
return copyInitializationOfClass(valueCat, source, (ICPPClassType) uqTarget, udc == UDCMode.DEFER,
noNarrowing);
}
if (uqSource instanceof ICPPClassType) {
@ -329,7 +330,7 @@ public class Conversions {
return Cost.NO_CONVERSION;
return initializationByConversion(valueCat, source, (ICPPClassType) uqSource, target, udc == UDCMode.DEFER,
false);
false, noNarrowing);
}
return checkStandardConversionSequence(uqSource, target);
@ -352,7 +353,7 @@ public class Conversions {
Cost worstCost = new Cost(arg.getType(), target, Rank.IDENTITY);
for (ICPPEvaluation clause : arg.getClauses()) {
Cost cost = checkImplicitConversionSequence(listType, clause.getType(), clause.getValueCategory(),
UDCMode.ALLOWED, Context.ORDINARY);
UDCMode.ALLOWED, Context.ORDINARY, false);
if (!cost.converts())
return cost;
if (cost.isNarrowingConversion()) {
@ -389,7 +390,7 @@ public class Conversions {
final ICPPEvaluation firstArg = args[0];
if (!firstArg.isInitializerList()) {
Cost cost = checkImplicitConversionSequence(target, firstArg.getType(), firstArg.getValueCategory(),
udc, Context.ORDINARY);
udc, Context.ORDINARY, false);
if (cost.isNarrowingConversion()) {
return Cost.NO_CONVERSION;
}
@ -614,24 +615,7 @@ public class Conversions {
data.fNoNarrowing = true;
// 13.3.3.1.4
ICPPConstructor[] filteredConstructors = constructors;
if (expandedArgs.length == 1) {
filteredConstructors = new ICPPConstructor[constructors.length];
int j = 0;
for (ICPPConstructor ctor : constructors) {
if (ctor.getRequiredArgumentCount() < 2) {
IType[] ptypes = ctor.getType().getParameterTypes();
if (ptypes.length > 0) {
IType ptype = getNestedType(ptypes[0], TDEF | REF | CVTYPE);
if (!t.isSameType(ptype)) {
filteredConstructors[j++] = ctor;
}
}
}
}
}
final IBinding result = CPPSemantics.resolveFunction(data, filteredConstructors, true, false);
final IBinding result = CPPSemantics.resolveFunction(data, constructors, true, false);
final Cost c;
if (result instanceof ICPPMethod) {
if (!isDirect && ((ICPPMethod) result).isExplicit()) {
@ -658,8 +642,8 @@ public class Conversions {
/**
* 13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy]
*/
static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t, boolean deferUDC)
throws DOMException {
static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t, boolean deferUDC,
boolean noNarrowing) throws DOMException {
if (deferUDC) {
Cost c = new Cost(source, t, Rank.USER_DEFINED_CONVERSION);
c.setDeferredUDC(DeferredUDC.COPY_INIT_OF_CLASS);
@ -698,8 +682,14 @@ public class Conversions {
if (ctor.getRequiredArgumentCount() > 1)
continue;
c1 = new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, valueCat,
UDCMode.FORBIDDEN, Context.ORDINARY));
Cost cost = checkImplicitConversionSequence(ptype, source, valueCat, UDCMode.FORBIDDEN,
Context.ORDINARY, noNarrowing);
if (noNarrowing && cost.isNarrowingConversion()) {
cost = Cost.NO_CONVERSION;
}
c1 = new FunctionCost(ctor, cost);
}
int cmp = c1.compareTo(null, cost1, 1);
if (cmp <= 0) {
@ -761,7 +751,7 @@ public class Conversions {
* 13.3.1.5 Initialization by conversion function [over.match.conv]
*/
static Cost initializationByConversion(ValueCategory valueCat, IType source, ICPPClassType uqSource, IType target,
boolean deferUDC, boolean allowExplicitConversion) throws DOMException {
boolean deferUDC, boolean allowExplicitConversion, boolean noNarrowing) throws DOMException {
if (deferUDC) {
Cost c = new Cost(source, target, Rank.USER_DEFINED_CONVERSION);
c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION);
@ -783,7 +773,7 @@ public class Conversions {
final IType returnType = functionType.getReturnType();
IType uqReturnType = getNestedType(returnType, TDEF | ALLCVQ);
Cost c2 = checkImplicitConversionSequence(target, uqReturnType,
valueCategoryFromReturnType(uqReturnType), UDCMode.FORBIDDEN, Context.ORDINARY);
valueCategoryFromReturnType(uqReturnType), UDCMode.FORBIDDEN, Context.ORDINARY, noNarrowing);
if (c2.converts()) {
if (isExplicitConversion && c2.getRank() != Rank.IDENTITY)
continue;

View file

@ -306,7 +306,7 @@ public class EvalConditional extends CPPDependentEvaluation {
if (vcat2.isGLValue()) {
IType target = new CPPReferenceType(t2, vcat2 == XVALUE);
Cost c = Conversions.checkImplicitConversionSequence(target, t1, vcat1, UDCMode.ALLOWED,
Context.REQUIRE_DIRECT_BINDING);
Context.REQUIRE_DIRECT_BINDING, false);
if (c.converts()) {
fType = t2;
fValueCategory = vcat2;
@ -333,7 +333,8 @@ public class EvalConditional extends CPPDependentEvaluation {
if (vcat2 != PRVALUE) {
t2 = Conversions.lvalue_to_rvalue(t2, false);
}
Cost c = Conversions.checkImplicitConversionSequence(t2, t1, vcat1, UDCMode.ALLOWED, Context.ORDINARY);
Cost c = Conversions.checkImplicitConversionSequence(t2, t1, vcat1, UDCMode.ALLOWED, Context.ORDINARY,
false);
if (c.converts()) {
fType = t2;
fValueCategory = PRVALUE;

View file

@ -35,7 +35,6 @@ 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.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
@ -234,7 +233,9 @@ public class EvalTypeId extends CPPDependentEvaluation {
}
private boolean computeIsConstantExpression() {
if (getConstructor() == null && fArguments.length == 1) {
ICPPFunction constructor = getConstructor();
if (constructor == null && fArguments.length == 1) {
// maybe EvalTypeID represents a conversion
ICPPEvaluation conversionEval = maybeApplyConversion(fArguments[0], fInputType, false, false);
if (isEquivalentTo(conversionEval)) {
@ -244,9 +245,13 @@ public class EvalTypeId extends CPPDependentEvaluation {
if (!conversionEval.isConstantExpression())
return false;
} else if (constructor == AGGREGATE_INITIALIZATION) {
// A literal type is one for which it might be possible to create an object within a constant expression.
// See also CPPImplicitConstructor.isConstExpr()
return getInputType() instanceof ICPPClassType classType && TypeTraits.isLiteralClass(classType);
}
return !fRepresentsNewExpression && areAllConstantExpressions(fArguments)
&& isNullOrConstexprFunc(getConstructor());
return !fRepresentsNewExpression && areAllConstantExpressions(fArguments) && isNullOrConstexprFunc(constructor);
}
@Override
@ -285,38 +290,35 @@ public class EvalTypeId extends CPPDependentEvaluation {
return null;
IType simplifiedType = SemanticUtil.getNestedType(fInputType, TDEF | CVTYPE);
if (simplifiedType instanceof ICPPClassType) {
ICPPClassType classType = (ICPPClassType) simplifiedType;
ICPPEvaluation[] arguments = fArguments;
ICPPConstructor[] constructors = classType.getConstructors();
if (fUsesBracedInitList && arguments.length > 0) {
if (simplifiedType instanceof ICPPClassType classType) {
if (fUsesBracedInitList) {
// (dcl.init.list)
EvalInitList evalInitList = new EvalInitList(fArguments, getTemplateDefinition());
try {
// List-initialization of a class (dcl.init.list-3).
// e.g. A{1,2}
ICPPConstructor[] ctors = getInitializerListConstructors(constructors);
if (ctors.length != 0) {
constructors = ctors;
arguments = new EvalInitList[] { new EvalInitList(arguments, getTemplateDefinition()) };
}
} else if (arguments.length == 1 && arguments[0] instanceof EvalInitList && !fUsesBracedInitList) {
// List-initialization of a class (dcl.init.list-3).
// e.g. A({1,2})
if (TypeTraits.isAggregateClass(classType)) {
// Pretend that aggregate initialization is calling the default constructor.
return findDefaultConstructor(classType, constructors);
}
if (((EvalInitList) arguments[0]).getClauses().length == 0) {
ICPPMethod ctor = findDefaultConstructor(classType, constructors);
if (ctor != null)
return ctor;
}
ICPPConstructor[] ctors = getInitializerListConstructors(constructors);
if (ctors.length != 0) {
constructors = ctors;
} else {
arguments = ((EvalInitList) arguments[0]).getClauses();
IBinding binding = CPPSemantics.findConstructorForDirectListInitialization(classType, evalInitList,
null);
if (binding instanceof ICPPConstructor constructor) {
return constructor;
} else if (binding instanceof IProblemBinding) {
return new CPPFunction.CPPFunctionProblem(null, ISemanticProblem.BINDING_NOT_FOUND,
classType.getNameCharArray());
} else if (TypeTraits.isAggregateClass(classType)) {
// If Conversions.listInitializationSequence() did not returned problem binding,
// this is a list-initialization of aggregate class, and there is no constructor.
return AGGREGATE_INITIALIZATION;
}
} catch (DOMException e) {
CCorePlugin.log(e);
}
return null;
}
ICPPEvaluation[] arguments = fArguments;
ICPPConstructor[] constructors = classType.getConstructors();
LookupData data = new LookupData(classType.getNameCharArray(), null, CPPSemantics.getCurrentLookupPoint());
data.foundItems = constructors;
data.setFunctionArguments(false, arguments);

View file

@ -98,7 +98,7 @@ class FunctionCost {
return false;
}
public boolean performUDC() throws DOMException {
public boolean performUDC(boolean noNarrowing) throws DOMException {
for (int i = 0; i < fCosts.length; i++) {
Cost cost = fCosts[i];
Cost udcCost = null;
@ -107,12 +107,12 @@ class FunctionCost {
continue;
case COPY_INIT_OF_CLASS:
udcCost = Conversions.copyInitializationOfClass(fValueCategories[i], cost.source,
(ICPPClassType) cost.target, false);
(ICPPClassType) cost.target, false, noNarrowing);
break;
case INIT_BY_CONVERSION:
IType uqSource = getNestedType(cost.source, TDEF | REF | CVTYPE);
udcCost = Conversions.initializationByConversion(fValueCategories[i], cost.source,
(ICPPClassType) uqSource, cost.target, false, allowsContextualBooleanConversion());
(ICPPClassType) uqSource, cost.target, false, allowsContextualBooleanConversion(), noNarrowing);
break;
case LIST_INIT_OF_CLASS:
udcCost = Conversions.listInitializationOfClass(((InitializerListType) cost.source).getEvaluation(),
@ -126,6 +126,7 @@ class FunctionCost {
return false;
}
fCosts[i] = udcCost;
if (!udcCost.converts()) {
return false;
}

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.ui; singleton:=true
Bundle-Version: 8.1.200.qualifier
Bundle-Version: 8.1.300.qualifier
Bundle-Activator: org.eclipse.cdt.ui.CUIPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@ -104,7 +104,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
org.eclipse.cdt.ui.wizards.conversion,
org.eclipse.cdt.utils.ui.controls
Import-Package: org.apache.commons.io;version="[2.8.0,3.0.0)"
Require-Bundle: org.eclipse.cdt.core;bundle-version="[8.3.0,9.0.0)",
Require-Bundle: org.eclipse.cdt.core;bundle-version="[8.4.0,9.0.0)",
org.eclipse.compare;bundle-version="[3.8.500,4.0.0)",
org.eclipse.core.expressions;bundle-version="[3.8.200,4.0.0)",
org.eclipse.core.filesystem;bundle-version="[1.9.500,2.0.0)",

View file

@ -180,7 +180,7 @@ public class ParameterGuesser {
private boolean isImplicitlyConvertible(IType orginType, IType candidateType) {
try {
Cost cost = Conversions.checkImplicitConversionSequence(orginType, candidateType, ValueCategory.LVALUE,
UDCMode.ALLOWED, Context.ORDINARY);
UDCMode.ALLOWED, Context.ORDINARY, false);
if (cost.converts())
return true;
} catch (DOMException e) {