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

Erroneous if constexpr instantiation in lambda template #44851

Open
llvmbot opened this issue Apr 12, 2020 · 3 comments
Open

Erroneous if constexpr instantiation in lambda template #44851

llvmbot opened this issue Apr 12, 2020 · 3 comments
Labels
bugzilla Issues migrated from bugzilla c++17 clang:to-be-triaged Should not be used for new issues

Comments

@llvmbot
Copy link
Member

llvmbot commented Apr 12, 2020

Bugzilla Link 45506
Version trunk
OS All
Reporter LLVM Bugzilla Contributor
CC @hubert-reinterpretcast,@zygoloid

Extended Description

clang++ erroneously instantiates the if constexpr statement commented "pfft" below; g++ and VS2019 accept it on local consensus is that it is a clang++ bug:

#include <cstdint>
#include <type_traits>
#include <variant>
#include <iostream>

template <typename T>
T foo(const std::variant<int64_t, double, std::string>& v)
{
    T result;
    std::visit([&result](auto&& a)
    {
        typedef std::decay_t<decltype(a)> vt;
        if constexpr (std::is_same_v<vt, double>)
            result = static_cast<T>(a);
        else if constexpr (std::is_same_v<vt, int64_t>)
            result = static_cast<T>(a);
        else if constexpr (std::is_same_v<vt, std::string> && std::is_class_v<T>)
            result = T::from_string(a); // pfft
        else
            throw std::logic_error("wibble");
    }, v);
    return result;
}

int main()
{
    std::cout << foo<double>(int64_t{});
}
@hubert-reinterpretcast
Copy link
Collaborator

hubert-reinterpretcast commented Apr 12, 2020

Reduced:

template <typename T> int foo() {
  int ans;
  auto &&x = [&ans](auto a) {
    if constexpr (sizeof(double) != sizeof a)
      ans = sizeof(T::type);
  };
  x(0.);
  return ans;
}

int main() {
  foo<double>();
}

ICC produces an error similar to Clang's.
The question is whether or not instantiation of foo<double> needs to defer substitution into the subexpression of the constexpr-if or accept formation of impossible types.

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented Apr 13, 2020

This code is only valid after the resolution of http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0588r1.html, which Clang does not yet implement. Prior to that change, instantiation of a generic lambda in general requires full substitution into the body of the lambda in order to determine the set of captures.

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented Apr 13, 2020

Note, however, that P0588R1 was accepted into C++ as a defect report resolution, so Clang will apply it retroactively to all language modes when it is implemented.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
@Endilll Endilll changed the title Erroneous "if constexpr" instantiation in lambda template Erroneous if constexpr instantiation in lambda template Jul 19, 2024
@Endilll Endilll added the clang:to-be-triaged Should not be used for new issues label Jul 19, 2024
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++17 clang:to-be-triaged Should not be used for new issues
Projects
None yet
Development

No branches or pull requests

3 participants