1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Bug 512932 - Check for standard conversions in CPPEvaluation.maybeApplyConversion()

Previously, we would just assume that if there is no user-defined
conversion involved, the evaluation successfully converts to the target
type.

This increased strictness exposed a couple of other bugs related to
evaluations, which are also fixed in this patch.

Change-Id: I8c40114da341d95b38f1ecc386e875badfe9f8c6
This commit is contained in:
Nathan Ridge 2017-05-01 03:01:11 -04:00
parent 432c3eaa04
commit c22ccedea2
4 changed files with 45 additions and 18 deletions

View file

@ -10227,4 +10227,19 @@ public class AST2TemplateTests extends AST2TestBase {
public void testDelegatingConstructorInPartialSpecialization_512932() throws Exception {
parseAndCheckBindings();
}
// enum class E { F };
//
// template <unsigned char>
// void foo();
//
// template <E>
// void foo();
//
// int main() {
// foo<E::F>(); // error here
// }
public void testOverloadingOnTypeOfNonTypeTemplateParameter_512932() throws Exception {
parseAndCheckBindings();
}
}

View file

@ -299,10 +299,6 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
}
private IType getStringType() {
if (fSuffix.length > 0) {
return getUserDefinedLiteralOperatorType();
}
IType type = new CPPBasicType(getBasicCharKind(), 0, this);
type = new CPPQualifierType(type, true, false);
return new CPPArrayType(type, getStringLiteralSize());

View file

@ -29,6 +29,8 @@ import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode;
import org.eclipse.core.runtime.CoreException;
public abstract class CPPEvaluation implements ICPPEvaluation {
@ -157,24 +159,37 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
protected static ICPPEvaluation maybeApplyConversion(ICPPEvaluation argument, IType targetType,
IASTNode point, boolean allowContextualConversion) {
IType type = argument.getType(point);
// Types match - don't bother to check for conversions.
if (targetType.isSameType(type)) {
return argument;
}
try {
// Source type is class type - check for conversion operator.
IType uqType= SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
ValueCategory valueCategory = argument.getValueCategory(point);
ICPPFunction conversion = null;
if (uqType instanceof ICPPClassType) {
try {
Cost cost = Conversions.initializationByConversion(valueCategory, type, (ICPPClassType) uqType,
targetType, false, point, allowContextualConversion);
conversion = cost.getUserDefinedConversion();
} catch (DOMException e) {
CCorePlugin.log(e);
}
}
ICPPFunction conversion = cost.getUserDefinedConversion();
if (conversion != null) {
if (!conversion.isConstexpr()) {
return EvalFixed.INCOMPLETE;
}
ICPPEvaluation eval = new EvalMemberAccess(uqType, valueCategory, conversion, argument, false, point);
argument = new EvalFunctionCall(new ICPPEvaluation[] { eval }, null, (IBinding) null);
return new EvalFunctionCall(new ICPPEvaluation[] { eval }, null, (IBinding) null);
}
}
// Source type is not a class type, or is but a conversion operator wasn't used.
// Check for standard conversions.
if (!Conversions.checkImplicitConversionSequence(targetType, type, valueCategory, UDCMode.FORBIDDEN,
Context.ORDINARY, point).converts()) {
return EvalFixed.INCOMPLETE;
}
} catch (DOMException e) {
CCorePlugin.log(e);
}
return argument;
}

View file

@ -110,7 +110,8 @@ public class EvalReference extends CPPDependentEvaluation {
@Override
public ValueCategory getValueCategory(IASTNode point) {
return getTargetEvaluation().getValueCategory(point);
// An EvalReference always refers to a named variable, so its value category is lvalue.
return ValueCategory.LVALUE;
}
@Override