1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-03-28 14:56:28 +01:00

[#455] If constructor arguments fail to resolve, propagate failure (#456)

This change prevents invalid partial specialisations from being chosen
when
instantiating a template in cases where the expression for the
type/value of a template parameter involves a constructor call.
This commit is contained in:
Davin McCall 2023-12-29 08:13:35 +10:00 committed by GitHub
parent a7bfdd2802
commit be3a2eb539
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 0 deletions

View file

@ -6865,6 +6865,44 @@ public class AST2TemplateTests extends AST2CPPTestBase {
parseAndCheckBindings();
}
// template <class, typename = void>
// struct A
// {
// using type = int *;
// };
//
// template <class T>
// struct A<T, decltype(void(typename T::p()))>
// {
// using type = typename T::p;
// };
//
// class d { };
//
// class B {
// public:
// using p = typename A<d>::type;
//
// public:
// explicit B(p) {}
// };
//
// int *ip = nullptr;
// B b1 { ip };
// B::p jp = nullptr;
public void testSfinae_c() throws Exception {
BindingAssertionHelper bh = getAssertionHelper();
IVariable varB1 = bh.assertNonProblem("b1");
IType bcls = bh.assertNonProblem("B");
IVariable varJp = bh.assertNonProblem("jp");
IVariable varIp = bh.assertNonProblem("ip");
assertFalse(varB1.getInitialValue() instanceof IProblemBinding);
assertTrue(varB1.getType().isSameType(bcls));
assertTrue(varIp.getType().isSameType(varJp.getType()));
}
// template<typename T>
// struct is_pod {
// static const bool value = __is_pod(T);

View file

@ -218,6 +218,7 @@ import org.eclipse.cdt.internal.core.dom.parser.IRecursionResolvingBinding;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
@ -5067,6 +5068,8 @@ public class CPPSemantics {
*/
public static IType getDeclTypeForEvaluation(ICPPEvaluation eval) {
IType expressionType = eval.getType();
if (expressionType instanceof ProblemType)
return expressionType;
boolean namedEntity = eval instanceof EvalBinding || eval instanceof EvalMemberAccess;
if (!namedEntity && !(expressionType instanceof ICPPReferenceType)) {
switch (eval.getValueCategory()) {

View file

@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IProblemType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
@ -42,6 +43,7 @@ import org.eclipse.cdt.internal.core.dom.parser.CompositeValue;
import org.eclipse.cdt.internal.core.dom.parser.DependentValue;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
@ -416,6 +418,15 @@ public class EvalTypeId extends CPPDependentEvaluation {
if (args == fArguments && type == fInputType)
return this;
// If type or arguments failed to resolve, return INCOMPLETE for SFINAE purposes
if (type instanceof ProblemBinding)
return EvalFixed.INCOMPLETE;
for (ICPPEvaluation arg : args) {
if (arg.getType() instanceof IProblemType) {
return EvalFixed.INCOMPLETE;
}
}
EvalTypeId result = new EvalTypeId(type, getTemplateDefinition(), fRepresentsNewExpression, fUsesBracedInitList,
args);