[PATCH] libstdc++: Fix ambiguity caused by new std::source_location constructor

Jonathan Wakely jwakely@redhat.com
Thu Feb 5 11:18:07 GMT 2026


On Thu, 5 Feb 2026 at 11:15, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> On Thu, 5 Feb 2026 at 11:11, Tomasz Kaminski <tkaminsk@redhat.com> wrote:
> >
> >
> >
> > On Thu, Feb 5, 2026 at 11:58 AM Tomasz Kaminski <tkaminsk@redhat.com> wrote:
> >>
> >>
> >>
> >> On Thu, Feb 5, 2026 at 11:55 AM Tomasz Kaminski <tkaminsk@redhat.com> wrote:
> >>>
> >>>
> >>>
> >>> On Thu, Feb 5, 2026 at 11:35 AM Jonathan Wakely <jwakely@redhat.com> 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().



More information about the Libstdc++ mailing list