From 1dceabb0ebbf4ba8a6948c796fcd58fc0aa888f6 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Wed, 10 May 2017 03:52:30 -0400 Subject: [PATCH] Bug 516338 - Detect substitution failure during instantiation of dependent alias template arguments Change-Id: Ia97e0632e17b4047a0fe35c05be72dab75e43d5c --- .../parser/tests/ast2/AST2TemplateTests.java | 16 +++++++++++++ .../parser/cpp/semantics/CPPTemplates.java | 23 ++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) 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 47f4a66ef6a..8ea14a808a7 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 @@ public class AST2TemplateTests extends AST2CPPTestBase { parseAndCheckBindings(); } + // template + // using void_t = void; + // + // template + // struct Waldo { + // using type = T; + // }; + // + // template + // struct Waldo> {}; + // + // Waldo::type foo(); + public void testSFINAEInAliasTemplateArgs_516338() throws Exception { + parseAndCheckBindings(); + } + // template // 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 c21ff48da66..ee3cce19e77 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 @@ public class CPPTemplates { return type; } } - + if (type instanceof TypeOfUnknownMember) { IBinding binding = resolveUnknown(((TypeOfUnknownMember) type).getUnknownMember(), context); if (binding instanceof IType) { @@ -1592,6 +1592,27 @@ public class CPPTemplates { } } + // 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();