From f9f94676a2a87cdf5759d3a3d89eccbb7e84119b Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Sun, 3 Mar 2013 19:59:26 -0500 Subject: [PATCH] Bug 402257 - Incorrect overload resolution with SFINAE and nested types Change-Id: Id97160bcccaa0daaa7eaeab965cc74fe816adef5 Reviewed-on: https://git.eclipse.org/r/10811 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../parser/tests/ast2/AST2TemplateTests.java | 27 ++++++++++++++++++- .../parser/cpp/semantics/CPPTemplates.java | 6 +++-- 2 files changed, 30 insertions(+), 3 deletions(-) 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 0028d9645d0..c6e89eeb5a7 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 @@ -6945,7 +6945,32 @@ public class AST2TemplateTests extends AST2TestBase { public void testSFINAEInDefaultArgument() throws Exception { parseAndCheckBindings(); } - + + // typedef char (&no_tag)[1]; + // typedef char (&yes_tag)[2]; + // + // template + // struct type_wrapper {}; + // + // template + // struct has_type { + // template + // static yes_tag test(type_wrapper const volatile*, type_wrapper* = 0); + // + // static no_tag test(...); + // + // static const bool value = sizeof(test(static_cast*>(0))) == sizeof(yes_tag); + // }; + // + // const bool B = has_type::value; + public void testSFINAEInNestedTypeInTemplateArgument_402257() throws Exception { + BindingAssertionHelper helper = new BindingAssertionHelper(getAboveComment(), true); + ICPPVariable B = helper.assertNonProblem("B", ICPPVariable.class); + Long val = B.getInitialValue().numericalValue(); + assertNotNull(val); + assertEquals(0 /* false */, val.longValue()); + } + // template // struct M { // template 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 4650cc7183f..29ab1ac1b4c 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 @@ -2618,16 +2618,18 @@ public class CPPTemplates { private static IBinding resolveDeferredClassInstance(ICPPDeferredClassInstance dci, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) { + ICPPClassTemplate classTemplate = dci.getClassTemplate(); ICPPTemplateArgument[] arguments = dci.getTemplateArguments(); ICPPTemplateArgument[] newArgs; try { - newArgs = instantiateArguments(arguments, tpMap, packOffset, within, point, false); + newArgs = instantiateArguments(arguments, tpMap, packOffset, within, point, true); } catch (DOMException e) { return e.getProblem(); } + if (newArgs == null) + return createProblem(classTemplate, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, point); boolean changed= arguments != newArgs; - ICPPClassTemplate classTemplate = dci.getClassTemplate(); IType classTemplateSpecialization= instantiateType(classTemplate, tpMap, packOffset, within, point); if (classTemplateSpecialization != classTemplate && classTemplateSpecialization instanceof ICPPClassTemplate) { classTemplate= (ICPPClassTemplate) classTemplateSpecialization;