Commit implementing LWG 2510 (r372777) breaks compilation of LLVM

Hi Louis,

I’m seeing compilation failures while trying to compile clang with libc++ after r372777.
This is blocking our integrates.

Checking for implicitly default-constructible types results in errors coming from access-checking.
I would expect this shouldn’t happen, given that the check is done in SFINAE context.

Is there a quick workaround? Should we revert the change until it’s found?

Here is the compilation error itself:

…/include/c++/v1/type_traits:2820:110: error: calling a protected constructor of class ‘clang::ento::Loc’
struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({}))>
^
…/include/c++/v1/utility:350:18: note: in instantiation of template class ‘std::__u::__is_implicitly_default_constructible<clang::ento::Loc, void>’ requested here
return __is_implicitly_default_constructible<_U1>::value
^
…/include/c++/v1/utility:341:19: note: in instantiation of function template specialization ‘std::__u::pair<clang::ento::Loc, clang::ento::SVal>::_CheckArgs::__enable_implicit_default<clang::ento::Loc, clang::ento::SVal>’ requested here
&& !__enable_implicit_default<_U1, _U2>();
^
…/include/c++/v1/utility:403:45: note: in instantiation of function template specialization ‘std::__u::pair<clang::ento::Loc, clang::ento::SVal>::_CheckArgs::__enable_explicit_default<clang::ento::Loc, clang::ento::SVal>’ requested here
_CheckArgsDep<_Dummy>::template __enable_explicit_default<_T1, _T2>()
^
…/include/c++/v1/utility:406:5: note: while substituting prior template arguments into non-type template parameter [with _Dummy = true]
pair() NOEXCEPT(is_nothrow_default_constructible<first_type>::value &&
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
…/include/c++/v1/utility:297:29: note: while substituting deduced template arguments into function template ‘pair’ [with _Dummy = (no value), $1 = (no value)]
struct _LIBCPP_TEMPLATE_VIS pair
^
third_party/llvm/llvm/include/llvm/Support/type_traits.h:90:7: note: (skipping 3 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
union trivial_helper {
^
third_party/llvm/llvm/include/llvm/Support/type_traits.h:176:40: note: in instantiation of static data member ‘llvm::is_trivially_copyable<std::__u::pair<clang::ento::Loc, clang::ento::SVal> >::has_trivial_move_constructor’ requested here
(has_deleted_move_constructor || has_trivial_move_constructor) &&
^
third_party/llvm/llvm/include/llvm/ADT/SmallVector.h:178:56: note: in instantiation of static data member ‘llvm::is_trivially_copyable<std::__u::pair<clang::ento::Loc, clang::ento::SVal> >::value’ requested here
template <typename T, bool = is_trivially_copyable::value>
^
third_party/llvm/llvm/include/llvm/ADT/SmallVector.h:315:32: note: in instantiation of default argument for ‘SmallVectorTemplateBase<std::__u::pair<clang::ento::Loc, clang::ento::SVal> >’ required here
class SmallVectorImpl : public SmallVectorTemplateBase {
^~~~~~~~~~~~~~~~~~~~~~~~~~
third_party/llvm/llvm/include/llvm/ADT/SmallVector.h:837:28: note: in instantiation of template class ‘llvm::SmallVectorImpl<std::__u::pair<clang::ento::Loc, clang::ento::SVal> >’ requested here
class SmallVector : public SmallVectorImpl, SmallVectorStorage<T, N> {
^
third_party/llvm/llvm/tools/clang/lib/StaticAnalyzer/Core/Store.cpp:51:46: note: in instantiation of template class ‘llvm::SmallVector<std::__u::pair<clang::ento::Loc, clang::ento::SVal>, 16>’ requested here
SmallVector<CallEvent::FrameBindingTy, 16> InitialBindings;
^
third_party/llvm/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h:322:3: note: declared protected here
Loc() = default;

I’ll have to revert the change to unbreak our integrate.
Sorry about the inconvenience.

Reverted in r372832.

I was able to reproduce the failure. I don’t understand it yet but it looks like we might have exposed a Clang bug. FWIW, here’s the repro:

#include

#include <type_traits>

struct Base { };

struct Derived : Base { protected: Derived() = default; };

static_assert(!std::is_default_constructible<std::pair<Derived, int> >::value, “”);

Louis

Awesome, thanks!
Let me know if I can be of any more help.