mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-10 12:03:16 +02:00
Bugs 250582, 250583.
This commit is contained in:
parent
b8c624e10f
commit
d2c1866cb7
2 changed files with 50 additions and 43 deletions
|
@ -6119,12 +6119,22 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
assertSame(ors[0], m1);
|
assertSame(ors[0], m1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void f(...);
|
// void f();
|
||||||
|
//
|
||||||
|
// void test(int p) {
|
||||||
|
// f(p);
|
||||||
|
// }
|
||||||
|
public void testFunctionExtraArgument() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
ba.assertProblem("f(p)", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// void f(...);
|
||||||
//
|
//
|
||||||
// void test(int* p) {
|
// void test(int* p) {
|
||||||
// f(p);
|
// f(p);
|
||||||
// }
|
// }
|
||||||
public void _testVariadicFunction_2500582() throws Exception {
|
public void testVariadicFunction_2500582() throws Exception {
|
||||||
final String comment= getAboveComment();
|
final String comment= getAboveComment();
|
||||||
final boolean[] isCpps= {false, true};
|
final boolean[] isCpps= {false, true};
|
||||||
for (boolean isCpp : isCpps) {
|
for (boolean isCpp : isCpps) {
|
||||||
|
@ -6132,7 +6142,7 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
ba.assertNonProblem("f(p)", 1, IFunction.class);
|
ba.assertNonProblem("f(p)", 1, IFunction.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct Incomplete;
|
// struct Incomplete;
|
||||||
//
|
//
|
||||||
// void f(Incomplete* p);
|
// void f(Incomplete* p);
|
||||||
|
@ -6142,7 +6152,7 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
// // Should resolve to f(Incomplete*) since 0 can be converted to Incomplete*
|
// // Should resolve to f(Incomplete*) since 0 can be converted to Incomplete*
|
||||||
// f(0);
|
// f(0);
|
||||||
// }
|
// }
|
||||||
public void _testVariadicFunction_2500583() throws Exception {
|
public void testVariadicFunction_2500583() throws Exception {
|
||||||
final String comment= getAboveComment();
|
final String comment= getAboveComment();
|
||||||
final boolean[] isCpps= {false, true};
|
final boolean[] isCpps= {false, true};
|
||||||
for (boolean isCpp : isCpps) {
|
for (boolean isCpp : isCpps) {
|
||||||
|
|
|
@ -1991,11 +1991,11 @@ public class CPPSemantics {
|
||||||
return new CPPUsingDeclaration(data.astName, fns);
|
return new CPPUsingDeclaration(data.astName, fns);
|
||||||
}
|
}
|
||||||
|
|
||||||
//we don't have any arguments with which to resolve the function
|
// We don't have any arguments with which to resolve the function
|
||||||
if (data.functionParameters == null) {
|
if (data.functionParameters == null) {
|
||||||
return resolveTargetedFunction(data, fns);
|
return resolveTargetedFunction(data, fns);
|
||||||
}
|
}
|
||||||
//reduce our set of candidate functions to only those who have the right number of parameters
|
// Reduce our set of candidate functions to only those who have the right number of parameters
|
||||||
reduceToViable(data, fns);
|
reduceToViable(data, fns);
|
||||||
|
|
||||||
if (data.forDefinition() || data.forExplicitInstantiation()) {
|
if (data.forDefinition() || data.forExplicitInstantiation()) {
|
||||||
|
@ -2007,29 +2007,29 @@ public class CPPSemantics {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFunction bestFn = null; //the best function
|
IFunction bestFn = null; // the best function
|
||||||
IFunction currFn = null; //the function currently under consideration
|
IFunction currFn = null; // the function currently under consideration
|
||||||
Cost[] bestFnCost = null; //the cost of the best function
|
Cost[] bestFnCost = null; // the cost of the best function
|
||||||
Cost[] currFnCost = null; //the cost for the current function
|
Cost[] currFnCost = null; // the cost for the current function
|
||||||
|
|
||||||
IASTExpression sourceExp;
|
IASTExpression sourceExp;
|
||||||
IType source = null; //parameter we are called with
|
IType source = null; // parameter we are called with
|
||||||
IType target = null; //function's parameter
|
IType target = null; // function's parameter
|
||||||
|
|
||||||
int comparison;
|
int comparison;
|
||||||
Cost cost = null; //the cost of converting source to target
|
Cost cost = null; // the cost of converting source to target
|
||||||
|
|
||||||
boolean hasWorse = false; //currFn has a worse parameter fit than bestFn
|
boolean hasWorse = false; // currFn has a worse parameter fit than bestFn
|
||||||
boolean hasBetter = false; //currFn has a better parameter fit than bestFn
|
boolean hasBetter = false; // currFn has a better parameter fit than bestFn
|
||||||
boolean ambiguous = false; //ambiguity, 2 functions are equally good
|
boolean ambiguous = false; // ambiguity, 2 functions are equally good
|
||||||
boolean currHasAmbiguousParam = false; //currFn has an ambiguous parameter conversion (ok if not bestFn)
|
boolean currHasAmbiguousParam = false; // currFn has an ambiguous parameter conversion (ok if not bestFn)
|
||||||
boolean bestHasAmbiguousParam = false; //bestFn has an ambiguous parameter conversion (not ok, ambiguous)
|
boolean bestHasAmbiguousParam = false; // bestFn has an ambiguous parameter conversion (not ok, ambiguous)
|
||||||
|
|
||||||
final IType[] sourceParameters = getSourceParameterTypes(data.functionParameters); //the parameters the function is being called with
|
final IType[] sourceParameters = getSourceParameterTypes(data.functionParameters); // the parameters the function is being called with
|
||||||
final boolean sourceVoid = (data.functionParameters == null || data.functionParameters.length == 0);
|
final boolean sourceVoid = (data.functionParameters == null || data.functionParameters.length == 0);
|
||||||
final IType impliedObjectType = data.getImpliedObjectArgument();
|
final IType impliedObjectType = data.getImpliedObjectArgument();
|
||||||
|
|
||||||
// loop over all functions
|
// Loop over all functions
|
||||||
function_loop: for (int fnIdx = 0; fnIdx < fns.length; fnIdx++) {
|
function_loop: for (int fnIdx = 0; fnIdx < fns.length; fnIdx++) {
|
||||||
currFn= fns[fnIdx];
|
currFn= fns[fnIdx];
|
||||||
if (currFn == null || bestFn == currFn) {
|
if (currFn == null || bestFn == currFn) {
|
||||||
|
@ -2039,7 +2039,6 @@ public class CPPSemantics {
|
||||||
final IType[] targetParameters = getTargetParameterTypes(currFn);
|
final IType[] targetParameters = getTargetParameterTypes(currFn);
|
||||||
final int useImplicitObj = (currFn instanceof ICPPMethod && !(currFn instanceof ICPPConstructor)) ? 1 : 0;
|
final int useImplicitObj = (currFn instanceof ICPPMethod && !(currFn instanceof ICPPConstructor)) ? 1 : 0;
|
||||||
final int sourceLen= Math.max(sourceParameters.length + useImplicitObj, 1);
|
final int sourceLen= Math.max(sourceParameters.length + useImplicitObj, 1);
|
||||||
final int numTargetParams= Math.max(targetParameters.length, 1 + useImplicitObj);
|
|
||||||
|
|
||||||
if (currFnCost == null || currFnCost.length != sourceLen) {
|
if (currFnCost == null || currFnCost.length != sourceLen) {
|
||||||
currFnCost= new Cost[sourceLen];
|
currFnCost= new Cost[sourceLen];
|
||||||
|
@ -2059,21 +2058,19 @@ public class CPPSemantics {
|
||||||
Object se= data.functionParameters.length == 0 ? null : data.functionParameters[j];
|
Object se= data.functionParameters.length == 0 ? null : data.functionParameters[j];
|
||||||
sourceExp= se instanceof IASTExpression ? (IASTExpression) se : null;
|
sourceExp= se instanceof IASTExpression ? (IASTExpression) se : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j < numTargetParams) {
|
if (j < targetParameters.length) {
|
||||||
if (j == targetParameters.length) {
|
target = targetParameters[j];
|
||||||
target = VOID_TYPE;
|
} else if (currFn.takesVarArgs()) {
|
||||||
} else {
|
|
||||||
target = targetParameters[j];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
varArgs = true;
|
varArgs = true;
|
||||||
}
|
} else {
|
||||||
|
target = VOID_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
if (isImpliedObject && ASTInternal.isStatic(currFn, false)) {
|
if (isImpliedObject && ASTInternal.isStatic(currFn, false)) {
|
||||||
//13.3.1-4 for static member functions, the implicit object parameter is considered to match any object
|
//13.3.1-4 for static member functions, the implicit object parameter is considered to match any object
|
||||||
cost = new Cost(source, target);
|
cost = new Cost(source, target);
|
||||||
cost.rank = Cost.IDENTITY_RANK; //exact match, no cost
|
cost.rank = Cost.IDENTITY_RANK; // exact match, no cost
|
||||||
} else if (source == null) {
|
} else if (source == null) {
|
||||||
continue function_loop;
|
continue function_loop;
|
||||||
} else if (varArgs) {
|
} else if (varArgs) {
|
||||||
|
@ -2081,7 +2078,7 @@ public class CPPSemantics {
|
||||||
cost.rank = Cost.ELLIPSIS_CONVERSION;
|
cost.rank = Cost.ELLIPSIS_CONVERSION;
|
||||||
} else if (source.isSameType(target) || (sourceVoid && j == useImplicitObj)) {
|
} else if (source.isSameType(target) || (sourceVoid && j == useImplicitObj)) {
|
||||||
cost = new Cost(source, target);
|
cost = new Cost(source, target);
|
||||||
cost.rank = Cost.IDENTITY_RANK; //exact match, no cost
|
cost.rank = Cost.IDENTITY_RANK; // exact match, no cost
|
||||||
} else {
|
} else {
|
||||||
cost= Conversions.checkImplicitConversionSequence(!data.forUserDefinedConversion, sourceExp, source, target, isImpliedObject);
|
cost= Conversions.checkImplicitConversionSequence(!data.forUserDefinedConversion, sourceExp, source, target, isImpliedObject);
|
||||||
}
|
}
|
||||||
|
@ -2092,9 +2089,9 @@ public class CPPSemantics {
|
||||||
|
|
||||||
hasWorse = false;
|
hasWorse = false;
|
||||||
hasBetter = false;
|
hasBetter = false;
|
||||||
//In order for this function to be better than the previous best, it must
|
// In order for this function to be better than the previous best, it must
|
||||||
//have at least one parameter match that is better that the corresponding
|
// have at least one parameter match that is better that the corresponding
|
||||||
//match for the other function, and none that are worse.
|
// match for the other function, and none that are worse.
|
||||||
int len = (bestFnCost == null || currFnCost.length < bestFnCost.length) ? currFnCost.length : bestFnCost.length;
|
int len = (bestFnCost == null || currFnCost.length < bestFnCost.length) ? currFnCost.length : bestFnCost.length;
|
||||||
for (int j = 1; j <= len; j++) {
|
for (int j = 1; j <= len; j++) {
|
||||||
Cost currCost = currFnCost[currFnCost.length - j];
|
Cost currCost = currFnCost[currFnCost.length - j];
|
||||||
|
@ -2104,8 +2101,8 @@ public class CPPSemantics {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//an ambiguity in the user defined conversion sequence is only a problem
|
// An ambiguity in the user defined conversion sequence is only a problem
|
||||||
//if this function turns out to be the best.
|
// if this function turns out to be the best.
|
||||||
currHasAmbiguousParam = (currCost.userDefined == 1);
|
currHasAmbiguousParam = (currCost.userDefined == 1);
|
||||||
if (bestFnCost != null) {
|
if (bestFnCost != null) {
|
||||||
comparison = currCost.compare(bestFnCost[bestFnCost.length - j]);
|
comparison = currCost.compare(bestFnCost[bestFnCost.length - j]);
|
||||||
|
@ -2116,13 +2113,13 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//If function has a parameter match that is better than the current best,
|
// If function has a parameter match that is better than the current best,
|
||||||
//and another that is worse (or everything was just as good, neither better nor worse).
|
// and another that is worse (or everything was just as good, neither better nor worse),
|
||||||
//then this is an ambiguity (unless we find something better than both later)
|
// then this is an ambiguity (unless we find something better than both later).
|
||||||
ambiguous |= (hasWorse && hasBetter) || (!hasWorse && !hasBetter);
|
ambiguous |= (hasWorse && hasBetter) || (!hasWorse && !hasBetter);
|
||||||
|
|
||||||
if (!hasWorse) {
|
if (!hasWorse) {
|
||||||
// if they are both template functions, we can order them that way
|
// If they are both template functions, we can order them that way
|
||||||
ICPPFunctionTemplate bestAsTemplate= asTemplate(bestFn);
|
ICPPFunctionTemplate bestAsTemplate= asTemplate(bestFn);
|
||||||
ICPPFunctionTemplate currAsTemplate= asTemplate(currFn);
|
ICPPFunctionTemplate currAsTemplate= asTemplate(currFn);
|
||||||
if (bestAsTemplate != null && currAsTemplate != null) {
|
if (bestAsTemplate != null && currAsTemplate != null) {
|
||||||
|
@ -2133,7 +2130,7 @@ public class CPPSemantics {
|
||||||
ambiguous = false;
|
ambiguous = false;
|
||||||
}
|
}
|
||||||
} else if (bestAsTemplate != null) {
|
} else if (bestAsTemplate != null) {
|
||||||
// we prefer normal functions over template functions, unless we specified template arguments
|
// We prefer normal functions over template functions, unless we specified template arguments
|
||||||
if (data.preferTemplateFunctions())
|
if (data.preferTemplateFunctions())
|
||||||
ambiguous = false;
|
ambiguous = false;
|
||||||
else
|
else
|
||||||
|
@ -2145,7 +2142,7 @@ public class CPPSemantics {
|
||||||
ambiguous = false;
|
ambiguous = false;
|
||||||
}
|
}
|
||||||
if (hasBetter) {
|
if (hasBetter) {
|
||||||
//the new best function.
|
// The new best function.
|
||||||
ambiguous = false;
|
ambiguous = false;
|
||||||
bestFnCost = currFnCost;
|
bestFnCost = currFnCost;
|
||||||
bestHasAmbiguousParam = currHasAmbiguousParam;
|
bestHasAmbiguousParam = currHasAmbiguousParam;
|
||||||
|
|
Loading…
Add table
Reference in a new issue