| Issue |
176023
|
| Summary |
[clang] Incorrect template instantiation for generic lambda with explicit trailing return type inside std::visit
|
| Labels |
|
| Assignees |
|
| Reporter |
Phibonoci
|
Clang fails to instantiate required template code when a templated derived class is returned as std::shared_ptr to a polymorphic base as trailing return type from within a lambda called in std::visit. Only the constructors of the derived type and std::shared_ptr appear to be instantiated; other required functions (including virtual overrides and std::shared_ptr members) are not generated.
**Minimal Reproduction** https://godbolt.org/z/WvWcYr5sa
```c++
#include <memory>
#include <variant>
struct Virtual {
virtual ~Virtual() = default;
virtual void Do() = 0;
};
template<class T>
struct Base : public Virtual {
void Do() override {}
};
using VirtualPtr = std::shared_ptr<Virtual>;
struct Test {
static VirtualPtr Make(auto some_variant) {
auto maker = [&](const auto& value) -> VirtualPtr {
return std::make_shared<Base<std::decay_t<decltype(value)>>>();
};
return std::visit([&](const auto& value) {
return maker(value);
}, some_variant);
}
};
int main() {
Test::Make(std::variant<int>{0})->Do();
}
```
**Workaround**
If the explicit trailing return type of maker is removed, Clang instantiate required function: https://godbolt.org/z/bTG3qGeqY
**Additional Notes**
* The issue does not reproduce if std::visit is removed.
* The issue does not reproduce if the trailing return type is omitted or set to auto.
* GCC generate the expected code in both cases.
* The issue is reproducible with Clang 15.
* The C++ standard includes the following note regarding instantiations of generic lambdas (ยง7.5.5.2.10):
```
Note 4:
If the generic lambda has no trailing-return-type or the trailing-return-type contains a placeholder type, return type deduction of the corresponding function call operator template specialization has to be done. The corresponding specialization is that instantiation of the function call operator template with the same template arguments as those deduced for the conversion function template.
```
Clang may be interpreting this rule too strictly and treating the absence of a placeholder in the trailing return type as a possible reason to skip instantiation completely.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs