[PATCH] libstdc++: Fix ambiguity caused by new std::source_location constructor
Tomasz Kaminski
tkaminsk@redhat.com
Thu Feb 5 11:10:53 GMT 2026
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.
>
>
>>
>>> 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
>>>
>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20260205/9208f11a/attachment-0001.htm>
More information about the Libstdc++
mailing list