private class members access fails with meta-programming in clang?

I thought this should pass with clang.

x-- start --x
  
#include <boost/mpl/has_xxx.hpp>

BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(hasSomething, Data, false);

class A {
private:
struct Data {
};
};

void function(bool val = hasSomething<A>::value) {}

x-- end --x

however it produces following output:
test_private_data.cpp:3:49: error: 'Data' is a private member of 'A'
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(hasSomething, Data, false);
^
/usr/include/boost/mpl/has_xxx.hpp:195:68: note: expanded from macro 'BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF'
, boost::mpl::aux::type_wrapper<BOOST_MSVC_TYPENAME U::name>* = 0 \
^
test_private_data.cpp:3:1: note: while substituting deduced template arguments into function template 'test' [with U = A]
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(hasSomething, Data, false);
^
/usr/include/boost/mpl/has_xxx.hpp:193:41: note: expanded from macro 'BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF'
static boost::mpl::aux::yes_tag test( \
^
test_private_data.cpp:12:26: note: in instantiation of template class 'hasSomething<A, mpl_::bool_<false> >' requested here
void function(bool val = hasSomething<A>::value) {}
^
1 error generated.
/usr/bin/ld: /tmp/test_private_data-Hatffv.o: No such file: No such file or directory
clang: error: linker command failed with exit code 1 (use -v to see invocation)

BUT it passes with GCC.

Which one is right?
-RH

I assume that Boost is using SFINAE here in its check. Access control
violations were not subject to SFINAE prior to C++11, and Clang is correct
to diagnose it. You can compile with -std=c++11 to make this work; the
trait will return 'false'.

John.

I am confused on how to find this in the std document.
What I find in there is (from n3485):
1. Page-231, clause 4 - Access control is applied uniformly to all
names, whether the names are referred to from declarations or
expressions.
2. Page-231, clause 5 - It should be noted that it is access to members
and base classes that is controlled, not their visibility. Names
of members are still visible, and implicit conversions to base classes
are still considered, when those members
and base classes are inaccessible. The interpretation of a given
construct is established without regard to
access control. If the interpretation established makes use of
inaccessible member names or base classes, the
construct is ill-formed.

I am not sure what they mean by visibility?

Could you send me what sections and clauses are you referring to?

Thanks for response again.

Regards.

On Behalf Of John McCall

I am confused on how to find this in the std document.
What I find in there is (from n3485):
1. Page-231, clause 4 - Access control is applied uniformly to all
names, whether the names are referred to from declarations or
expressions.
2. Page-231, clause 5 - It should be noted that it is access to members
and base classes that is controlled, not their visibility. Names
of members are still visible, and implicit conversions to base classes
are still considered, when those members
and base classes are inaccessible. The interpretation of a given
construct is established without regard to
access control. If the interpretation established makes use of
inaccessible member names or base classes, the
construct is ill-formed.

I am not sure what they mean by visibility?

Could you send me what sections and clauses are you referring to?

We're not a C++ support forum; your question might be better directed to
stackoverflow. If you want to understand how the C++11 rules differ from
C++03, you should compare the C++11 and C++03 standards. Search for things
like "would be ill-formed" and "type deduction fails".

If you think that Clang is actually wrong here (if this code is still
rejected with -std=c++11, for instance), please provide preprocessed (and
preferably reduced) source code.