Skip to content

missing check that deduction actually succeeded when partially ordering function templates #18291

Closed
@zygoloid

Description

@zygoloid
Bugzilla Link 17917
Version trunk
OS Linux
CC @DougGregor

Extended Description

Consider:

template<bool> struct enable_if { typedef void type; };
template <class T> class Foo {};
template <class X> constexpr bool check() { return true; }
template <class X, class Enable = void> struct Bar {};

#ifdef FUNCTION_ORDERING

template<class X> void func(Bar<X, typename enable_if<check<X>()>::type>) { }
template<class T> int func(Bar<Foo<T>>) {  return 0; }
int (*p)(Bar<Foo<int>>) = func;

#else

template<typename X> struct Bar<X, typename enable_if<check<X>()>::type> {};
template<typename X> struct Bar<Foo<X>> { typedef int type; };
Bar<Foo<int>>::type bar;

#endif

Per 14.5.5.2/1, the class template partial specialization partial ordering and the function template partial ordering above should behave exactly the same. But they don't: for clang, gcc, and edg, the FUNCTION_ORDERING case is accepted and the other (class ordering) case is rejected.

Morally, both cases should be rejected; this is ambiguous because the first template has the constraint that enable_if<check<X>()>::type == void, and the second template has the constraint that X == Foo<T> for some T. Clearly, neither of these implies the other.

Practically, we're missing a call to something like FinishTemplateArgumentDeduction in the FunctionTemplateDecl form of isAtLeastAsSpecializedAs: we fail to check that the deduction produces template arguments that make the deduced A compatible with the original A (as required by [temp.deduct.type]p1).

Metadata

Metadata

Assignees

Labels

bugzillaIssues migrated from bugzillac++clang:frontendLanguage frontend issues, e.g. anything involving "Sema"

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions