Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
zygoloid mannequin opened this issue Nov 13, 2013 · 1 comment · Fixed by #100692
Closed

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

zygoloid mannequin opened this issue Nov 13, 2013 · 1 comment · Fixed by #100692
Assignees
Labels
bugzilla Issues migrated from bugzilla c++ clang:frontend Language frontend issues, e.g. anything involving "Sema"

Comments

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented Nov 13, 2013

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).

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 9, 2021
@mizvekov mizvekov self-assigned this Jul 25, 2024
mizvekov added a commit that referenced this issue Jul 26, 2024
…mplates

This makes partial ordering of function templates consistent with
other entities.

Fixes #18291
mizvekov added a commit that referenced this issue Jul 26, 2024
…mplates

This makes partial ordering of function templates consistent with
other entities.

Fixes #18291
mizvekov added a commit that referenced this issue Jul 26, 2024
…mplates

This makes partial ordering of function templates consistent with
other entities.

Fixes #18291
mizvekov added a commit that referenced this issue Jul 26, 2024
…mplates

This makes partial ordering of function templates consistent with
other entities.

Fixes #18291
mizvekov added a commit that referenced this issue Jul 27, 2024
…mplates

This makes partial ordering of function templates consistent with
other entities.

Fixes #18291
mizvekov added a commit that referenced this issue Jul 27, 2024
…mplates

This makes partial ordering of function templates consistent with
other entities.

Fixes #18291
@Endilll Endilll added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Jul 27, 2024
@llvmbot
Copy link
Member

llvmbot commented Jul 27, 2024

@llvm/issue-subscribers-clang-frontend

Author: None (ec04fc15-fa35-46f2-80e1-5d271f2ef708)

| | | | --- | --- | | Bugzilla Link | [17917](https://llvm.org/bz17917) | | Version | trunk | | OS | Linux | | CC | @DougGregor |

Extended Description

Consider:

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

#ifdef FUNCTION_ORDERING

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

#else

template&lt;typename X&gt; struct Bar&lt;X, typename enable_if&lt;check&lt;X&gt;()&gt;::type&gt; {};
template&lt;typename X&gt; struct Bar&lt;Foo&lt;X&gt;&gt; { typedef int type; };
Bar&lt;Foo&lt;int&gt;&gt;::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&lt;check&lt;X&gt;()&gt;::type == void, and the second template has the constraint that X == Foo&lt;T&gt; 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).

mizvekov added a commit that referenced this issue Jul 28, 2024
…mplates

This makes partial ordering of function templates consistent with
other entities.

Fixes #18291
mizvekov added a commit that referenced this issue Aug 5, 2024
…mplates

This makes partial ordering of function templates consistent with
other entities.

Fixes #18291
mizvekov added a commit that referenced this issue Aug 20, 2024
…mplates

This makes partial ordering of function templates consistent with
other entities.

Fixes #18291
mizvekov added a commit that referenced this issue Aug 25, 2024
…mplates

This makes partial ordering of function templates consistent with
other entities.

Fixes #18291
mizvekov added a commit that referenced this issue Aug 28, 2024
…mplates (#100692)

This makes partial ordering of function templates consistent with other
entities, by implementing [temp.deduct.type]p1 in that case.

Fixes #18291
mizvekov added a commit that referenced this issue Sep 10, 2024
This fixes a bug in #18291, that was reported in the PR.

Since this is a bug fix for a patch that was never released, no
entries are added to the changelog.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla c++ clang:frontend Language frontend issues, e.g. anything involving "Sema"
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants