1
0
Fork 0
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:
Igor V. Kovalenko 2023-03-27 02:36:22 +03:00 committed by Jonah Graham
parent 47275c3884
commit 385b915257
2 changed files with 44 additions and 1 deletions

View file

@ -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];
//

View file

@ -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];
}