Skip to content
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

[Clang][concepts] Conditional explicit specifier is checked too early in constrained constructor #59827

Closed
JMazurkiewicz opened this issue Jan 4, 2023 · 9 comments · Fixed by #70548
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts

Comments

@JMazurkiewicz
Copy link
Contributor

JMazurkiewicz commented Jan 4, 2023

Repro (3rd version, 2nd version reproduced other possible bug; see edit history):

template<class X>
constexpr X failure() {
    return nullptr;
}

struct T {
    template<class X>
        requires false
    constexpr explicit(failure<X>()) T(X) { }

    T(int) { }
};

static T t(5);

Expected: correct compilation

Got:

<source>:3:12: error: cannot initialize return object of type 'int' with an rvalue of type 'std::nullptr_t'
    return nullptr;
           ^~~~~~~
<source>:9:24: note: in instantiation of function template specialization 'failure<int>' requested here
    constexpr explicit(failure<X>()) T(X) { }
                       ^
<source>:14:10: note: while substituting deduced template arguments into function template 'T' [with X = int]
static T t(5);
         ^

Compiler explorer: https://godbolt.org/z/sPsGh46Gs
Discovered in: microsoft/STL#3323

@EugeneZelenko EugeneZelenko added c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts and removed new issue labels Jan 4, 2023
@llvmbot
Copy link
Member

llvmbot commented Jan 4, 2023

@llvm/issue-subscribers-c-20

@llvmbot
Copy link
Member

llvmbot commented Jan 4, 2023

@llvm/issue-subscribers-clang-frontend

JMazurkiewicz added a commit to JMazurkiewicz/STL that referenced this issue Jan 4, 2023
@CaseyCarter
Copy link
Member

CaseyCarter commented Jan 8, 2023

I believe the key wording here is [over.match.funcs.general]/8: "... If a constructor template or conversion function template has an explicit-specifier whose constant-expression is value-dependent ([temp.dep]), template argument deduction is performed first and then, if the context admits only candidates that are not explicit and the generated specialization is explicit ([dcl.fct.spec]), it will be removed from the candidate set. ..."

Also, I think the repro could be a bit cleaner (https://godbolt.org/z/sszb5z5ha):

template<class> constexpr bool always_false = false;

template<class T> concept False = always_false<T>;

template<class X>
constexpr bool do_not_instantiate() {
    static_assert(always_false<X>);
    return true;
}

struct T {
    template<False X>
    explicit(do_not_instantiate<X>()) T(X) { }

    T(int) { }
};

T t(5);
  • requires false smells like IF-NDR, best to avoid it
  • static is extraneous, as is constexpr on the constructor
  • the expression in the explicit-specifier correctly has type bool after substitution.

@nitnelave
Copy link

Note that it makes clang-17 unable to compile a lot of code with the libstdc++ distributed with GCC 13. You can reproduce by trying to compile std::is_constructible<std::tuple<int>, std::tuple<>> (root cause is the same)

@shafik
Copy link
Collaborator

shafik commented Oct 24, 2023

CC @erichkeane

@LYP951018
Copy link
Contributor

LYP951018 commented Oct 27, 2023

i've been hacking on this weeks ago. Currently I partially instantiate the constructor decl (without instantiate the explicit specifier) and mutate the AST via setExplicitSpecifier after deferred instantiation of explicit speciifer during template argument deduction. Is that reansonable? I want to ensure the decl specialization have resolved explicit specifier... Could you please give me some advice on this? @erichkeane ;)

@erichkeane
Copy link
Collaborator

I think that seams reasonable. I believe there is a version of the exception specifier 'storage' that allows us to have uninstantiated exception specifiers in place, and I think we should be able to use that. It might 'just work' after that, since i think later lookups/uses of these check and instantiate that.

@LYP951018
Copy link
Contributor

This issue is about explicit specifier but not exception specifier. Did I miss anything here?

@erichkeane
Copy link
Collaborator

This issue is about explicit specifier but not exception specifier. Did I miss anything here?

Woops, nope, I think I did. I don't have a good idea here unfortunately on how to give advise then, but what you said in your post at least seems promising.

erichkeane added a commit that referenced this issue Nov 1, 2023
…t checking completes (#70548)

Modifications:

- Skip the instantiation of the explicit-specifier during Decl
substitution if we are deducing template arguments and the
explicit-specifier is value dependent.

- Instantiate the explicit-specifier after the constraint checking
completes.

- Make `instantiateExplicitSpecifier` a member function in order to
instantiate the explicit-specifier in different stages.


This PR doesn’t defer the instantiation of the explicit specifier for
deduction guides, because I’m not familiar with deduction guides yet.
I’ll dig into it after this PR.

According to my local test, GCC 13 tuple works with this PR.

Fixes #59827.

---------

Co-authored-by: Erich Keane <[email protected]>
krwalker pushed a commit to krwalker/llvm-project that referenced this issue Nov 14, 2023
…t checking completes (llvm#70548)

Modifications:

- Skip the instantiation of the explicit-specifier during Decl
substitution if we are deducing template arguments and the
explicit-specifier is value dependent.

- Instantiate the explicit-specifier after the constraint checking
completes.

- Make `instantiateExplicitSpecifier` a member function in order to
instantiate the explicit-specifier in different stages.

This PR doesn’t defer the instantiation of the explicit specifier for
deduction guides, because I’m not familiar with deduction guides yet.
I’ll dig into it after this PR.

According to my local test, GCC 13 tuple works with this PR.

Fixes llvm#59827.

---------

Co-authored-by: Erich Keane <[email protected]>
tchaikov added a commit to tchaikov/seastar that referenced this issue Jan 26, 2024
to address the build failure caused by
llvm/llvm-project#59827, and to test
the build with C++23, we need to use clang-18. which will be
released in March 2023.

Signed-off-by: Kefu Chai <[email protected]>
tchaikov added a commit to tchaikov/seastar that referenced this issue Jan 27, 2024
to address the build failure caused by
llvm/llvm-project#59827, and to test
the build with C++23, we need to use clang-18. which will be
released in March 2023.

Signed-off-by: Kefu Chai <[email protected]>
avikivity pushed a commit to avikivity/seastar that referenced this issue Feb 1, 2024
to address the build failure caused by
llvm/llvm-project#59827, and to test
the build with C++23, we need to use clang-18. which will be
released in March 2023.

Signed-off-by: Kefu Chai <[email protected]>

Closes scylladb#2058

[avi: regenerate toolchain]
tchaikov added a commit to tchaikov/seastar that referenced this issue Feb 1, 2024
to address the build failure caused by
llvm/llvm-project#59827, and to test
the build with C++23, we need to use clang-18. which will be
released in March 2023.

since we now install `clang-tools-18`, circleci is updated to
build C++20 module with clang-18. as clang-tools-18 provides
clang-scan-deps.

Signed-off-by: Kefu Chai <[email protected]>

Closes scylladb#2058

[avi: regenerate toolchain]
tchaikov added a commit to tchaikov/seastar that referenced this issue Feb 1, 2024
to address the build failure caused by
llvm/llvm-project#59827, and to test
the build with C++23, we need to use clang-18. which will be
released in March 2023.

since we now install `clang-tools-18`, circleci is updated to
build C++20 module with clang-18. as clang-tools-18 provides
clang-scan-deps.

Signed-off-by: Kefu Chai <[email protected]>

Closes scylladb#2058

[avi: regenerate toolchain]
tchaikov added a commit to tchaikov/seastar that referenced this issue Feb 1, 2024
to address the build failure caused by
llvm/llvm-project#59827, and to test
the build with C++23, we need to use clang-18. which will be
released in March 2023.

Signed-off-by: Kefu Chai <[email protected]>
tchaikov added a commit to tchaikov/seastar that referenced this issue Feb 1, 2024
to address the build failure caused by
llvm/llvm-project#59827, and to test
the build with C++23, we need to use clang-18. which will be
released in March 2023.

since we now install `clang-tools-18`, circleci is updated to
build C++20 module with clang-18. as clang-tools-18 provides
clang-scan-deps.

Signed-off-by: Kefu Chai <[email protected]>

Closes scylladb#2058

[avi: regenerate toolchain]
tchaikov added a commit to tchaikov/seastar that referenced this issue Feb 2, 2024
to address the build failure caused by
llvm/llvm-project#59827, and to test
the build with C++23, we need to use clang-18. which will be
released in March 2023.

Signed-off-by: Kefu Chai <[email protected]>
tchaikov added a commit to tchaikov/seastar that referenced this issue Feb 5, 2024
to address the build failure caused by
llvm/llvm-project#59827, and to test
the build with C++23, we need to use clang-18. which will be
released in March 2023.

since we now install `clang-tools-18`, circleci is updated to
build C++20 module with clang-18. as clang-tools-18 provides
clang-scan-deps.

Signed-off-by: Kefu Chai <[email protected]>

Closes scylladb#2058

[avi: regenerate toolchain]
avikivity pushed a commit to scylladb/seastar that referenced this issue Feb 11, 2024
to address the build failure caused by
llvm/llvm-project#59827, and to test
the build with C++23, we need to use clang-18. which will be
released in March 2023.

since we now install `clang-tools-18`, circleci is updated to
build C++20 module with clang-18. as clang-tools-18 provides
clang-scan-deps.

Signed-off-by: Kefu Chai <[email protected]>

Closes #2058

[avi: regenerate toolchain]
graphcareful pushed a commit to graphcareful/seastar that referenced this issue Mar 20, 2024
to address the build failure caused by
llvm/llvm-project#59827, and to test
the build with C++23, we need to use clang-18. which will be
released in March 2023.

since we now install `clang-tools-18`, circleci is updated to
build C++20 module with clang-18. as clang-tools-18 provides
clang-scan-deps.

Signed-off-by: Kefu Chai <[email protected]>

Closes scylladb#2058

[avi: regenerate toolchain]
Flamefire added a commit to Flamefire/bimap that referenced this issue Dec 9, 2024
There is a bug with libstdc++13 in 24.04: llvm/llvm-project#59827
Flamefire added a commit to Flamefire/chrono that referenced this issue Dec 9, 2024
There is a bug with libstdc++13 in 24.04: llvm/llvm-project#59827
Flamefire added a commit to Flamefire/bimap that referenced this issue Dec 10, 2024
There is a bug with libstdc++13 in 24.04: llvm/llvm-project#59827
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts
Projects
Status: Done
8 participants