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:
parent
432c3eaa04
commit
c22ccedea2
4 changed files with 45 additions and 18 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue