Bug 516338 - Detect substitution failure during instantiation of dependent alias template arguments
Change-Id: Ia97e0632e17b4047a0fe35c05be72dab75e43d5c
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
index 47f4a66..8ea14a8 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
@@ -10131,6 +10131,22 @@
parseAndCheckBindings();
}
+ // template <typename>
+ // using void_t = void;
+ //
+ // template <typename T, typename = void>
+ // struct Waldo {
+ // using type = T;
+ // };
+ //
+ // template <typename T>
+ // struct Waldo<T, void_t<typename T::type>> {};
+ //
+ // Waldo<int>::type foo();
+ public void testSFINAEInAliasTemplateArgs_516338() throws Exception {
+ parseAndCheckBindings();
+ }
+
// template <typename, typename>
// struct is_same {
// static constexpr bool value = false;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
index c21ff48..ee3cce1 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
@@ -1536,7 +1536,7 @@
return type;
}
}
-
+
if (type instanceof TypeOfUnknownMember) {
IBinding binding = resolveUnknown(((TypeOfUnknownMember) type).getUnknownMember(), context);
if (binding instanceof IType) {
@@ -1592,6 +1592,27 @@
}
}
+ // An alias template instance may have dependent arguments that don't contribute
+ // to the target type but can SFINAE out during instantiation, so it's not
+ // sufficient to handle it in the ITypeContainer case.
+ if (type instanceof ICPPAliasTemplateInstance) {
+ ICPPAliasTemplateInstance instance = (ICPPAliasTemplateInstance) type;
+ ICPPAliasTemplate template = instance.getTemplateDefinition();
+ ICPPTemplateArgument[] args = instance.getTemplateArguments();
+ ICPPTemplateArgument[] newArgs = instantiateArguments(args, context, true);
+ if (newArgs == null) {
+ return (IType) createProblem(template,
+ IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, context.getPoint());
+ }
+ if (args != newArgs) {
+ IType target = instantiateType(instance.getType(), context);
+ CPPTemplateParameterMap map =
+ instantiateArgumentMap(instance.getTemplateParameterMap(), context);
+ return new CPPAliasTemplateInstance(template, target, instance.getOwner(), map, newArgs);
+ }
+ return type;
+ }
+
if (type instanceof ITypeContainer) {
final ITypeContainer typeContainer = (ITypeContainer) type;
IType nestedType = typeContainer.getType();