mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-03-28 14:56:28 +01:00
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:
parent
a7bfdd2802
commit
be3a2eb539
3 changed files with 52 additions and 0 deletions
|
@ -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);
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue