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
>>>
>>>

Reply via email to