[libcxx-commits] [libcxx] [libc++] Fix ambiguous std::complex constructor (PR #103409)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Aug 13 13:03:34 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Louis Dionne (ldionne)
<details>
<summary>Changes</summary>
Fixes #<!-- -->101960
---
Full diff: https://github.com/llvm/llvm-project/pull/103409.diff
2 Files Affected:
- (modified) libcxx/include/complex (+6-3)
- (added) libcxx/test/std/numerics/complex.number/complex.special/gh_101960_ambiguous_constructor.pass.cpp (+38)
``````````diff
diff --git a/libcxx/include/complex b/libcxx/include/complex
index 22271acaf7358d..e6534025de57e5 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -421,7 +421,8 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f) : __re_(__re), __im_(__im) {}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(__from_builtin_tag, _Complex float __v)
+ template <class _Tag, __enable_if_t<_IsSame<_Tag, __from_builtin_tag>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit complex(_Tag, _Complex float __v)
: __re_(__real__ __v), __im_(__imag__ __v) {}
_LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
@@ -517,7 +518,8 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) : __re_(__re), __im_(__im) {}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(__from_builtin_tag, _Complex double __v)
+ template <class _Tag, __enable_if_t<_IsSame<_Tag, __from_builtin_tag>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit complex(_Tag, _Complex double __v)
: __re_(__real__ __v), __im_(__imag__ __v) {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
@@ -617,7 +619,8 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L)
: __re_(__re), __im_(__im) {}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(__from_builtin_tag, _Complex long double __v)
+ template <class _Tag, __enable_if_t<_IsSame<_Tag, __from_builtin_tag>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit complex(_Tag, _Complex long double __v)
: __re_(__real__ __v), __im_(__imag__ __v) {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
diff --git a/libcxx/test/std/numerics/complex.number/complex.special/gh_101960_ambiguous_constructor.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.special/gh_101960_ambiguous_constructor.pass.cpp
new file mode 100644
index 00000000000000..bffe8764386a75
--- /dev/null
+++ b/libcxx/test/std/numerics/complex.number/complex.special/gh_101960_ambiguous_constructor.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <complex>
+
+// Regression test for https://github.com/llvm/llvm-project/issues/101960 where we used to
+// trigger an ambiguous constructor.
+
+#include <complex>
+#include <cassert>
+
+struct NastyConvertible {
+ template <class T>
+ operator T() const {
+ return T(0);
+ }
+};
+
+template <class T>
+void test() {
+ NastyConvertible nasty;
+ std::complex<T> x(nasty, nasty);
+ assert(x.real() == T(0));
+ assert(x.imag() == T(0));
+}
+
+int main(int, char**) {
+ test<float>();
+ test<double>();
+ test<long double>();
+
+ return 0;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/103409
More information about the libcxx-commits
mailing list