On Thu, 5 Feb 2026 at 11:15, Jonathan Wakely <[email protected]> wrote: > > On Thu, 5 Feb 2026 at 11:11, Tomasz Kaminski <[email protected]> wrote: > > > > > > > > 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. > > We already have such a function: > > // [support.srcloc.cons], creation > static consteval source_location > current(__builtin_ret_type __p = __builtin_source_location()) noexcept > { > source_location __ret; > __ret._M_impl = static_cast <const __impl*>(__p); > return __ret; > } > > So the contract_violation type could just call that to construct a > source_location from its _M_src_loc_ptr. > > Then we don't need a private constructor at all.
Ah, but that's a consteval function so we can't use it in contract_violation::location().
