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

Bug 430230 - Invalid constructor call is ignored by SFINAE template

resolution.
This commit is contained in:
Sergey Prigogin 2014-03-13 16:28:20 -07:00
parent d5db93891d
commit aa2ae49463
3 changed files with 110 additions and 10 deletions

View file

@ -7404,6 +7404,53 @@ public class AST2TemplateTests extends AST2TestBase {
parseAndCheckBindings();
}
// template<typename T, typename = decltype(T(0))>
// static void test(int);
//
// template<typename>
// static int test(...);
//
// struct A {};
//
// int waldo(int p);
//
// int x = waldo(test<A>(0));
public void testSfinaeInConstructorCall_430230() throws Exception {
parseAndCheckBindings();
}
// template<typename T, typename = decltype(new T(0))>
// static void test(int);
//
// template<typename>
// static int test(...);
//
// struct A {};
//
// int waldo(int p);
//
// int x = waldo(test<A>(0));
public void testSfinaeInNewExpression_430230() throws Exception {
parseAndCheckBindings();
}
// template<typename T, typename = decltype(new T)>
// static void test(int);
//
// template<typename>
// static int test(...);
//
// struct A {
// A() = delete;
// };
//
// int waldo(int p);
//
// int x = waldo(test<A>(0));
public void testSfinaeInNewExpressionWithDeletedConstructor_430230() throws Exception {
parseAndCheckBindings();
}
// template <typename>
// struct M {
// template <typename... Args>

View file

@ -31,16 +31,16 @@ import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTExpressionList;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
import org.eclipse.core.runtime.Assert;
@ -267,11 +267,19 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
IType t= CPPVisitor.createType(getTypeId());
IType t = CPPVisitor.createType(getTypeId());
if (t instanceof IArrayType) {
t= ((IArrayType) t).getType();
t = ((IArrayType) t).getType();
}
fEvaluation= new EvalFixed(new CPPPointerType(t), PRVALUE, Value.UNKNOWN);
ICPPEvaluation[] arguments = ICPPEvaluation.EMPTY_ARRAY;
if (initializer instanceof ICPPASTConstructorInitializer) {
IASTInitializerClause[] args = ((ICPPASTConstructorInitializer) initializer).getArguments();
arguments= new ICPPEvaluation[args.length];
for (int i = 0; i < arguments.length; i++) {
arguments[i] = ((ICPPASTInitializerClause) args[i]).getEvaluation();
}
}
fEvaluation = EvalTypeId.createForNewExpression(t, this, arguments);
}
return fEvaluation;
}

View file

@ -14,17 +14,23 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromReturnType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
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.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException;
@ -34,19 +40,29 @@ import org.eclipse.core.runtime.CoreException;
public class EvalTypeId extends CPPDependentEvaluation {
private final IType fInputType;
private final ICPPEvaluation[] fArguments;
private final boolean fRepresentsNewExpression;
private IType fOutputType;
public EvalTypeId(IType type, IASTNode pointOfDefinition, ICPPEvaluation... arguments) {
this(type, findEnclosingTemplate(pointOfDefinition), arguments);
this(type, findEnclosingTemplate(pointOfDefinition), false, arguments);
}
public EvalTypeId(IType type, IBinding templateDefinition, ICPPEvaluation... arguments) {
this(type, templateDefinition, false, arguments);
}
private EvalTypeId(IType type, IBinding templateDefinition, boolean forNewExpression, ICPPEvaluation... arguments) {
super(templateDefinition);
if (arguments == null)
throw new NullPointerException("arguments"); //$NON-NLS-1$
fInputType= type;
fArguments= arguments;
fRepresentsNewExpression = forNewExpression;
}
public static EvalTypeId createForNewExpression(IType type, IASTNode pointOfDefinition, ICPPEvaluation... arguments) {
return new EvalTypeId(type, findEnclosingTemplate(pointOfDefinition), true, arguments);
}
public IType getInputType() {
@ -78,7 +94,11 @@ public class EvalTypeId extends CPPDependentEvaluation {
private IType computeType() {
if (CPPTemplates.isDependentType(fInputType))
return new TypeOfDependentExpression(this);
return typeFromReturnType(fInputType);
IType type = typeFromReturnType(fInputType);
if (fRepresentsNewExpression)
return new CPPPointerType(type);
return type;
}
@Override
@ -87,6 +107,8 @@ public class EvalTypeId extends CPPDependentEvaluation {
return Value.create(this);
if (isTypeDependent())
return Value.create(this);
if (fRepresentsNewExpression)
return Value.UNKNOWN;
if (fOutputType instanceof ICPPClassType) {
// TODO(sprigogin): Simulate execution of a ctor call.
return Value.UNKNOWN;
@ -123,6 +145,8 @@ public class EvalTypeId extends CPPDependentEvaluation {
short firstBytes = ITypeMarshalBuffer.EVAL_TYPE_ID;
if (includeValue)
firstBytes |= ITypeMarshalBuffer.FLAG1;
if (fRepresentsNewExpression)
firstBytes |= ITypeMarshalBuffer.FLAG2;
buffer.putShort(firstBytes);
buffer.marshalType(fInputType);
@ -149,7 +173,8 @@ public class EvalTypeId extends CPPDependentEvaluation {
args = ICPPEvaluation.EMPTY_ARRAY; // arguments must not be null
}
IBinding templateDefinition= buffer.unmarshalBinding();
return new EvalTypeId(type, templateDefinition, args);
boolean forNewExpression = (firstBytes & ITypeMarshalBuffer.FLAG2) != 0;
return new EvalTypeId(type, templateDefinition, forNewExpression, args);
}
@Override
@ -159,7 +184,27 @@ public class EvalTypeId extends CPPDependentEvaluation {
IType type = CPPTemplates.instantiateType(fInputType, tpMap, packOffset, within, point);
if (args == fArguments && type == fInputType)
return this;
return new EvalTypeId(type, getTemplateDefinition(), args);
if (!CPPTemplates.isDependentType(type) && type instanceof ICPPClassType) {
// Check the constructor call and return EvalFixed.INCOMPLETE to indicate a substitution
// failure if the call cannot be resolved.
ICPPClassType classType = (ICPPClassType) type;
LookupData data = new LookupData(classType.getNameCharArray(), null, point);
ICPPConstructor[] constructors = classType.getConstructors();
data.foundItems = constructors;
data.setFunctionArguments(false, fArguments);
try {
IBinding binding = CPPSemantics.resolveFunction(data, constructors, true);
if (binding == null || binding instanceof IProblemBinding ||
binding instanceof ICPPFunction && ((ICPPFunction) binding).isDeleted()) {
return EvalFixed.INCOMPLETE;
}
} catch (DOMException e) {
CCorePlugin.log(e);
return EvalFixed.INCOMPLETE;
}
}
return new EvalTypeId(type, getTemplateDefinition(), fRepresentsNewExpression, args);
}
@Override
@ -178,7 +223,7 @@ public class EvalTypeId extends CPPDependentEvaluation {
}
if (args == fArguments)
return this;
return new EvalTypeId(fInputType, getTemplateDefinition(), args);
return new EvalTypeId(fInputType, getTemplateDefinition(), fRepresentsNewExpression, args);
}
@Override