The new constructor added for Contracts support was not explicit, so
caused ambiguities when arbitrary pointers were used in contexts which
could convert to std::source_location.
We don't actually need a constructor, the contract_violation::location()
function can just set the data member directly.
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/contracts (contract_violation::location): Use
source_location default constructor and then set _M_impl.
* include/std/source_location (source_location(const void*)):
Remove constructor.
* testsuite/18_support/contracts/includes.cc: Move to...
* testsuite/18_support/contracts/srcloc.cc: ...here. Test for
ambiguity caused by new constructor.
---
v2: remove the new constructor completely, and make contract_violation
set the data member instead.
Iain, Nina, is there a reason we need the new problematic constructor,
or can we just do this instead? If we do need the constructor, does it
need to take const void* or could it use const __impl* instead?
I know there are differences between the __builtin_source_location()
builtin's return type in GCC and Clang, but I don't think that matters
here. All that matters is that the libstdc++ contract_violation is used
alongside the libstdc++ source_location, but that should be guaranteed.
You can't mix the libc++ <contracts> header with the libstdc++
<source_location> header, or vice versa.
libstdc++-v3/include/std/contracts | 5 ++++-
libstdc++-v3/include/std/source_location | 4 ----
.../18_support/contracts/{includes.cc => srcloc.cc} | 10 ++++++++++
3 files changed, 14 insertions(+), 5 deletions(-)
rename libstdc++-v3/testsuite/18_support/contracts/{includes.cc => srcloc.cc}
(59%)
diff --git a/libstdc++-v3/include/std/contracts
b/libstdc++-v3/include/std/contracts
index 0fd9b10247ea..c1fe54750af9 100644
--- a/libstdc++-v3/include/std/contracts
+++ b/libstdc++-v3/include/std/contracts
@@ -92,7 +92,10 @@ namespace contracts
detection_mode mode() const noexcept { return _M_detection_mode; }
const char* comment() const noexcept { return _M_comment; }
std::source_location location() const noexcept {
- return std::source_location (_M_src_loc_ptr);
+ std::source_location __loc;
+ __loc._M_impl
+ = static_cast<const source_location::__impl*>(_M_src_loc_ptr);
+ return __loc;
}
bool is_terminating () const noexcept {
return _M_evaluation_semantic ==
std::contracts::evaluation_semantic::enforce
diff --git a/libstdc++-v3/include/std/source_location
b/libstdc++-v3/include/std/source_location
index f773879755c9..8115e059536d 100644
--- a/libstdc++-v3/include/std/source_location
+++ b/libstdc++-v3/include/std/source_location
@@ -89,11 +89,7 @@ _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*. */
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