Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions stl/inc/complex
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,23 @@ constexpr complex<long double>::complex(const complex<float>& _Right) noexcept /
constexpr complex<long double>::complex(const complex<double>& _Right) noexcept // strengthened
: _Complex_base<long double, _Lcomplex_value>(_Right.real(), _Right.imag()) {}

#if !_HAS_NONFLOATING_COMPLEX
_EXPORT_STD template <class _Ty>
class complex {
static_assert(false,
"The effect of instantiating the template std::complex for any type other than float, double, or long double "
"is unspecified. The possibility of such instantiation will be removed in a future version. "
Comment on lines +1327 to +1328

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to say "a cv-unqualified floating-point type" (see [complex.numbers.general]/2) which looks more future-proof?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure. I copied that from the deprecation message.

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The static_assert text says non-floating instantiation "will be removed in a future version", but with _HAS_NONFLOATING_COMPLEX defaulting to 0 this PR effectively removes it now (unless explicitly re-enabled). Please update the wording to accurately describe the current state (e.g., that it is disabled by default / requires opting in) so the error message doesn’t mislead users.

Suggested change
"is unspecified. The possibility of such instantiation will be removed in a future version. "
"is unspecified. Such instantiations are disabled by default in this version. "

Copilot uses AI. Check for mistakes.
"You can define _HAS_NONFLOATING_COMPLEX to 1 to enable such instantiation "
"and define _SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING to suppress its deprecation warning.");
Comment on lines +1324 to +1330

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static_assert(false, ...) inside a class template is non-dependent, so it will fire immediately when is parsed (even if std::complex<T> is never instantiated), effectively breaking all users when _HAS_NONFLOATING_COMPLEX is 0. Make the assertion dependent on _Ty (e.g., assert on a dependent boolean/trait) so the diagnostic is emitted only when std::complex<non-floating> is actually instantiated.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WG21-P2593 enables static_assert(false).
By now, it has been implemented for every supported target compiler, even Cuda.

So we'll keep it here.


// For deduction, primary template is used, so keeping a couple of constructors around

constexpr complex(const _Ty& = _Ty(), const _Ty& = _Ty()) = delete;
Comment on lines +1332 to +1334

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The deleted deduction-only ctor complex(const _Ty& = _Ty(), const _Ty& = _Ty()) can be ill-formed for some _Ty (e.g. _Ty=void makes const void& invalid; non-default-constructible _Ty makes the default arguments ill-formed). That can cause diagnostics that mask or precede the intended class-scope static_assert message. Consider avoiding _Ty() defaults (e.g. provide separate 1-arg/2-arg deleted overloads without defaults) and/or using a parameter alias that is always a valid object type (e.g. conditional_t<is_void_v<_Ty>, int, _Ty>) so the template remains well-formed and reliably hits the static_assert.

Suggested change
// For deduction, primary template is used, so keeping a couple of constructors around
constexpr complex(const _Ty& = _Ty(), const _Ty& = _Ty()) = delete;
using _Deduction_type = conditional_t<is_void_v<_Ty>, int, _Ty>;
// For deduction, primary template is used, so keeping a couple of constructors around
constexpr complex() = delete;
constexpr complex(const _Deduction_type&) = delete;
constexpr complex(const _Deduction_type&, const _Deduction_type&) = delete;

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've been there. C++14 still needs to be supported here.


template <class _Other>
constexpr complex(const complex<_Other>&) = delete;
};
#else // ^^^ !_HAS_NONFLOATING_COMPLEX / _HAS_NONFLOATING_COMPLEX vvv
_EXPORT_STD template <class _Ty>
class complex : public _Complex_base<_Ty, _Complex_value<_Ty>> {
public:
Expand Down Expand Up @@ -1411,6 +1428,7 @@ public:
return *this;
}
};
#endif // ^^^ _HAS_NONFLOATING_COMPLEX ^^^

_EXPORT_STD template <class _Ty>
_NODISCARD _CONSTEXPR20 complex<_Ty> operator+(const complex<_Ty>& _Left, const complex<_Ty>& _Right)
Expand Down
6 changes: 6 additions & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,10 @@ _EMIT_STL_ERROR(STL1001, "Unexpected compiler version, expected MSVC Compiler 19
#error /GR implies _HAS_STATIC_RTTI.
#endif // defined(_CPPRTTI) && !_HAS_STATIC_RTTI

#ifndef _HAS_NONFLOATING_COMPLEX
#define _HAS_NONFLOATING_COMPLEX 0
#endif // !defined(_HAS_NONFLOATING_COMPLEX)

// N4950 [dcl.constexpr]/1: "A function or static data member declared with the
// constexpr or consteval specifier is implicitly an inline function or variable"

Expand Down Expand Up @@ -1400,6 +1404,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect
#define _CXX20_REMOVE_CISO646
#endif // ^^^ warning disabled ^^^

#if _HAS_NONFLOATING_COMPLEX
#if !defined(_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING)
#define _DEPRECATE_NONFLOATING_COMPLEX \
[[deprecated("warning STL4037: " \
Expand All @@ -1410,6 +1415,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect
#else // ^^^ warning enabled / warning disabled vvv
#define _DEPRECATE_NONFLOATING_COMPLEX
#endif // ^^^ warning disabled ^^^
#endif // ^^^ _HAS_NONFLOATING_COMPLEX ^^^

// STL4038 is used to warn that "The contents of <meow> are available only with C++NN or later."

Expand Down
2 changes: 1 addition & 1 deletion tests/libcxx/usual_matrix.lst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

RUNALL_INCLUDE ..\universal_prefix.lst
RUNALL_CROSSLIST
* PM_CL="/EHsc /MTd /std:c++latest /permissive- /utf-8 /FImsvc_stdlib_force_include.h /wd4643"
* PM_CL="/EHsc /MTd /std:c++latest /permissive- /utf-8 /FImsvc_stdlib_force_include.h /wd4643 /D_HAS_NONFLOATING_COMPLEX=1"

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test matrix change forces _HAS_NONFLOATING_COMPLEX=1 for the default libc++-compat run, which means the libc++ test job will no longer exercise the new default behavior (_HAS_NONFLOATING_COMPLEX defaults to 0 in yvals_core.h). If the goal is to validate the removal path, consider keeping the default run on the default setting and adding a separate opt-in matrix entry for _HAS_NONFLOATING_COMPLEX=1 (or gating this define to only the specific configs/tests that still require it).

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libc++ tests do assume nonfloating complex, nothing can be done here without upstream change, which I don't think will work out.

RUNALL_CROSSLIST
PM_CL="/Zc:preprocessor"
ASAN PM_CL="-fsanitize=address /Zi" PM_LINK="/debug"
Expand Down