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 16 -> 17 regression: "deduced return type cannot be used before it is defined" #64029

Closed
helmesjo opened this issue Jul 22, 2023 · 7 comments
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" regression

Comments

@helmesjo
Copy link

helmesjo commented Jul 22, 2023

See minimal reproducer here (godbolt).

It works fine in Clang 16.0.0 (and older, tested back to 11.0), but fails in 17 (trunk).

@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" and removed new issue labels Jul 22, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Jul 22, 2023

@llvm/issue-subscribers-clang-frontend

@MitalAshok
Copy link
Contributor

This is broken by 0fd9c37

It compiles with -fno-builtin-std-forward_like.

This is not a regression because your code has undefined behaviour (you modify the std namespace). To do these "polyfills" safely, you need to do something like this:

namespace my_namespace {
#ifdef __cpp_lib_forward_like
    using std::forward_like;
#else
    // your definition for forward_like
#endif
}

Though I do agree the given warning is confusing, and might be a sign that the implementation of the builtin wouldn't work with a conforming library implementation of forward_like (though [forward]p8 seems to say the return type is not auto&&)

@helmesjo
Copy link
Author

helmesjo commented Jul 24, 2023

Thanks for the reply, and yes it's definitely UB but indeed the error message threw me off (I would expect it to complain about a redefinition). But then again, why isn't __cpp_lib_forward_like defined properly?

Edit.
Alright, got it. It's not fully implemented yet (AFAICT), and overall things are broken as soon as one puts stuff inside the std namespace so I reckon after that all bets are already off anyways.

@EugeneZelenko EugeneZelenko added the question A question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead! label Jul 25, 2023
@CaseyCarter
Copy link
Member

Reopening for reconsideration because https://github.com/microsoft/STL/blob/f98b286a17e7c72e3fa10297868b877f9cdc0fa8/stl/inc/utility#L930-L949 is "the implementation" =)

We can workaround the issue, but we'd rather not muss our nicely clean implementation. Is there any chance you folks will address this regression?

@CaseyCarter CaseyCarter reopened this Sep 7, 2023
@CaseyCarter CaseyCarter added regression and removed question A question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead! labels Sep 7, 2023
@cor3ntin
Copy link
Contributor

cor3ntin commented Sep 7, 2023

@CaseyCarter Could you do something like libc++ ?

[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto forward_like(_LIBCPP_LIFETIMEBOUND _Up&& __ux) noexcept

The issue only affects implements who use type deduction in forward-like
And I think it would be a non-trivial fix.
As best we might be able to not replace the call if the declaration has a deduced type, but you would not get the perf benefits

@zygoloid did that work so maybe he would have a better idea!

@zygoloid
Copy link
Collaborator

zygoloid commented Sep 7, 2023

As part of treating std::forward_like as a builtin, we no longer instantiate its definition when it's used. This is an important optimization, at least for std::forward and std::move (and likely for std::forward_like once it starts being adopted more heavily). But that means that if the return type is deduced, then we don't have a body to deduce it against.

So, we could change Clang to accept this implementation of forward_like, by instantiating a definition anyway in the case where the return type is deduced. That'd accept the MSVC stdlib implementation, but would mean that you get slower compiles (and potentially larger object files and more debug information depending on whether we manage to avoid emitting anything about the instantiated template specialization or not). Or the MSVC implementation could add an explicit return type, and our optimization could continue to function. Or we could make this case even-more-builtin, and ignore the return type declared in the standard library entirely and work it out for ourselves (either only if it's deduced, or always).

@CaseyCarter
Copy link
Member

I was hoping for "even-more-builtin" as a best case, but I admit the marginal benefit over the current optimization would be small. In any case, I've found a compromise that I think MSVC and Clang are equally happy with; let's close this issue again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" regression
Projects
None yet
Development

No branches or pull requests

7 participants