Skip to content

Commit 68aea8d

Browse files
committed
work around clang bug in visit
1 parent 27491cd commit 68aea8d

2 files changed

Lines changed: 32 additions & 13 deletions

File tree

include/boost/json/impl/visit.hpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,30 @@ visit(
4949
value const& jv) -> decltype(
5050
static_cast<Visitor&&>(v)( std::declval<std::nullptr_t const&>() ) )
5151
{
52+
detail::scalar const& sc = detail::access::get_scalar(jv);
5253
switch(jv.kind())
5354
{
5455
default: // unreachable()?
5556
case kind::string: return static_cast<Visitor&&>(v)( jv.get_string() );
5657
case kind::array: return static_cast<Visitor&&>(v)( jv.get_array() );
5758
case kind::object: return static_cast<Visitor&&>(v)( jv.get_object() );
58-
case kind::bool_: return static_cast<Visitor&&>(v)( detail::access::get_scalar(jv).b );
59-
case kind::int64: return static_cast<Visitor&&>(v)( detail::access::get_scalar(jv).i );
60-
case kind::uint64: return static_cast<Visitor&&>(v)( detail::access::get_scalar(jv).u );
61-
case kind::double_: return static_cast<Visitor&&>(v)( detail::access::get_scalar(jv).d );
59+
// local variables work around a bug in older clangs
60+
case kind::bool_: {
61+
bool const& b = sc.b;
62+
return static_cast<Visitor&&>(v)(b);
63+
}
64+
case kind::int64: {
65+
std::int64_t const& i = sc.i;
66+
return static_cast<Visitor&&>(v)(i);
67+
}
68+
case kind::uint64: {
69+
std::uint64_t const& u = sc.u;
70+
return static_cast<Visitor&&>(v)(u);
71+
}
72+
case kind::double_: {
73+
double const& d = sc.d;
74+
return static_cast<Visitor&&>(v)(d);
75+
}
6276
case kind::null: {
6377
auto const& np = detail::stable_np;
6478
return static_cast<Visitor&&>(v)(np) ;

test/visit.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ struct visitor_checker<value const&>
2929
operator()(std::nullptr_t const& n) const
3030
{ return {kind::null, &n}; }
3131

32+
std::pair<kind, void const*>
33+
operator()(bool&)
34+
{ BOOST_TEST_FAIL(); return {(kind)50, nullptr}; }
35+
3236
std::pair<kind, void const*>
3337
operator()(bool const& b) const
3438
{ return {kind::bool_, &b}; }
@@ -60,17 +64,17 @@ struct visitor_checker<value const&>
6064
template<class T>
6165
std::pair<kind, void const*>
6266
operator()(T&&) const&
63-
{ return {(kind)1000000, nullptr}; }
67+
{ return {(kind)40, nullptr}; }
6468

6569
template<class T>
6670
std::pair<kind, void const*>
6771
operator()(T&&) &
68-
{ return {(kind)1000000, nullptr}; }
72+
{ return {(kind)41, nullptr}; }
6973

7074
template<class T>
7175
std::pair<kind, void const*>
7276
operator()(T&&) &&
73-
{ return {(kind)1000000, nullptr}; }
77+
{ return {(kind)42, nullptr}; }
7478
};
7579

7680
template<>
@@ -115,17 +119,17 @@ struct visitor_checker<value&>
115119
template<class T>
116120
std::pair<kind, void const*>
117121
operator()(T&&) const&
118-
{ return {(kind)1000000, nullptr}; }
122+
{ return {(kind)40, nullptr}; }
119123

120124
template<class T>
121125
std::pair<kind, void const*>
122126
operator()(T&&) &
123-
{ return {(kind)1000000, nullptr}; }
127+
{ return {(kind)41, nullptr}; }
124128

125129
template<class T>
126130
std::pair<kind, void const*>
127131
operator()(T&&) &&
128-
{ return {(kind)1000000, nullptr}; }
132+
{ return {(kind)42, nullptr}; }
129133
};
130134

131135
template<>
@@ -170,17 +174,17 @@ struct visitor_checker<value&&>
170174
template<class T>
171175
std::pair<kind, void const*>
172176
operator()(T&&) const&
173-
{ return {(kind)1000000, nullptr}; }
177+
{ static_assert( !std::is_same<T, T>::value, "" ); return {(kind)40, nullptr}; }
174178

175179
template<class T>
176180
std::pair<kind, void const*>
177181
operator()(T&&) &
178-
{ return {(kind)1000000, nullptr}; }
182+
{ static_assert( !std::is_same<T, T>::value, "" ); return {(kind)41, nullptr}; }
179183

180184
template<class T>
181185
std::pair<kind, void const*>
182186
operator()(T&&) &&
183-
{ return {(kind)1000000, nullptr}; }
187+
{ static_assert( !std::is_same<T, T>::value, "" ); return {(kind)42, nullptr}; }
184188
};
185189

186190
class visit_test
@@ -288,6 +292,7 @@ class visit_test
288292

289293
void run()
290294
{
295+
value const jv;
291296
visitor_ref_tester()();
292297

293298
BOOST_TEST_CHECKPOINT();

0 commit comments

Comments
 (0)