mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 06:02:11 +02:00
Do not error out failing to resolve function in dependend context
Detect if function set failed to resolve while instantiating for template-id which still has dependend arguments. Since resolution still can succeed later via ADL when template-id is fully instantiated, do not error out immediately and return original evaluation to allow trying to instantiate later.
This commit is contained in:
parent
47275c3884
commit
385b915257
2 changed files with 44 additions and 1 deletions
|
@ -8052,6 +8052,34 @@ public class AST2TemplateTests extends AST2CPPTestBase {
|
||||||
parseAndCheckBindings();
|
parseAndCheckBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// namespace std {
|
||||||
|
// template<typename _Tp, typename _Up = _Tp&&> _Up __declval(int);
|
||||||
|
// template<typename _Tp> _Tp __declval(long);
|
||||||
|
// template<typename _Tp> auto declval() noexcept -> decltype(__declval<_Tp>(0));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// template <typename T>
|
||||||
|
// using is_augmented_t = decltype (is_augmented (std::declval<T *> ()));
|
||||||
|
//
|
||||||
|
// template <typename T, typename = is_augmented_t<T>>
|
||||||
|
// constexpr T f(T x) { return x; }
|
||||||
|
//
|
||||||
|
// template <typename T, typename = is_augmented_t<T>>
|
||||||
|
// constexpr T g(T x) { return x; }
|
||||||
|
//
|
||||||
|
// enum E { E1 = 42 };
|
||||||
|
// void is_augmented(E *);
|
||||||
|
//
|
||||||
|
// void is_augmented(int *);
|
||||||
|
//
|
||||||
|
// constexpr int value_via_adl = f(E1); // ADL via enumeration argument finds is_augmented(E*)
|
||||||
|
// constexpr int value_no_adl = g(int(E1)); // Error: no ADL performed, is_augmented(int*) is not found
|
||||||
|
public void testSfinaeInDependentContext() throws Exception {
|
||||||
|
BindingAssertionHelper bh = getAssertionHelper();
|
||||||
|
bh.assertVariableValue("value_via_adl", 42);
|
||||||
|
bh.assertProblem("g(int(E1))", 1);
|
||||||
|
}
|
||||||
|
|
||||||
// typedef char (&no_tag)[1];
|
// typedef char (&no_tag)[1];
|
||||||
// typedef char (&yes_tag)[2];
|
// typedef char (&yes_tag)[2];
|
||||||
//
|
//
|
||||||
|
|
|
@ -25,12 +25,14 @@ import java.util.Arrays;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IValue;
|
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||||
|
@ -39,6 +41,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.CompositeValue;
|
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.DependentValue;
|
||||||
|
@ -242,8 +245,20 @@ public final class EvalFunctionCall extends CPPDependentEvaluation {
|
||||||
EvalFunctionSet functionSet = (EvalFunctionSet) args[0];
|
EvalFunctionSet functionSet = (EvalFunctionSet) args[0];
|
||||||
args[0] = functionSet.resolveFunction(Arrays.copyOfRange(args, 1, args.length));
|
args[0] = functionSet.resolveFunction(Arrays.copyOfRange(args, 1, args.length));
|
||||||
|
|
||||||
// Propagate instantiation errors for SFINAE purposes.
|
|
||||||
if (args[0] == EvalFixed.INCOMPLETE) {
|
if (args[0] == EvalFixed.INCOMPLETE) {
|
||||||
|
// Do not error if instantiation context is still a dependent template-id,
|
||||||
|
// as function set can still be resolved later via ADL.
|
||||||
|
if (CPPSemantics.getCurrentLookupPoint() instanceof ICPPASTTemplateId templateId) {
|
||||||
|
for (IASTNode argument : templateId.getTemplateArguments()) {
|
||||||
|
if (argument instanceof IASTTypeId typeId) {
|
||||||
|
if (CPPVisitor.createType(typeId) instanceof ICPPTemplateParameter) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Propagate instantiation errors for SFINAE purposes.
|
||||||
return args[0];
|
return args[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue