On Thu, Feb 5, 2026 at 11:58 AM Tomasz Kaminski <[email protected]> wrote:
> > > On Thu, Feb 5, 2026 at 11:55 AM Tomasz Kaminski <[email protected]> > wrote: > >> >> >> On Thu, Feb 5, 2026 at 11:35 AM Jonathan Wakely <[email protected]> >> wrote: >> >>> The new constructor added for Contracts support should be explicit, and >>> only needs to be defined when contracts are enabled by -fcontracts. >>> >>> It might as well be marked noexcept too. And the comment on the friend >>> declaration isn't accurate, the friend needs access to the private >>> constructor, not the __impl type. >>> >>> libstdc++-v3/ChangeLog: >>> >>> * include/std/source_location (source_location(const void*)): >>> Make new constructor explicit and gate on __glibcxx_contracts. >>> * testsuite/18_support/contracts/includes.cc: Move to... >>> * testsuite/18_support/contracts/srcloc.cc: ...here. Test for >>> ambiguity caused by new constructor. >>> --- >>> >>> Tested x86_64-linux. >>> >> While adding explicit is desired why this constructor accepts void* >> (and thus causes issues), instead of __impl*. This would reduce >> the risk of ambiguities even more. >> And if contranct_violation can access the constructor, it can >> also access __impl. >> > We could either cast to impl in function: > std::source_location location() const noexcept { > return std::source_location (_M_src_loc_ptr); > } > Or store _M_src_loc_ptr as source_location::impl*. > I think casting inside contract_handler is a much cleaner solution, it is up to contract_handler to know that _M_src_loc_ptr void* points to source_location::__impl. I contrast, is very fishy for source_location(void*) constructor to assume that any void* the pointer it got is pointing to __impl. Or even better, instead of constructor, this should be static _S_from_impl_ptr(const void*) private function. If the type is part of the name of the function, it can accept void* argument. > > >> >>> libstdc++-v3/include/std/source_location | 7 +++---- >>> .../18_support/contracts/{includes.cc => srcloc.cc} | 10 ++++++++++ >>> 2 files changed, 13 insertions(+), 4 deletions(-) >>> rename libstdc++-v3/testsuite/18_support/contracts/{includes.cc => >>> srcloc.cc} (59%) >>> >>> diff --git a/libstdc++-v3/include/std/source_location >>> b/libstdc++-v3/include/std/source_location >>> index f773879755c9..4d79480254b6 100644 >>> --- a/libstdc++-v3/include/std/source_location >>> +++ b/libstdc++-v3/include/std/source_location >>> @@ -89,11 +89,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >>> private: >>> const __impl* _M_impl = nullptr; >>> >>> - constexpr source_location (const void *__t) >>> - : _M_impl (static_cast <const __impl*>(__t)) {} >>> - >>> #ifdef __glibcxx_contracts >>> - /* To enable use of the source __impl*. */ >>> + constexpr explicit source_location (const void* __t) noexcept >>> + : _M_impl(static_cast<const __impl*>(__t)) { } >>> + >>> friend class std::contracts::contract_violation; >>> #endif >>> }; >>> diff --git a/libstdc++-v3/testsuite/18_support/contracts/includes.cc >>> b/libstdc++-v3/testsuite/18_support/contracts/srcloc.cc >>> similarity index 59% >>> rename from libstdc++-v3/testsuite/18_support/contracts/includes.cc >>> rename to libstdc++-v3/testsuite/18_support/contracts/srcloc.cc >>> index 91f793f1e201..d616b5557db6 100644 >>> --- a/libstdc++-v3/testsuite/18_support/contracts/includes.cc >>> +++ b/libstdc++-v3/testsuite/18_support/contracts/srcloc.cc >>> @@ -4,3 +4,13 @@ >>> // We should not get errors from including this before <contracts>: >>> #include <source_location> >>> #include <contracts> >>> + >>> +struct S { S(char const *); }; >>> +void f(S); >>> +void f(std::source_location); >>> + >>> +void >>> +test01() >>> +{ >>> + f(""); // { dg-bogus "ambiguous" } >>> +} >>> -- >>> 2.52.0 >>> >>>
