Skip to content

Error compiling std::pair constructor with gcc >= 4.7 #23145

@DimitryAndric

Description

@DimitryAndric
Bugzilla Link 22771
Resolution FIXED
Resolved on Mar 30, 2015 14:29
Version unspecified
OS All
CC @emaste,@mclow,@zygoloid

Extended Description

One of the FreeBSD developers attempted to build the -CURRENT source tree (which includes a relatively new snapshot of libc++) using gcc 4.9.1, and encountered an error about std::make_pair during compilation of clang's lib/AST/DeclBase.cpp [1]:

In file included from /usr/src/lib/clang/libclangast/../../../contrib/llvm/include/llvm/Support/type_traits.h:17:0,
from /usr/src/lib/clang/libclangast/../../../contrib/llvm/include/llvm/Support/Casting.h:19,
from /usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/include/clang/Basic/LLVM.h:22,
from /usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/include/clang/AST/AttrIterator.h:17,
from /usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/include/clang/AST/DeclBase.h:17,
from /usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/lib/AST/DeclBase.cpp:14:
/usr/obj/usr/src/tmp/usr/include/c++/v1/type_traits: In instantiation of 'struct std::__1::__is_convertible<const clang::StoredDeclsList&, clang::StoredDeclsList, 0u, 0u>':
/usr/obj/usr/src/tmp/usr/include/c++/v1/type_traits:943:62: required from 'struct std::__1::is_convertible<const clang::StoredDeclsList&, clang::StoredDeclsList>'
/usr/obj/usr/src/tmp/usr/include/c++/v1/utility:269:77: required by substitution of 'template<class _U1, class _U2> std::__1::pair<_T1, _T2>::pair(const std::__1::pair<_U1, _U2>&, typename std::__1::enable_if<(std::__1::is_convertible<const _U1&, _T1>::value && std::__1::is_convertible<const _U2&, _T2>::value)>::type*) [with _U1 = clang::DeclarationName; _U2 = clang::StoredDeclsList]'
/usr/obj/usr/src/tmp/usr/include/c++/v1/utility:491:69: required from 'std::__1::pair<typename std::__1::__make_pair_return<_Tp>::type, typename std::__1::__make_pair_return<_T2>::type> std::__1::make_pair(_T1&&, _T2&&) [with _T1 = clang::DeclarationName&; _T2 = clang::StoredDeclsList; typename std::__1::__make_pair_return<_T2>::type = clang::StoredDeclsList; typename std::__1::__make_pair_return<_Tp>::type = clang::DeclarationName]'
/usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/lib/AST/DeclBase.cpp:1313:59: required from here
/usr/obj/usr/src/tmp/usr/include/c++/v1/type_traits:881:87: error: use of deleted function 'constexpr clang::StoredDeclsList::StoredDeclsList(const clang::StoredDeclsList&)'
sizeof(__is_convertible_imp::__test<_T2>(__is_convertible_imp::__source<_T1>())) == 1
^
In file included from /usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/lib/AST/DeclBase.cpp:20:0:
/usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h:32:8: note: 'constexpr clang::StoredDeclsList::StoredDeclsList(const clang::StoredDeclsList&)' is implicitly declared as deleted because 'clang::StoredDeclsList' declares a move constructor or move assignment operator
struct StoredDeclsList {
^

Apparently, gcc concludes that 1) it requires a copy constructor for StoredDeclsList, and 2) the copy constructor is deleted because StoredDeclsList declares a move constructor. Clang obviously has no problem compiling this code.

A minimal test case is as follows:

#include

struct Foo {
Foo() {}
Foo(Foo &&RHS) {}
};

void pairtest(int i)
{
auto p1 = std::make_pair(i, Foo());
}

Compiling this with gcc 4.9.1, and using libc++ trunk r230867 as headers, results in a similar error:

$ g++49 -std=c++11 -I/share/dim/src/libcxx/trunk/include -c pairtest.cpp
In file included from /share/dim/src/libcxx/trunk/include/__tuple:16:0,
from /share/dim/src/libcxx/trunk/include/utility:157,
from pairtest.cpp:1:
/share/dim/src/libcxx/trunk/include/type_traits: In instantiation of 'struct std::__1::__is_convertible<const Foo&, Foo, 0u, 0u>':
/share/dim/src/libcxx/trunk/include/type_traits:949:62: required from 'struct std::__1::is_convertible<const Foo&, Foo>'
/share/dim/src/libcxx/trunk/include/utility:274:77: required by substitution of 'template<class _U1, class _U2> std::__1::pair<_T1, _T2>::pair(const std::__1::pair<_U1, _U2>&, typename std::__1::enable_if<(std::__1::is_convertible<const _U1&, _T1>::value && std::__1::is_convertible<const _U2&, _T2>::value)>::type*) [with _U1 = int; _U2 = Foo]'
pairtest.cpp:10:36: required from here
/share/dim/src/libcxx/trunk/include/type_traits:887:87: error: use of deleted function 'constexpr Foo::Foo(const Foo&)'
sizeof(__is_convertible_imp::__test<_T2>(__is_convertible_imp::__source<_T1>())) == 1
^
pairtest.cpp:3:8: note: 'constexpr Foo::Foo(const Foo&)' is implicitly declared as deleted because 'Foo' declares a move constructor or move assignment operator
struct Foo {
^
In file included from /share/dim/src/libcxx/trunk/include/__tuple:16:0,
from /share/dim/src/libcxx/trunk/include/utility:157,
from pairtest.cpp:1:
/share/dim/src/libcxx/trunk/include/type_traits:851:28: error: initializing argument 1 of 'char std::__1::__is_convertible_imp::__test(_Tp) [with _Tp = Foo]'
template char __test(_Tp);
^

The question is whether this is a libc++ problem or a gcc problem.

[1] https://jenkins.freebsd.org/job/FreeBSD_HEAD_external_toolchain_gcc/6/console

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzillalibc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions