mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-21 21:52:10 +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();
|
||||
}
|
||||
|
||||
// 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 (&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.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||
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.ICPPFunction;
|
||||
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.ICPPSpecialization;
|
||||
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.internal.core.dom.parser.CompositeValue;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.DependentValue;
|
||||
|
@ -242,8 +245,20 @@ public final class EvalFunctionCall extends CPPDependentEvaluation {
|
|||
EvalFunctionSet functionSet = (EvalFunctionSet) args[0];
|
||||
args[0] = functionSet.resolveFunction(Arrays.copyOfRange(args, 1, args.length));
|
||||
|
||||
// Propagate instantiation errors for SFINAE purposes.
|
||||
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];
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue