Commit 068d3f6e authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

Fix is_constexpr_default_constructible under clang-10

Summary: [Folly] Fix `is_constexpr_default_constructible` under clang-10, which suffers a crash (https://bugs.llvm.org/show_bug.cgi?id=47620) and divergent behavior in certain constexpr evaluations.

Reviewed By: mpark, Mizuchi

Differential Revision: D24302661

fbshipit-source-id: b6a58b5b675f367bf2dc1d810edb9926cfb87a2e
parent 7c4ac999
...@@ -81,7 +81,19 @@ struct is_similar_instantiation ...@@ -81,7 +81,19 @@ struct is_similar_instantiation
namespace detail { namespace detail {
struct is_constexpr_default_constructible_ { struct is_constexpr_default_constructible_ {
template <typename T, int = (void(T()), 0)> template <typename T>
static constexpr auto make(tag_t<T>) -> decltype(void(T()), 0) {
return (void(T()), 0);
}
// second param should just be: int = (void(T()), 0)
// but under clang 10, crash: https://bugs.llvm.org/show_bug.cgi?id=47620
// and, with assertions disabled, expectation failures showing compiler
// deviation from the language spec
// xcode renumbers clang versions so detection is tricky, but, if detection
// were desired, a combination of __apple_build_version__ and __clang_major__
// may be used to reduce frontend overhead under correct compilers: clang 12
// under xcode and clang 10 otherwise
template <typename T, int = make(tag<T>)>
static std::true_type sfinae(T*); static std::true_type sfinae(T*);
static std::false_type sfinae(void*); static std::false_type sfinae(void*);
template <typename T> template <typename T>
......
...@@ -469,16 +469,11 @@ TEST(Traits, is_constexpr_default_constructible) { ...@@ -469,16 +469,11 @@ TEST(Traits, is_constexpr_default_constructible) {
EXPECT_TRUE(is_constexpr_default_constructible_v<Empty>); EXPECT_TRUE(is_constexpr_default_constructible_v<Empty>);
EXPECT_TRUE(is_constexpr_default_constructible<Empty>{}); EXPECT_TRUE(is_constexpr_default_constructible<Empty>{});
// under clang 10, crash: https://bugs.llvm.org/show_bug.cgi?id=47620 struct NonTrivialDtor {
// and, with assertions disabled, expectation failures showing compiler FOLLY_MAYBE_UNUSED ~NonTrivialDtor() {}
// deviation from the language spec };
if (kClangVerMajor != (kIsApple ? 12 : 10)) { EXPECT_FALSE(is_constexpr_default_constructible_v<NonTrivialDtor>);
struct NonTrivialDtor { EXPECT_FALSE(is_constexpr_default_constructible<NonTrivialDtor>{});
~NonTrivialDtor() {}
};
EXPECT_FALSE(is_constexpr_default_constructible_v<NonTrivialDtor>);
EXPECT_FALSE(is_constexpr_default_constructible<NonTrivialDtor>{});
}
struct ConstexprCtor { struct ConstexprCtor {
int x, y; int x, y;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment