From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id D71D03858415 for ; Mon, 22 Nov 2021 16:30:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D71D03858415 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-313-H3vQXY2IPMi4O-FtO9kT6w-1; Mon, 22 Nov 2021 11:30:26 -0500 X-MC-Unique: H3vQXY2IPMi4O-FtO9kT6w-1 Received: by mail-wm1-f70.google.com with SMTP id g11-20020a1c200b000000b003320d092d08so7027970wmg.9 for ; Mon, 22 Nov 2021 08:30:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:to :content-language:cc:from:subject:content-transfer-encoding; bh=jS2xxQtur6hMaGKaEIrLTSmSsed1Hnr55k6e/vF0Vrs=; b=00JhLbfYf+2r1x/yJ/uMx0umea0QJ1AWbHTI91yvpWafy4QEDFmnoysnKmlQfTh183 ETV6qHb3goV+8sMpSnfPKGtyUcBjfd+AbtjwTdR8Ve3toKGEUJCZHvQEYothSTiiWwlV xgcNjex4fjdMcVn7/kp/ddluYTpg95e7h1NlVTDd6UcuJ1GDHl+Cqi5jcwHSgVJ+RfAW Nb8ZdyF4re1SdZefehhhB619gHgrsXKZrckbNoE9E0CznlDF2wVksMrxD5E7pQhhUyrt IyfQzZ4EzxUx46kukcMCuGq9pq5wNGvSTTrqxe9UaTVxu+CeqRjWxRRs1pOb9locasxS Clmg== X-Gm-Message-State: AOAM532ZF3ndffZP6U0Nji11uYO8jh5+fbf3Xzsq5x14DPsHnTAnhQS3 M5YBKNQzO8m2s5rPhrL2ofLT8AOVaKedwdtQR5qiJqna1joQvheFn/yiVzbkJCzm5lQalKWiWMJ 95pm4deHA3FvPS/enicBNFegerEEskwsgLuvbiRMKpZNyWlgBC5irqoPcfAoeJ3JreZo= X-Received: by 2002:a5d:648e:: with SMTP id o14mr39295605wri.141.1637598625057; Mon, 22 Nov 2021 08:30:25 -0800 (PST) X-Google-Smtp-Source: ABdhPJyaY3TfC3vrGTsfZfdrk3jpZTxqJzcxMzM5IKJZLYz+pFsgrkp00+wq2BwKjElKGkEjzs7BqA== X-Received: by 2002:a5d:648e:: with SMTP id o14mr39295535wri.141.1637598624625; Mon, 22 Nov 2021 08:30:24 -0800 (PST) Received: from [192.168.188.57] (dynamic-077-006-201-015.77.6.pool.telefonica.de. [77.6.201.15]) by smtp.gmail.com with ESMTPSA id b14sm11839808wrd.24.2021.11.22.08.30.24 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 22 Nov 2021 08:30:24 -0800 (PST) Message-ID: <3292e732-f4ff-d80c-d29e-e3a99a0fe3d5@redhat.com> Date: Mon, 22 Nov 2021 17:30:23 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.3.0 To: libstdc++@gcc.gnu.org Cc: gcc-patches@gcc.gnu.org From: Stephan Bergmann Subject: std::basic_string<_Tp> constructor point of instantiation woes? X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-14.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=unavailable autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Nov 2021 16:30:32 -0000 When using recent libstc++ trunk with Clang in C++20 mode, std::u16string literals as in > #include > int main() { > using namespace std::literals; > u""s; > } started to cause linker failures due to undefined > _ZNSt7__cxx1112basic_stringIDsSt11char_traitsIDsESaIDsEE12_M_constructIPKDsEEvT_S8_St20forward_iterator_tag After some head scratching, I found the more insightful > $ cat test.cc > #include > constexpr std::string s("", 0); > $ clang++ -std=c++20 -fsyntax-only test.cc > test.cc:2:23: error: constexpr variable 's' must be initialized by a constant expression > constexpr std::string s("", 0); > ^~~~~~~~ > ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/basic_string.h:620:2: note: undefined function '_M_construct' cannot be used in a constant expression > _M_construct(__s, __s + __n, std::forward_iterator_tag()); > ^ > test.cc:2:23: note: in call to 'basic_string(&""[0], 0, std::allocator())' > constexpr std::string s("", 0); > ^ > ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/basic_string.h:331:9: note: declared here > _M_construct(_FwdIterator __beg, _FwdIterator __end, > ^ > 1 error generated. and after some more head scratching found Clang to complain about the reduced > template struct S { > constexpr void f(); > constexpr S() { f(); }; > }; > S s1; > template constexpr void S::f() {} > constexpr S s2; (about which GCC does not complain). Not entirely sure who is right, but what would help Clang is to move the definitions of the literal operators in basic_string.h (which implicitly instantiate the corresponding std::basic_string<_Tp> constructor) past the definition of _M_construct (which is called from the constructor) in basic_string.tcc; something like > diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h > index 6e7de738308..871ca89e16e 100644 > --- a/libstdc++-v3/include/bits/basic_string.h > +++ b/libstdc++-v3/include/bits/basic_string.h > @@ -4304,55 +4304,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > struct __is_fast_hash> : std::false_type > { }; > > -#if __cplusplus >= 201402L > - > -#define __cpp_lib_string_udls 201304 > - > - inline namespace literals > - { > - inline namespace string_literals > - { > -#pragma GCC diagnostic push > -#pragma GCC diagnostic ignored "-Wliteral-suffix" > - > -#if __cpp_lib_constexpr_string >= 201907L > -# define _GLIBCXX_STRING_CONSTEXPR constexpr > -#else > -# define _GLIBCXX_STRING_CONSTEXPR > -#endif > - > - _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR > - inline basic_string > - operator""s(const char* __str, size_t __len) > - { return basic_string{__str, __len}; } > - > - _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR > - inline basic_string > - operator""s(const wchar_t* __str, size_t __len) > - { return basic_string{__str, __len}; } > - > -#ifdef _GLIBCXX_USE_CHAR8_T > - _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR > - inline basic_string > - operator""s(const char8_t* __str, size_t __len) > - { return basic_string{__str, __len}; } > -#endif > - > - _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR > - inline basic_string > - operator""s(const char16_t* __str, size_t __len) > - { return basic_string{__str, __len}; } > - > - _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR > - inline basic_string > - operator""s(const char32_t* __str, size_t __len) > - { return basic_string{__str, __len}; } > - > -#undef _GLIBCXX_STRING_CONSTEXPR > -#pragma GCC diagnostic pop > - } // inline namespace string_literals > - } // inline namespace literals > - > #if __cplusplus >= 201703L > namespace __detail::__variant > { > @@ -4369,7 +4320,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > { }; > } // namespace __detail::__variant > #endif // C++17 > -#endif // C++14 > > _GLIBCXX_END_NAMESPACE_VERSION > } // namespace std > diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc > index 6f619a08f70..2fd607ef50a 100644 > --- a/libstdc++-v3/include/bits/basic_string.tcc > +++ b/libstdc++-v3/include/bits/basic_string.tcc > @@ -1123,6 +1123,57 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > #endif // _GLIBCXX_USE_WCHAR_T > #endif // _GLIBCXX_EXTERN_TEMPLATE > > +#if __cplusplus >= 201402L > + > +#define __cpp_lib_string_udls 201304 > + > + inline namespace literals > + { > + inline namespace string_literals > + { > +#pragma GCC diagnostic push > +#pragma GCC diagnostic ignored "-Wliteral-suffix" > + > +#if __cpp_lib_constexpr_string >= 201907L > +# define _GLIBCXX_STRING_CONSTEXPR constexpr > +#else > +# define _GLIBCXX_STRING_CONSTEXPR > +#endif > + > + _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR > + inline basic_string > + operator""s(const char* __str, size_t __len) > + { return basic_string{__str, __len}; } > + > + _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR > + inline basic_string > + operator""s(const wchar_t* __str, size_t __len) > + { return basic_string{__str, __len}; } > + > +#ifdef _GLIBCXX_USE_CHAR8_T > + _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR > + inline basic_string > + operator""s(const char8_t* __str, size_t __len) > + { return basic_string{__str, __len}; } > +#endif > + > + _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR > + inline basic_string > + operator""s(const char16_t* __str, size_t __len) > + { return basic_string{__str, __len}; } > + > + _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_STRING_CONSTEXPR > + inline basic_string > + operator""s(const char32_t* __str, size_t __len) > + { return basic_string{__str, __len}; } > + > +#undef _GLIBCXX_STRING_CONSTEXPR > +#pragma GCC diagnostic pop > + } // inline namespace string_literals > + } // inline namespace literals > + > +#endif // C++14 > + > _GLIBCXX_END_NAMESPACE_VERSION > } // namespace std >