[clang] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)
MaxEW707 wrote: > Is intrin0.h a header that ships with MSVC's compiler, or with MS's STL? If > the latter, shouldn't everything just work already? It ships with MSVC. `intrin0.h` from MSVC doesn't work currently due to some declarations not matching declarations in clang's own `intrin.h`. For example `_addcary_u64`. Which I now realize I am missing since that is inside `adxintrin.h` which I mistakenly assumed only included adx instriniscs and not adc intrinsics as well. > What I'd like to see is a pull request sent to > https://github.com/microsoft/stl with some agreement about how to structure > the ifdefs so we can use intrin0.h when it is available. Sounds good I'll do that. > We probably can't use __has_include() because MSVC ships its own > copy of intrin0.h, and they can't be distinguished. I was thinking I could use `__has_include_next`. If `_has_include_next()` is true then we know clang is providing its own `intrin0.h`. Another option I had was to preemptively get a PR up to MSVC STL with a `__clang_major__` check for clang 18 assuming this PR gets in before the release window. A custom name like `intrin_msstl.h` works for me as well. https://github.com/llvm/llvm-project/pull/75711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)
MaxEW707 wrote: MSVC STL requires the x64 adc intel intrinsics. I moved those to a separate file `adcintrin.h` that can be included from `immintrin.h` and `intrin0.h` for x64. I also made a table [here ](https://gist.github.com/MaxEW707/2f4bf26801bc1b6b088aa7a2fadba526) of all the intrinsics available with MSVC's `intrin0.h`, which intrinsics are used by MSVC STL, which are used by MSVC STL when compiled under clang and which intrinsics are provided as builtins from clang. You will notice that the `_ReadWriteBarrier` compiler barrier isn't supported on arm by clang. This [godbolt](https://godbolt.org/z/xEv3oEbK6) appears to corroborate that finding. I am not too worried about this since I believe Microsoft is dropping 32-bit ARM in a future Windows 11 update if my memory is correct. The last table at the end shows the intrinsics that aren't implemented in clang but MSVC STL has workarounds using the clang intrinsics instead. We don't have to worry about supporting those. https://github.com/llvm/llvm-project/pull/75711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
https://github.com/MaxEW707 created https://github.com/llvm/llvm-project/pull/75992 See https://github.com/llvm/llvm-project/pull/75711 for discussion. As a summary from the PR above, `` includes adc intrinsics and adx intrinsics. To support MSVC STL we need to expose the adc intrinsics inside the currently proposed `` header. Move the processor agnostic adc intrinsics into a separate file that can be included from `` and the currently proposed ``. >From b6ea2ffe22f414ec79cd9ccd7e47c7b063583bcc Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:55:21 -0500 Subject: [PATCH] Move Intel ADC instrinsics into a separate file --- clang/lib/Headers/CMakeLists.txt | 1 + clang/lib/Headers/adcintrin.h| 160 +++ clang/lib/Headers/adxintrin.h| 127 +--- clang/lib/Headers/immintrin.h| 3 +- 4 files changed, 163 insertions(+), 128 deletions(-) create mode 100644 clang/lib/Headers/adcintrin.h diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index f8fdd402777e48..735e4e4e3be89b 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -139,6 +139,7 @@ set(webassembly_files set(x86_files # Intrinsics + adcintrin.h adxintrin.h ammintrin.h amxcomplexintrin.h diff --git a/clang/lib/Headers/adcintrin.h b/clang/lib/Headers/adcintrin.h new file mode 100644 index 00..b43322f22297d7 --- /dev/null +++ b/clang/lib/Headers/adcintrin.h @@ -0,0 +1,160 @@ +/*=== adxintrin.h - ADX intrinsics -=== + * + * 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 + * + *===---=== + */ + +#ifndef __ADCINTRIN_H +#define __ADCINTRIN_H + +#if !defined(__i386__) && !defined(__x86_64__) +#error "This header is only meant to be used on x86 and x64 architecture" +#endif + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) + +/* Use C++ inline semantics in C++, GNU inline for C mode. */ +#if defined(__cplusplus) +#define __INLINE __inline +#else +#define __INLINE static __inline +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/// Adds unsigned 32-bit integers \a __x and \a __y, plus 0 or 1 as indicated +///by the carry flag \a __cf. Stores the unsigned 32-bit sum in the memory +///at \a __p, and returns the 8-bit carry-out (carry flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store32(__p, __x + __y + temp) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c ADC instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +///A 32-bit unsigned addend. +/// \param __y +///A 32-bit unsigned addend. +/// \param __p +///Pointer to memory for storing the sum. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS _addcarry_u32(unsigned char __cf, +unsigned int __x, +unsigned int __y, +unsigned int *__p) { + return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p); +} + +/// Adds unsigned 32-bit integer \a __y to 0 or 1 as indicated by the carry +///flag \a __cf, and subtracts the result from unsigned 32-bit integer +///\a __x. Stores the unsigned 32-bit difference in the memory at \a __p, +///and returns the 8-bit carry-out (carry or overflow flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store32(__p, __x - (__y + temp)) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c SBB instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +///The 32-bit unsigned minuend. +/// \param __y +///The 32-bit unsigned subtrahend. +/// \param __p +///Pointer to memory for storing the difference. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS _subborrow_u32(unsigned char __cf, + unsigned int __x, + unsigned int __y, + unsigned int *__p) { + return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p); +} + +#ifdef __x86_64__ +/// Adds unsigned 64-bit integers \a __x and \a __y, plus 0 or 1 as indicated +///by the carry flag \a __cf. Stores the unsigned 64-bit su
[clang] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)
MaxEW707 wrote: > @MaxEW707 If you pull out the adcintrin.h change into a separate PR we can > fast track it as it should be done anyhow Done :). Here is the link since I can't add reviewers https://github.com/llvm/llvm-project/pull/75992. https://github.com/llvm/llvm-project/pull/75711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/75992 >From b6ea2ffe22f414ec79cd9ccd7e47c7b063583bcc Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:55:21 -0500 Subject: [PATCH 1/2] Move Intel ADC instrinsics into a separate file --- clang/lib/Headers/CMakeLists.txt | 1 + clang/lib/Headers/adcintrin.h| 160 +++ clang/lib/Headers/adxintrin.h| 127 +--- clang/lib/Headers/immintrin.h| 3 +- 4 files changed, 163 insertions(+), 128 deletions(-) create mode 100644 clang/lib/Headers/adcintrin.h diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index f8fdd402777e48..735e4e4e3be89b 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -139,6 +139,7 @@ set(webassembly_files set(x86_files # Intrinsics + adcintrin.h adxintrin.h ammintrin.h amxcomplexintrin.h diff --git a/clang/lib/Headers/adcintrin.h b/clang/lib/Headers/adcintrin.h new file mode 100644 index 00..b43322f22297d7 --- /dev/null +++ b/clang/lib/Headers/adcintrin.h @@ -0,0 +1,160 @@ +/*=== adxintrin.h - ADX intrinsics -=== + * + * 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 + * + *===---=== + */ + +#ifndef __ADCINTRIN_H +#define __ADCINTRIN_H + +#if !defined(__i386__) && !defined(__x86_64__) +#error "This header is only meant to be used on x86 and x64 architecture" +#endif + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) + +/* Use C++ inline semantics in C++, GNU inline for C mode. */ +#if defined(__cplusplus) +#define __INLINE __inline +#else +#define __INLINE static __inline +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/// Adds unsigned 32-bit integers \a __x and \a __y, plus 0 or 1 as indicated +///by the carry flag \a __cf. Stores the unsigned 32-bit sum in the memory +///at \a __p, and returns the 8-bit carry-out (carry flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store32(__p, __x + __y + temp) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c ADC instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +///A 32-bit unsigned addend. +/// \param __y +///A 32-bit unsigned addend. +/// \param __p +///Pointer to memory for storing the sum. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS _addcarry_u32(unsigned char __cf, +unsigned int __x, +unsigned int __y, +unsigned int *__p) { + return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p); +} + +/// Adds unsigned 32-bit integer \a __y to 0 or 1 as indicated by the carry +///flag \a __cf, and subtracts the result from unsigned 32-bit integer +///\a __x. Stores the unsigned 32-bit difference in the memory at \a __p, +///and returns the 8-bit carry-out (carry or overflow flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store32(__p, __x - (__y + temp)) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c SBB instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +///The 32-bit unsigned minuend. +/// \param __y +///The 32-bit unsigned subtrahend. +/// \param __p +///Pointer to memory for storing the difference. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS _subborrow_u32(unsigned char __cf, + unsigned int __x, + unsigned int __y, + unsigned int *__p) { + return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p); +} + +#ifdef __x86_64__ +/// Adds unsigned 64-bit integers \a __x and \a __y, plus 0 or 1 as indicated +///by the carry flag \a __cf. Stores the unsigned 64-bit sum in the memory +///at \a __p, and returns the 8-bit carry-out (carry flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store64(__p, __x + __y + temp) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c ADC instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/75992 >From b6ea2ffe22f414ec79cd9ccd7e47c7b063583bcc Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:55:21 -0500 Subject: [PATCH 1/3] Move Intel ADC instrinsics into a separate file --- clang/lib/Headers/CMakeLists.txt | 1 + clang/lib/Headers/adcintrin.h| 160 +++ clang/lib/Headers/adxintrin.h| 127 +--- clang/lib/Headers/immintrin.h| 3 +- 4 files changed, 163 insertions(+), 128 deletions(-) create mode 100644 clang/lib/Headers/adcintrin.h diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index f8fdd402777e48..735e4e4e3be89b 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -139,6 +139,7 @@ set(webassembly_files set(x86_files # Intrinsics + adcintrin.h adxintrin.h ammintrin.h amxcomplexintrin.h diff --git a/clang/lib/Headers/adcintrin.h b/clang/lib/Headers/adcintrin.h new file mode 100644 index 00..b43322f22297d7 --- /dev/null +++ b/clang/lib/Headers/adcintrin.h @@ -0,0 +1,160 @@ +/*=== adxintrin.h - ADX intrinsics -=== + * + * 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 + * + *===---=== + */ + +#ifndef __ADCINTRIN_H +#define __ADCINTRIN_H + +#if !defined(__i386__) && !defined(__x86_64__) +#error "This header is only meant to be used on x86 and x64 architecture" +#endif + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) + +/* Use C++ inline semantics in C++, GNU inline for C mode. */ +#if defined(__cplusplus) +#define __INLINE __inline +#else +#define __INLINE static __inline +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/// Adds unsigned 32-bit integers \a __x and \a __y, plus 0 or 1 as indicated +///by the carry flag \a __cf. Stores the unsigned 32-bit sum in the memory +///at \a __p, and returns the 8-bit carry-out (carry flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store32(__p, __x + __y + temp) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c ADC instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +///A 32-bit unsigned addend. +/// \param __y +///A 32-bit unsigned addend. +/// \param __p +///Pointer to memory for storing the sum. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS _addcarry_u32(unsigned char __cf, +unsigned int __x, +unsigned int __y, +unsigned int *__p) { + return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p); +} + +/// Adds unsigned 32-bit integer \a __y to 0 or 1 as indicated by the carry +///flag \a __cf, and subtracts the result from unsigned 32-bit integer +///\a __x. Stores the unsigned 32-bit difference in the memory at \a __p, +///and returns the 8-bit carry-out (carry or overflow flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store32(__p, __x - (__y + temp)) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c SBB instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +///The 32-bit unsigned minuend. +/// \param __y +///The 32-bit unsigned subtrahend. +/// \param __p +///Pointer to memory for storing the difference. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS _subborrow_u32(unsigned char __cf, + unsigned int __x, + unsigned int __y, + unsigned int *__p) { + return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p); +} + +#ifdef __x86_64__ +/// Adds unsigned 64-bit integers \a __x and \a __y, plus 0 or 1 as indicated +///by the carry flag \a __cf. Stores the unsigned 64-bit sum in the memory +///at \a __p, and returns the 8-bit carry-out (carry flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store64(__p, __x + __y + temp) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c ADC instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
@@ -580,8 +580,7 @@ _storebe_i64(void * __P, long long __D) { #include #endif -/* Some intrinsics inside adxintrin.h are available only on processors with ADX, - * whereas others are also available at all times. */ MaxEW707 wrote: > add comment for adcintrin.h Up to you. I felt the header names imply that `` has adx specific intrinsics and `` has the always available adc intrinsics. Let me know and I can add a, "/* Intrinsics inside adcintrin.h are available at all times. */", comment above ``. > should we use the same format for adxintrin.h I didn't protect `` since it was unprotected earlier and didn't want to introduce a behavioural change there. For `_MSC_VER` this header isn't large enough to cause the current compile-time issues with MSVC STL. For `__SCE__` the git blame here, https://github.com/llvm/llvm-project/commit/046130490f230559e8dae7d7cb4959bd04f89bb8, appears to have missed guarding this header to prevent accidental usage of these intrinsics on PS4 since Intel ADX isn't available on the PS4 Jaguar chips. https://github.com/llvm/llvm-project/pull/75992 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/75992 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/75992 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/75992 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/75992 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/75992 >From b6ea2ffe22f414ec79cd9ccd7e47c7b063583bcc Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:55:21 -0500 Subject: [PATCH 1/4] Move Intel ADC instrinsics into a separate file --- clang/lib/Headers/CMakeLists.txt | 1 + clang/lib/Headers/adcintrin.h| 160 +++ clang/lib/Headers/adxintrin.h| 127 +--- clang/lib/Headers/immintrin.h| 3 +- 4 files changed, 163 insertions(+), 128 deletions(-) create mode 100644 clang/lib/Headers/adcintrin.h diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index f8fdd402777e48..735e4e4e3be89b 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -139,6 +139,7 @@ set(webassembly_files set(x86_files # Intrinsics + adcintrin.h adxintrin.h ammintrin.h amxcomplexintrin.h diff --git a/clang/lib/Headers/adcintrin.h b/clang/lib/Headers/adcintrin.h new file mode 100644 index 00..b43322f22297d7 --- /dev/null +++ b/clang/lib/Headers/adcintrin.h @@ -0,0 +1,160 @@ +/*=== adxintrin.h - ADX intrinsics -=== + * + * 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 + * + *===---=== + */ + +#ifndef __ADCINTRIN_H +#define __ADCINTRIN_H + +#if !defined(__i386__) && !defined(__x86_64__) +#error "This header is only meant to be used on x86 and x64 architecture" +#endif + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) + +/* Use C++ inline semantics in C++, GNU inline for C mode. */ +#if defined(__cplusplus) +#define __INLINE __inline +#else +#define __INLINE static __inline +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/// Adds unsigned 32-bit integers \a __x and \a __y, plus 0 or 1 as indicated +///by the carry flag \a __cf. Stores the unsigned 32-bit sum in the memory +///at \a __p, and returns the 8-bit carry-out (carry flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store32(__p, __x + __y + temp) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c ADC instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +///A 32-bit unsigned addend. +/// \param __y +///A 32-bit unsigned addend. +/// \param __p +///Pointer to memory for storing the sum. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS _addcarry_u32(unsigned char __cf, +unsigned int __x, +unsigned int __y, +unsigned int *__p) { + return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p); +} + +/// Adds unsigned 32-bit integer \a __y to 0 or 1 as indicated by the carry +///flag \a __cf, and subtracts the result from unsigned 32-bit integer +///\a __x. Stores the unsigned 32-bit difference in the memory at \a __p, +///and returns the 8-bit carry-out (carry or overflow flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store32(__p, __x - (__y + temp)) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c SBB instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +///The 32-bit unsigned minuend. +/// \param __y +///The 32-bit unsigned subtrahend. +/// \param __p +///Pointer to memory for storing the difference. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS _subborrow_u32(unsigned char __cf, + unsigned int __x, + unsigned int __y, + unsigned int *__p) { + return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p); +} + +#ifdef __x86_64__ +/// Adds unsigned 64-bit integers \a __x and \a __y, plus 0 or 1 as indicated +///by the carry flag \a __cf. Stores the unsigned 64-bit sum in the memory +///at \a __p, and returns the 8-bit carry-out (carry flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store64(__p, __x + __y + temp) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c ADC instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
@@ -580,8 +580,7 @@ _storebe_i64(void * __P, long long __D) { #include #endif -/* Some intrinsics inside adxintrin.h are available only on processors with ADX, - * whereas others are also available at all times. */ MaxEW707 wrote: Confirmed that Intel ADX is supported on Ryzen. I checked the Sony PS5 compiler on my work pc and confirmed that `__ADX__` is defined to `1` as expected for the PS5 Ryzen chips so we won't break them. I check the Sony PS4 compiler on my work pc and confirmed that `__ADX__` is not defined as expected for the PS4 Jaguar chips. https://github.com/llvm/llvm-project/pull/75992 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/75992 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/75992 >From b6ea2ffe22f414ec79cd9ccd7e47c7b063583bcc Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:55:21 -0500 Subject: [PATCH 1/5] Move Intel ADC instrinsics into a separate file --- clang/lib/Headers/CMakeLists.txt | 1 + clang/lib/Headers/adcintrin.h| 160 +++ clang/lib/Headers/adxintrin.h| 127 +--- clang/lib/Headers/immintrin.h| 3 +- 4 files changed, 163 insertions(+), 128 deletions(-) create mode 100644 clang/lib/Headers/adcintrin.h diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index f8fdd402777e48..735e4e4e3be89b 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -139,6 +139,7 @@ set(webassembly_files set(x86_files # Intrinsics + adcintrin.h adxintrin.h ammintrin.h amxcomplexintrin.h diff --git a/clang/lib/Headers/adcintrin.h b/clang/lib/Headers/adcintrin.h new file mode 100644 index 00..b43322f22297d7 --- /dev/null +++ b/clang/lib/Headers/adcintrin.h @@ -0,0 +1,160 @@ +/*=== adxintrin.h - ADX intrinsics -=== + * + * 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 + * + *===---=== + */ + +#ifndef __ADCINTRIN_H +#define __ADCINTRIN_H + +#if !defined(__i386__) && !defined(__x86_64__) +#error "This header is only meant to be used on x86 and x64 architecture" +#endif + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) + +/* Use C++ inline semantics in C++, GNU inline for C mode. */ +#if defined(__cplusplus) +#define __INLINE __inline +#else +#define __INLINE static __inline +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/// Adds unsigned 32-bit integers \a __x and \a __y, plus 0 or 1 as indicated +///by the carry flag \a __cf. Stores the unsigned 32-bit sum in the memory +///at \a __p, and returns the 8-bit carry-out (carry flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store32(__p, __x + __y + temp) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c ADC instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +///A 32-bit unsigned addend. +/// \param __y +///A 32-bit unsigned addend. +/// \param __p +///Pointer to memory for storing the sum. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS _addcarry_u32(unsigned char __cf, +unsigned int __x, +unsigned int __y, +unsigned int *__p) { + return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p); +} + +/// Adds unsigned 32-bit integer \a __y to 0 or 1 as indicated by the carry +///flag \a __cf, and subtracts the result from unsigned 32-bit integer +///\a __x. Stores the unsigned 32-bit difference in the memory at \a __p, +///and returns the 8-bit carry-out (carry or overflow flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store32(__p, __x - (__y + temp)) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c SBB instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero value indicates carry. +/// \param __x +///The 32-bit unsigned minuend. +/// \param __y +///The 32-bit unsigned subtrahend. +/// \param __p +///Pointer to memory for storing the difference. +/// \returns The 8-bit unsigned carry-out value. +__INLINE unsigned char __DEFAULT_FN_ATTRS _subborrow_u32(unsigned char __cf, + unsigned int __x, + unsigned int __y, + unsigned int *__p) { + return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p); +} + +#ifdef __x86_64__ +/// Adds unsigned 64-bit integers \a __x and \a __y, plus 0 or 1 as indicated +///by the carry flag \a __cf. Stores the unsigned 64-bit sum in the memory +///at \a __p, and returns the 8-bit carry-out (carry flag). +/// +/// \code{.operation} +/// temp := (__cf == 0) ? 0 : 1 +/// Store64(__p, __x + __y + temp) +/// result := CF +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the \c ADC instruction. +/// +/// \param __cf +///The 8-bit unsigned carry flag; any non-zero
[clang] [clang] Separate Intel ADC instrinsics from ADX intrinsics (PR #75992)
MaxEW707 wrote: > Thanks @MaxEW707 ! I don't have other comments now. Do you need help to merge > it for you? Thanks for the review :). I don't have commit access so we need someone to commit the PR for me. https://github.com/llvm/llvm-project/pull/75992 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][driver] Fix unused var warnings in if statements (PR #76346)
https://github.com/MaxEW707 created https://github.com/llvm/llvm-project/pull/76346 None >From e95623f3e0b89d2499ffe19a4d36eabef9ffa2d4 Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Sun, 24 Dec 2023 20:53:19 -0500 Subject: [PATCH] Fix unused var warnings in clang driver --- clang/lib/Driver/ToolChains/Clang.cpp | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 4783affd3220bc..a76bd9d9881a2e 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3203,13 +3203,13 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, options::OPT_fstrict_float_cast_overflow, false)) CmdArgs.push_back("-fno-strict-float-cast-overflow"); - if (const Arg *A = Args.getLastArg(options::OPT_fcx_limited_range)) + if (Args.getLastArg(options::OPT_fcx_limited_range)) CmdArgs.push_back("-fcx-limited-range"); - if (const Arg *A = Args.getLastArg(options::OPT_fcx_fortran_rules)) + if (Args.getLastArg(options::OPT_fcx_fortran_rules)) CmdArgs.push_back("-fcx-fortran-rules"); - if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_limited_range)) + if (Args.getLastArg(options::OPT_fno_cx_limited_range)) CmdArgs.push_back("-fno-cx-limited-range"); - if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_fortran_rules)) + if (Args.getLastArg(options::OPT_fno_cx_fortran_rules)) CmdArgs.push_back("-fno-cx-fortran-rules"); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][driver] Fix unused var warnings in if statements (PR #76346)
MaxEW707 wrote: Closing this out. Looks like someone beat me to it :). https://github.com/llvm/llvm-project/commit/81ae2a8bb01d38162e0269fc6819584af6d60b03 https://github.com/llvm/llvm-project/pull/76346 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][driver] Fix unused var warnings in if statements (PR #76346)
https://github.com/MaxEW707 closed https://github.com/llvm/llvm-project/pull/76346 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
https://github.com/MaxEW707 created https://github.com/llvm/llvm-project/pull/76596 Background https://godbolt.org/z/hv53svTrq for reference on all of the below. In games debug performance is critical as much as optimized performance. We mainly accomplish this by reducing the amount of function calls being made in debug builds. This does not imply the use of `always_inline` but mainly being diligent in the amount of small functions being called such as getters and accessor functions. As has been gaining support the last couple years and shown by clangs builtin support there are a lot of language level features that are implemented in the standard library such as `std::move` which lead to poor debugging performance, experience and extra compile time due to template instantiations. Since clang already treats these meta cast functions as implicit builtins I will assume the reasoning for such is already a given. However us and many other game studios do not use the `std` and have our own core libraries and/or STL implementations. Therefore we do not get the benefits that clang provides by recognizing certain functions inside the `std` namespace. I will try to list some reasons why we cannot just include `` and use the std functions. I am happy to expand on those reasons in the comments if desired. The EASTL paper [here](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html) is a good starting point and still relevant today in my opinion. Use Case We have our own core libraries and STL implementation. Internally our STL and core libraries use `static_cast` to implement move and forward semantics. However almost all user code, the engine and games themselves, use the provided move and forward template function from these libraries. Currently we have two variants due to historical reasons that will most likely never converge. One is inside a namespace like so `MySTL::move(...)` and one is prefixed as is done in C code like so `MyMove(...)`. ClangCL Last year MSVC added `[[msvc::intrinsic]]` for us game devs [here](https://github.com/MicrosoftDocs/cpp-docs/blob/main/docs/cpp/attributes.md#msvcintrinsic). This was explicitly added as an attribute under the request of us since a lot of us have custom STLs. Clang currently lacks such an attribute which means we can't fully move onto `ClangCL` until we have a similar facility. It would also be helpful to have this attribute for our other platforms which are mostly console vendors who supply their own fork of clang but more on that below. Besides the overloaded use of the word `intrinsic` one downside to this approach is that any warnings that could be generated by knowledge of `std` function implicit behaviours are not generated. Pessimizing move return warnings aren't generated. This is still the case for our explicit core code that uses `static_cast` and something I plan to improve within Clang in the future. Force Inline Move To get around the GCC/Clang we do currently mark our move/forward functions as force inline which is respected in debug. However as the godbolt shows the codegen isn't as good as the builtin in debug. We still incur the compile-time cost compared to the builtin. Just use std While we might be able to use `std::move` via using declarations and macros that expand to `std::move` we cannot at all suffer the include times from vendor std implementations. Do note that we need to ship across different STL versions and vendor STLs that are not one of the major 3 public STLs that we all know. MSVC STL shipped with MSVC 1938 takes 45ms to parse with clang. libstdc++ shipped with Ubuntu 22.04 takes 31ms to parse with clang. libc++ shipped with Ubuntu 22.04 takes 156ms to parse with clang. We cannot include such costly headers into basically every single source file. We also don't want to balloon our PCH headers with expensive std includes and instead keep them for our internal includes as much as possible since the larger the PCH the slower your builds. I haven't looked into `-fpch-instantiate-templates` yet or whether MSVC `/Yc` still has the same behaviour as `-fpch-instantiate-templates`. As MSVC gets more conforming and since we have to deal with vendor clang forks and vendor libraries, some which include templates in their headers, I don't want to be enforcing non-conforming defaults on our game teams using our core libraries. Just declare move Clang only looks for the declaration so we can just declare `move` inside the `std` namespace. We have done this in the past however `libc++` started marking a bunch of functions with `abi_tag` which cannot be redeclared as shown in the godbolt. We still need to ensure that our headers work with `std` headers included after us because there are some platform specific source files that need to interact with vendor or third party libraries who do use and include `std` from t
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/76596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/76596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/76596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/76596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/76596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/76596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/76596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/76596 >From ff2c4b9310950c56a4e2a2b7752f3c3c442a6805 Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Fri, 29 Dec 2023 04:02:10 -0500 Subject: [PATCH 1/3] Add `clang::behaves_like_std(...)` attribute --- clang/include/clang/Basic/Attr.td | 9 +++ clang/include/clang/Basic/AttrDocs.td | 29 .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/lib/Sema/SemaDecl.cpp | 47 +--- clang/lib/Sema/SemaDeclAttr.cpp | 16 + clang/lib/Sema/SemaExpr.cpp | 21 ++ clang/test/CodeGenCXX/builtin-std-move.cpp| 72 +++ clang/test/CodeGenCXX/builtins.cpp| 7 ++ .../SemaCXX/err-invalid-behaves-like-std.cpp | 20 ++ .../SemaCXX/unqualified-std-call-fixits.cpp | 28 +++- clang/test/SemaCXX/warn-pessmizing-move.cpp | 22 ++ clang/test/SemaCXX/warn-redundant-move.cpp| 47 ++-- clang/test/SemaCXX/warn-self-move.cpp | 55 ++ 13 files changed, 359 insertions(+), 16 deletions(-) create mode 100644 clang/test/SemaCXX/err-invalid-behaves-like-std.cpp diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index db17211747b17d..5ad72c7026425d 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1922,6 +1922,15 @@ def Convergent : InheritableAttr { let SimpleHandler = 1; } +def BehavesLikeStd : InheritableAttr { + let Spellings = [Clang<"behaves_like_std">]; + let Subjects = SubjectList<[Function]>; + let Args = [StringArgument<"StdFunction">]; + let LangOpts = [CPlusPlus]; + let PragmaAttributeSupport = 0; + let Documentation = [BehavesLikeStdDocs]; +} + def NoInline : DeclOrStmtAttr { let Spellings = [CustomKeyword<"__noinline__">, GCC<"noinline">, CXX11<"clang", "noinline">, C23<"clang", "noinline">, diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 98a7ecc7fd7df3..5d99bb87587ceb 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -577,6 +577,35 @@ effect applies only to a specific function pointer. For example: }]; } +def BehavesLikeStdDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +This function attribute can be used to tag functions that behave like `std` functions. +This allows custom STL libraries in non-freestanding environments to get the same benefits +as the `std` functions that are treated like builtins without conflicting with the `std` declarations +and without including costly `std` headers. + +This attribute currently supports all `std` functions that are implicitly treated as builtins which include +`std::addressof`, `std::forward`, `std::forward_like`, `std::move`, `std::move_if_noexcept`, and `std::as_const`. + +.. code-block:: c + + namespace MySTL { +template +[[clang::behaves_like_std("move")]] constexpr remove_reference_t&& move(T &&t) noexcept; + } + + template + [[clang::behaves_like_std("move")]] constexpr remove_reference_t&& myMove(T &&t) noexcept; + + void example(std::string a, std::string b) { +foo(MySTL::move(a)); +foo(myMove(b)); + } + + }]; +} + def NoInlineDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index aebb7d9b945c33..4ebcda089ca307 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3132,6 +3132,8 @@ def err_attribute_no_member_function : Error< def err_attribute_parameter_types : Error< "%0 attribute parameter types do not match: parameter %1 of function %2 has type %3, " "but parameter %4 of function %5 has type %6">; +def err_attribute_invalid_std_builtin : Error< + "not a valid std builtin for attribute %0">; def err_attribute_too_many_arguments : Error< "%0 attribute takes no more than %1 argument%s1">; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ffbe317d559995..2498af5c7e6a1a 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9753,14 +9753,11 @@ static Scope *getTagInjectionScope(Scope *S, const LangOptions &LangOpts) { return S; } -/// Determine whether a declaration matches a known function in namespace std. -static bool isStdBuiltin(ASTContext &Ctx, FunctionDecl *FD, - unsigned BuiltinID) { +/// Determine whether a declaration matches a known cast function in namespace +/// std. +static bool isStdCastBuiltin(ASTContext &Ctx, FunctionDecl *FD, + unsigned BuiltinID) { switch (BuiltinID) { - case Builtin::BI__GetExceptionInfo: -// No type checking whatsoever. -return Ctx.g
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
MaxEW707 wrote: > (@MaxEW707 I think having a chat about this informally would be nice.) Sounds good. Let me know the best way to contact you. > While I disagree with the reasoning for not just using std I'll try to give more context here. The main reason is include times and not wanting to work around a variety of vendor STLs who have widely different include times and behaviours. For clang we need to worry about 5 different STLs: MSVC STL, libstdc++, libc++, a vendor STL and some vendor forks of libc++. There are larger issues here when dealing with shipped vendor STLs that are custom or forks of libc++ that we can talk about offline. On one of our smaller projects the PC build is ~16,000 cpp files which includes the generated cpp files, the tools, engine, tests, and the game itself. This is the build that most engineers work on and they usually need to work across a variety of domains since a change in the engine may require a change in the code generator, editor, asset building, the unit tests, the integration tests, etc. On this smaller project one of our console builds which only includes the game itself is around ~4k source files when I last checked. Just adding `#include ` to our `corelib/placement_new.h` header increased build times by ~22 seconds. On this platform the vendor STL `` took 29ms to parse so that means that header was roughly included into ~750 files. That is a build time increase for one file include that we cannot at all live with. We do not use the STL anywhere in our code base. We have our own so just including any STL header also brings in other headers like `type_traits` and their config headers. On MSVC STL it brings in `yvals_core.h` and its dependencies. For us these headers are never amortized because a cpp file might use ``, ``, ``, etc from the STL. At the end of the day we don't want to deal with different STL implementations. We do not use STL and do not want to include it. We do not agree with a lot of language level features like move, placement new, etc being implemented in the std. We would prefer to just have compiler builtins for us like `__builtin_launder` and `__builtin_addressof`. A lot of std headers also aren't small. `` is huge when I just need `move` and `forward`. `` is massive when I just need placement new because we do not at all ever hit global new. libc++ is getting better here, https://libcxx.llvm.org/DesignDocs/HeaderRemovalPolicy.html, but we still have to deal with MSVC STL, vendor STL and vendor forks of libc++. We would rather just have compiler support that everyone can use instead of relying on the STL to implement language level features especially given how much the compiler is being asked to poke into the std lately. In my view C++ should not require the STL to "work". I shouldn't need a library to use a language. https://github.com/llvm/llvm-project/pull/76596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
MaxEW707 wrote: > I don't know whether all of these things should be handled with the same > attribute, or whether they should be handled at all, but they should > definitely be considered when designing this attribute. For this I am more concerned with language level features such as move, forward, reserved placement operator new, etc and not all generic std functions. I can see where that becomes muddy. For example `to_integer`, `to_underlying` or `identity::operator` I don't view as language level features that require a `std` implementation. I view them as a larger issue with high level operations being poorly represented by the language itself. I would love `operator->` and `operator*` on smart pointers that just return a member variable to be replaced with a direct field access. I would love for bitwise operators on enum class types to be replaced directly with the builtin bitwise operation on the underlying type instead of a function call. I would love for `std::byte` to be a builtin type in the compiler like `char8_t` and not be implemented in the std with a special check inside clang for `isStdByte`. Thankfully we can workaround this with the `may_alias` attribute on clang for our own enum class byte type. I would also love for `std::initializer_list` to be a builtin type without this delicate dance with the std and the compiler on specific signatures for the constructor. Look at how MSVC defines `std::initializer_list`. I foresee the compiler increasing making assumptions about the names of functions and types inside the std namespace like `std::to_underlying`, `std::byte`, etc. `clang::behaves_like_std` gives users an easy to tell the compiler to make those same assumptions with user defined names. There are cases where the std functions have other implicit properties. Reserved placement operator new can be assumed to not have to check the returned pointer for null. If you implement your own placement operator new you do not get this benefit. MSVC only removes this check for the reserved placement new but thankfully provides the define `__PLACEMENT_NEW_INLINE` if you decide to define it yourself. I believe you can work this with the `returns_nonnull` attribute on clang when I checked some months back. However clang still does the function call in debug if you are not the global reserved placement operator new which sucks. Maybe for stuff like `operator->` on a smart pointer the compiler will start looking at `std::unique_ptr::operator->`. Maybe for these facilities we instead have a more generic attribute like `[[clang::treat_as_macro]]` which more closely aligns with the semantics of `mvsc::intrinsic`. Maybe we improve `always_inline` code gen for small functions like `std::move` and `operator->` on a object that just returns its member variable to have the same assembly in debug as if those functions were implemented like macros. I haven't thought too much about those other cases yet but if `always_inline` on `MyMove` produced the same code in debug as `std::move` that gets me 90% of what I want and that would also probably fix all the other small function calls. My 2c. https://github.com/llvm/llvm-project/pull/76596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)
https://github.com/MaxEW707 created https://github.com/llvm/llvm-project/pull/76646 There are code bases that inline `std::move` manually via `static_cast`. Treat a static cast to an xvalue as an inlined `std::move` call and warn on a self move. >From a081f8266f24405523e6d283318bd898fd2d376a Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Sat, 30 Dec 2023 22:00:38 -0500 Subject: [PATCH] Warn on self move for inlined static cast --- clang/lib/Sema/SemaChecking.cpp | 19 ++- clang/test/SemaCXX/warn-self-move.cpp | 13 + 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 2a69325f029514..a21410434d8099 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -18843,17 +18843,26 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, LHSExpr = LHSExpr->IgnoreParenImpCasts(); RHSExpr = RHSExpr->IgnoreParenImpCasts(); - // Check for a call expression + // Check for a call expression or static_cast expression const CallExpr *CE = dyn_cast(RHSExpr); - if (!CE || CE->getNumArgs() != 1) + const CXXStaticCastExpr *CXXSCE = dyn_cast(RHSExpr); + if (!CE && !CXXSCE) return; // Check for a call to std::move - if (!CE->isCallToStdMove()) + if (CE && (CE->getNumArgs() != 1 || !CE->isCallToStdMove())) return; - // Get argument from std::move - RHSExpr = CE->getArg(0); + // Check for a static_cast(..) to an xvalue which we can treat as an + // inlined std::move + if (CXXSCE && !CXXSCE->isXValue()) +return; + + // Get argument from std::move or static_cast + if (CE) +RHSExpr = CE->getArg(0); + else +RHSExpr = CXXSCE->getSubExpr(); const DeclRefExpr *LHSDeclRef = dyn_cast(LHSExpr); const DeclRefExpr *RHSDeclRef = dyn_cast(RHSExpr); diff --git a/clang/test/SemaCXX/warn-self-move.cpp b/clang/test/SemaCXX/warn-self-move.cpp index 0987e9b6bf6017..d0158626424142 100644 --- a/clang/test/SemaCXX/warn-self-move.cpp +++ b/clang/test/SemaCXX/warn-self-move.cpp @@ -16,6 +16,9 @@ void int_test() { x = std::move(x); // expected-warning{{explicitly moving}} (x) = std::move(x); // expected-warning{{explicitly moving}} + x = static_cast(x); // expected-warning{{explicitly moving}} + (x) = static_cast(x); // expected-warning{{explicitly moving}} + using std::move; x = move(x); // expected-warning{{explicitly moving}} \ expected-warning {{unqualified call to 'std::move}} @@ -26,6 +29,9 @@ void global_int_test() { global = std::move(global); // expected-warning{{explicitly moving}} (global) = std::move(global); // expected-warning{{explicitly moving}} + global = static_cast(global); // expected-warning{{explicitly moving}} + (global) = static_cast(global); // expected-warning{{explicitly moving}} + using std::move; global = move(global); // expected-warning{{explicitly moving}} \ expected-warning {{unqualified call to 'std::move}} @@ -35,11 +41,14 @@ class field_test { int x; field_test(field_test&& other) { x = std::move(x); // expected-warning{{explicitly moving}} +x = static_cast(x); // expected-warning{{explicitly moving}} x = std::move(other.x); other.x = std::move(x); other.x = std::move(other.x); // expected-warning{{explicitly moving}} +other.x = static_cast(other.x); // expected-warning{{explicitly moving}} } void withSuggest(int x) { +x = static_cast(x); // expected-warning{{explicitly moving variable of type 'int' to itself; did you mean to move to member 'x'?}} x = std::move(x); // expected-warning{{explicitly moving variable of type 'int' to itself; did you mean to move to member 'x'?}} } }; @@ -50,11 +59,15 @@ struct C { C() {}; ~C() {} }; void struct_test() { A a; a = std::move(a); // expected-warning{{explicitly moving}} + a = static_cast(a); // expected-warning{{explicitly moving}} B b; b = std::move(b); // expected-warning{{explicitly moving}} + b = static_cast(b); // expected-warning{{explicitly moving}} b.a = std::move(b.a); // expected-warning{{explicitly moving}} + b.a = static_cast(b.a); // expected-warning{{explicitly moving}} C c; c = std::move(c); // expected-warning{{explicitly moving}} + c = static_cast(c); // expected-warning{{explicitly moving}} } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/76646 >From a081f8266f24405523e6d283318bd898fd2d376a Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Sat, 30 Dec 2023 22:00:38 -0500 Subject: [PATCH 1/2] Warn on self move for inlined static cast --- clang/lib/Sema/SemaChecking.cpp | 19 ++- clang/test/SemaCXX/warn-self-move.cpp | 13 + 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 2a69325f029514..a21410434d8099 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -18843,17 +18843,26 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, LHSExpr = LHSExpr->IgnoreParenImpCasts(); RHSExpr = RHSExpr->IgnoreParenImpCasts(); - // Check for a call expression + // Check for a call expression or static_cast expression const CallExpr *CE = dyn_cast(RHSExpr); - if (!CE || CE->getNumArgs() != 1) + const CXXStaticCastExpr *CXXSCE = dyn_cast(RHSExpr); + if (!CE && !CXXSCE) return; // Check for a call to std::move - if (!CE->isCallToStdMove()) + if (CE && (CE->getNumArgs() != 1 || !CE->isCallToStdMove())) return; - // Get argument from std::move - RHSExpr = CE->getArg(0); + // Check for a static_cast(..) to an xvalue which we can treat as an + // inlined std::move + if (CXXSCE && !CXXSCE->isXValue()) +return; + + // Get argument from std::move or static_cast + if (CE) +RHSExpr = CE->getArg(0); + else +RHSExpr = CXXSCE->getSubExpr(); const DeclRefExpr *LHSDeclRef = dyn_cast(LHSExpr); const DeclRefExpr *RHSDeclRef = dyn_cast(RHSExpr); diff --git a/clang/test/SemaCXX/warn-self-move.cpp b/clang/test/SemaCXX/warn-self-move.cpp index 0987e9b6bf6017..d0158626424142 100644 --- a/clang/test/SemaCXX/warn-self-move.cpp +++ b/clang/test/SemaCXX/warn-self-move.cpp @@ -16,6 +16,9 @@ void int_test() { x = std::move(x); // expected-warning{{explicitly moving}} (x) = std::move(x); // expected-warning{{explicitly moving}} + x = static_cast(x); // expected-warning{{explicitly moving}} + (x) = static_cast(x); // expected-warning{{explicitly moving}} + using std::move; x = move(x); // expected-warning{{explicitly moving}} \ expected-warning {{unqualified call to 'std::move}} @@ -26,6 +29,9 @@ void global_int_test() { global = std::move(global); // expected-warning{{explicitly moving}} (global) = std::move(global); // expected-warning{{explicitly moving}} + global = static_cast(global); // expected-warning{{explicitly moving}} + (global) = static_cast(global); // expected-warning{{explicitly moving}} + using std::move; global = move(global); // expected-warning{{explicitly moving}} \ expected-warning {{unqualified call to 'std::move}} @@ -35,11 +41,14 @@ class field_test { int x; field_test(field_test&& other) { x = std::move(x); // expected-warning{{explicitly moving}} +x = static_cast(x); // expected-warning{{explicitly moving}} x = std::move(other.x); other.x = std::move(x); other.x = std::move(other.x); // expected-warning{{explicitly moving}} +other.x = static_cast(other.x); // expected-warning{{explicitly moving}} } void withSuggest(int x) { +x = static_cast(x); // expected-warning{{explicitly moving variable of type 'int' to itself; did you mean to move to member 'x'?}} x = std::move(x); // expected-warning{{explicitly moving variable of type 'int' to itself; did you mean to move to member 'x'?}} } }; @@ -50,11 +59,15 @@ struct C { C() {}; ~C() {} }; void struct_test() { A a; a = std::move(a); // expected-warning{{explicitly moving}} + a = static_cast(a); // expected-warning{{explicitly moving}} B b; b = std::move(b); // expected-warning{{explicitly moving}} + b = static_cast(b); // expected-warning{{explicitly moving}} b.a = std::move(b.a); // expected-warning{{explicitly moving}} + b.a = static_cast(b.a); // expected-warning{{explicitly moving}} C c; c = std::move(c); // expected-warning{{explicitly moving}} + c = static_cast(c); // expected-warning{{explicitly moving}} } >From ecd9d5bf0d3fa0bc3e64266c6e7586da25438652 Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Sun, 31 Dec 2023 17:47:03 -0500 Subject: [PATCH 2/2] use auto --- clang/lib/Sema/SemaChecking.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a21410434d8099..ecb3269d0d30c7 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -18845,7 +18845,7 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, // Check for a call expression or static_cast expression const CallExpr *CE = dy
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
MaxEW707 wrote: I appreciate the discussions. I know I have a tendency to get ranty in my writing so I just want to be clear that I mean no malice. I can further explain my side. > Include times > Modules should ease that pain I don't know how else to make it clear that we will never be including std headers from our core library headers and within the core engine itself. The include times are a non-starter. If the verdict is just use std, we are going to continue just marking these functions as `always_inline` and live with the worse code gen than a builtin but still better than a function call. Even if libc++ becomes tolerable we have to deal with msvc stl, libstdc++, libc++, SCE stl, and vendor forks of libc++ that I will not mention since this specific company is super duper litigious over the most minor things. If I could have an attribute that solves my problems without header includes and I can chuck it on the implementations in our core libraries then I am golden instead of trying to work around various std libraries. I also want to highlight that we in particular have a wide range of platform support. We were just able to get rid of VS2015 early 2023. We also finally removed GCC4.8 late 2022. We still have to ship on a custom toolchain of VS2017 msvc for Xbox One. We have game teams that are also on the latest VS2022. Our macOS/iPhone support is quite wide as well. SCE is very quick to upgrade their clang so we are on Clang 16 now if my memory is correct there on SCE. Any change to libc++ does not help SCE STL or the other vendors shipping their own fork of clang + libc++. A lot of these vendors will upgrade clang but not libc++ as well. On our Linux servers we have such a variety of distros and GCC/Clang versions. Regarding modules. Try moving the titanic that is [insert favourite game here that is shipping content every year]. Now try moving 3+ titanics. Try moving that when you still have platforms that cannot move past VS2017. Plus some vendors have no intention, as far as I am aware, of supporting modules in their vendor libraries which do include `` and such for move/forward. Apple Clang + Xcode still don't support modules last I checked. We haven't upgraded to Xcode 15 yet. We have our own build system generator. We have our own package management system. We have our stuff working well with PCH files where needed. We have all the infrastructure set up to promote fast builds from the core libraries down the stack. I don't foresee us even considering modules for 10+ years. > More general observations on the "using c++ without the STL thing": > I don't think this is a major consideration of the language/standard > committee going forward. > Reflection will also have a dependency on the STL I don't want to speak for my peers but I think I can speak to the general sentiment of my community. This is why among many many many other reasons SG14 failed and why a lot of us in the game dev community have just given up. Some are at companies that do not allow any form of open source contributions or participation in the C++ discourse. That seems to be changing. Thankfully I am at a company that does allows me to make these contributions here on my free time, LLVM license makes it easy for me to do so and I have the means to try to push them through. Selfishly for me but also for the game dev community at large. Especially nowadays where we can basically ship with clang on almost every platform, a change in clang affects our entire ecosystem. It seems gone are the days of custom vendor compilers for every platform with EDG as the frontend. I have followed the Reflection TS and its fine. At every game company I worked at our reflection needs are so esoteric that we are going to continue writing our own with our own code generators. Almost every single game engine has its own way to do some form of dynamic casting, similar reasons that llvm also seems to have its own infrastructure from reading the docs, and that casting is usually very tightly integrated with the engine's reflection system. Trying to highlight that in general a lot of these papers, for the language itself or the std, will never solve the esoteric needs of us or handle the esoteric platforms that we support. Not everything uses the BSD sockets API for example. Win32 is considered BSD compared to the stuff I've seen. We just want a systems language that allows us to accomplish system level tasks while still retaining a lot of really useful core features like templates, easy support for intrusive data structures, control over allocations, etc. As mentioned above our Linux servers use a variety of distros. The server software running in our datacentres still uses all our core libraries like all the game software but has more liberty with what game teams can run. We are less strict on what the various amount of server services are allowed to use since that software is usually tightly w
[compiler-rt] [libcxx] [mlir] [openmp] [lldb] [lld] [clang-tools-extra] [llvm] [clang] [flang] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)
MaxEW707 wrote: > I would like some measurements so we can compare build times on Windows. I took some benchmarks with `-ftime-trace` on the parse times with and without this change. Pretty much all the big hitters, string/vector/map/algorithm, includes `` which includes `` which includes ``. The test file used looked as follows to simulate some common stl includes. ``` #include #include #include ``` clang-cl 16 frontend took ~190ms to parse those 3 headers. `intrin.h` took ~32ms to parse. clang-cl built with this PR frontend took ~1368ms to parse. `intrin.h` took ~969ms to parse. Most of that time is from `` as expected. `intrin0.h` took ~2ms to parse. It is known that `immintrin.h` and `x86intrin.h` being the everything header definitely makes it an **expensive** include. I don't need to compile any project to know that include time difference will be felt by any code that uses STL. MSVC STL ships with each compiler upgrade. VS has a separate dir for each installed msvc, `VC\Tools\MSVC\14.38.33130` for MSVC 1938, and each installed compiler has a specific version of msvc stl shipped with it under, `VC\Tools\MSVC\[version]\include`. Only one version of clang-cl is shipped with VS at a time and it will always point to the latest `VCToolsDir` via the clang driver unless clang is passed an explicit dir on the command line by the user. For example VS2022 17.7 upgraded from clang-cl 15 to clang-cl 16. From that point on-wards only clang-cl 16 exists on disk in your VS install. That seems to correspond to what was said here, https://github.com/microsoft/STL/pull/4282#discussion_r1441191186, every shipped version of MSVC STL supports only the latest compilers provided by VS. We have some options. I am fine with whatever the consensus is as long as I can move this over the finish line. 1. Users who upgrade clang-cl before MSVC STL officially supports the new version of clang-cl will suffer slower builds. I would classify this as an unsupported config since once VS ships with support for the new clang-cl, intentionally building against an older `VCToolsDir` will also incur the include overhead. Up to you guys if view this as an unsupported config. 2. Add a config define that users can define to enable the old behaviour in the interim. Once MSVC STL supports the new version of clang-cl we can remove this config define in the next release. 3. Release clang with `intrin0.h`. Get a change into MSVC STL. Wait for MSVC STL release. Release another clang with `intrin.h` changes. I am not well versed on what changes clang allows in patch or minor releases but this feels like it would have a long lag time before clang-cl can become usable for us. https://github.com/llvm/llvm-project/pull/75711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[openmp] [flang] [mlir] [lldb] [clang-tools-extra] [llvm] [libcxx] [lld] [compiler-rt] [clang] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)
MaxEW707 wrote: > Users (Chromium included) use recent versions of Clang that are not vendored > by Microsoft. Users can also use the LLVM OSS releases. I think most users > probably won't notice the compile time regression, and it will silently go > away the next time the update MSVC, but if they do and they care (and this > should be in the release notes), it would be nice to have a macro to get the > old behavior. I thought of another solution this morning that can work. Looks like we already have precedent with redefining macros in clang's interposing MSVC headers. `vadefs.h` for example. MSVC STL would like to replace [_STL_INTRIN_HEADER](https://github.com/microsoft/STL/blob/main/stl/inc/yvals_core.h#L2038) macro with just `#include ` when they support the version of clang shipped with `intrin0.h`. We could provide our own `yvals_core.h` header like so: ``` #include_next #if defined(_MSC_VER_) && defined(_STL_INTRIN_HEADER) #undef _STL_INTRIN_HEADER #define _STL_INTRIN_HEADER #include #endif ``` This should also fix users upgrading clang while still building against an older MSVC STL. Once MSVC STL moves forward we can probably remove this interposing header sometime in the future. https://github.com/llvm/llvm-project/pull/75711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [lldb] [llvm] [openmp] [clang] [compiler-rt] [libcxx] [lld] [flang] [mlir] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)
MaxEW707 wrote: > #include > >clang-cl 16 frontend took ~190ms to parse those 3 headers. intrin.h took ~32ms >to parse. > >clang-cl built with this PR frontend took ~1368ms to parse. intrin.h took >~969ms to parse. Most of that time is from as expected. >intrin0.h took ~2ms to parse. Did this same test with the most recent change that included the `yvals_core.h` interposing header. The parse time was around ~170ms since `intrin0.h` is still cheaper than the old `intrin.h`. This was tested with the MSVC STL shipped with MSVC 1938. https://github.com/llvm/llvm-project/pull/75711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen] Fix `CanSkipVTablePointerInitialization` for dynamic classes with a trivial anonymous union (PR #84651)
MaxEW707 wrote: @AaronBallman @efriedma-quic Pinging you two for a review. Looking through the history of `CGClass.cpp` you guys appear to be the common reviewers and the CodeOwners file didn't have any information for who owns `CodeGen`. Feel free to add anyone who may be a better fit. Thanks :). https://github.com/llvm/llvm-project/pull/84651 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen] Fix `CanSkipVTablePointerInitialization` for dynamic classes with a trivial anonymous union (PR #84651)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/84651 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-cl] Allow a colon after /Fo option (PR #87209)
MaxEW707 wrote: @rnk for review. LGTM! >From experience with msvc the docs are very much outdated. For example almost >all path options accept the `:` form. For example `/Fd:` is valid even though the msdn docs do not state that. https://learn.microsoft.com/en-us/cpp/build/reference/fd-program-database-file-name?view=msvc-170. Try out the following and it works, `cl.exe /std:c++17 /Fo:test.obj /Fd:test.pdb /Zi /c test.cpp`. Thankfully from memory VS2019+ `/?` lists all the options that accept a colon form. The output of msvc 1939 `/?` shows the following: ``` /Fd: name .PDB file /Fe: name executable file /Fm: name map file /Fo: name object file /Fp: name .PCH file /FR: name extended .SBR file /Fi: name preprocessed file ``` showing that these options do in fact accept the colon form even though MSDN is outdated. I think it would be super appreciated if we can fix all instances where clang-cl fails to accept the colon form for any non-ignored options that are supported if you got the time. If not no worries it was on my backlog anyways when I get time heh :). https://github.com/llvm/llvm-project/pull/87209 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen] Fix `CanSkipVTablePointerInitialization` for dynamic classes with a trivial anonymous union (PR #84651)
@@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -emit-llvm -o - | FileCheck %s MaxEW707 wrote: Fair point since they are both Itanium ABI. I'll remove the line. https://github.com/llvm/llvm-project/pull/84651 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen] Fix `CanSkipVTablePointerInitialization` for dynamic classes with a trivial anonymous union (PR #84651)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/84651 >From 28cbaad3c16e985306c7b977cb7d9e8e89c39a07 Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Sat, 9 Mar 2024 15:40:52 -0500 Subject: [PATCH 1/2] Fix `CanSkipVTablePointerInitialization` for dynamic classes with an anonymous union --- clang/lib/CodeGen/CGClass.cpp | 2 +- .../skip-vtable-pointer-initialization.cpp| 63 +++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index d18f186ce5b415..ca3ac7142af9c0 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1395,7 +1395,7 @@ FieldHasTrivialDestructorBody(ASTContext &Context, // The destructor for an implicit anonymous union member is never invoked. if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion()) -return false; +return true; return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl); } diff --git a/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp b/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp index eb8f21b57aa7b6..d99a45869fdb54 100644 --- a/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp +++ b/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -emit-llvm -o - | FileCheck %s // See Test9 for test description. // CHECK: @_ZTTN5Test91BE = linkonce_odr unnamed_addr constant @@ -198,3 +199,65 @@ struct C : virtual B { C::~C() {} } + +namespace Test10 { + +// Check that we don't initialize the vtable pointer in A::~A(), since the class has an anonymous union which +// never has its destructor invoked. +struct A { +virtual void f(); +~A(); + +union +{ +int i; +unsigned u; +}; +}; + +// CHECK-LABEL: define{{.*}} void @_ZN6Test101AD2Ev +// CHECK-NOT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN6Test101AE, i32 0, inrange i32 0, i32 2), ptr +A::~A() { +} + +} + +namespace Test11 { + +// Check that we don't initialize the vtable pointer in A::~A(), even if the base class has a non trivial destructor. +struct Field { +~Field(); +}; + +struct A : public Field { +virtual void f(); +~A(); +}; + +// CHECK-LABEL: define{{.*}} void @_ZN6Test111AD2Ev +// CHECK-NOT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN6Test111AE, i32 0, inrange i32 0, i32 2), ptr +A::~A() { +} + +} + +namespace Test12 { + +// Check that we don't initialize the vtable pointer in A::~A(), since the class has an anonymous struct with trivial fields. +struct A { +virtual void f(); +~A(); + +struct +{ +int i; +unsigned u; +}; +}; + +// CHECK-LABEL: define{{.*}} void @_ZN6Test121AD2Ev +// CHECK-NOT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN6Test121AE, i32 0, inrange i32 0, i32 2), ptr +A::~A() { +} + +} >From fd190fb64877636c94cbaf73d1977018e592a622 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 1 Apr 2024 20:36:54 -0400 Subject: [PATCH 2/2] remove RUN line in unit test --- clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp b/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp index d99a45869fdb54..9c5388fd64a502 100644 --- a/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp +++ b/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -emit-llvm -o - | FileCheck %s // See Test9 for test description. // CHECK: @_ZTTN5Test91BE = linkonce_odr unnamed_addr constant ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)
MaxEW707 wrote: Ping Wondering if there is anything else required of me to progress this PR forward. Let me know :). https://github.com/llvm/llvm-project/pull/75711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/76646 >From a081f8266f24405523e6d283318bd898fd2d376a Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Sat, 30 Dec 2023 22:00:38 -0500 Subject: [PATCH 1/4] Warn on self move for inlined static cast --- clang/lib/Sema/SemaChecking.cpp | 19 ++- clang/test/SemaCXX/warn-self-move.cpp | 13 + 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 2a69325f029514..a21410434d8099 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -18843,17 +18843,26 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, LHSExpr = LHSExpr->IgnoreParenImpCasts(); RHSExpr = RHSExpr->IgnoreParenImpCasts(); - // Check for a call expression + // Check for a call expression or static_cast expression const CallExpr *CE = dyn_cast(RHSExpr); - if (!CE || CE->getNumArgs() != 1) + const CXXStaticCastExpr *CXXSCE = dyn_cast(RHSExpr); + if (!CE && !CXXSCE) return; // Check for a call to std::move - if (!CE->isCallToStdMove()) + if (CE && (CE->getNumArgs() != 1 || !CE->isCallToStdMove())) return; - // Get argument from std::move - RHSExpr = CE->getArg(0); + // Check for a static_cast(..) to an xvalue which we can treat as an + // inlined std::move + if (CXXSCE && !CXXSCE->isXValue()) +return; + + // Get argument from std::move or static_cast + if (CE) +RHSExpr = CE->getArg(0); + else +RHSExpr = CXXSCE->getSubExpr(); const DeclRefExpr *LHSDeclRef = dyn_cast(LHSExpr); const DeclRefExpr *RHSDeclRef = dyn_cast(RHSExpr); diff --git a/clang/test/SemaCXX/warn-self-move.cpp b/clang/test/SemaCXX/warn-self-move.cpp index 0987e9b6bf6017..d0158626424142 100644 --- a/clang/test/SemaCXX/warn-self-move.cpp +++ b/clang/test/SemaCXX/warn-self-move.cpp @@ -16,6 +16,9 @@ void int_test() { x = std::move(x); // expected-warning{{explicitly moving}} (x) = std::move(x); // expected-warning{{explicitly moving}} + x = static_cast(x); // expected-warning{{explicitly moving}} + (x) = static_cast(x); // expected-warning{{explicitly moving}} + using std::move; x = move(x); // expected-warning{{explicitly moving}} \ expected-warning {{unqualified call to 'std::move}} @@ -26,6 +29,9 @@ void global_int_test() { global = std::move(global); // expected-warning{{explicitly moving}} (global) = std::move(global); // expected-warning{{explicitly moving}} + global = static_cast(global); // expected-warning{{explicitly moving}} + (global) = static_cast(global); // expected-warning{{explicitly moving}} + using std::move; global = move(global); // expected-warning{{explicitly moving}} \ expected-warning {{unqualified call to 'std::move}} @@ -35,11 +41,14 @@ class field_test { int x; field_test(field_test&& other) { x = std::move(x); // expected-warning{{explicitly moving}} +x = static_cast(x); // expected-warning{{explicitly moving}} x = std::move(other.x); other.x = std::move(x); other.x = std::move(other.x); // expected-warning{{explicitly moving}} +other.x = static_cast(other.x); // expected-warning{{explicitly moving}} } void withSuggest(int x) { +x = static_cast(x); // expected-warning{{explicitly moving variable of type 'int' to itself; did you mean to move to member 'x'?}} x = std::move(x); // expected-warning{{explicitly moving variable of type 'int' to itself; did you mean to move to member 'x'?}} } }; @@ -50,11 +59,15 @@ struct C { C() {}; ~C() {} }; void struct_test() { A a; a = std::move(a); // expected-warning{{explicitly moving}} + a = static_cast(a); // expected-warning{{explicitly moving}} B b; b = std::move(b); // expected-warning{{explicitly moving}} + b = static_cast(b); // expected-warning{{explicitly moving}} b.a = std::move(b.a); // expected-warning{{explicitly moving}} + b.a = static_cast(b.a); // expected-warning{{explicitly moving}} C c; c = std::move(c); // expected-warning{{explicitly moving}} + c = static_cast(c); // expected-warning{{explicitly moving}} } >From ecd9d5bf0d3fa0bc3e64266c6e7586da25438652 Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Sun, 31 Dec 2023 17:47:03 -0500 Subject: [PATCH 2/4] use auto --- clang/lib/Sema/SemaChecking.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a21410434d8099..ecb3269d0d30c7 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -18845,7 +18845,7 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, // Check for a call expression or static_cast expression const CallExpr *CE = dy
[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)
MaxEW707 wrote: Thanks all for the review :). I will need one of you to commit on my behalf since I do not have write access. https://github.com/llvm/llvm-project/pull/76646 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)
MaxEW707 wrote: Friendly reminder that I require someone to commit on my behalf since I do not have write access :). https://github.com/llvm/llvm-project/pull/75711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen] Fix `CanSkipVTablePointerInitialization` for dynamic classes with a trivial anonymous union (PR #84651)
https://github.com/MaxEW707 created https://github.com/llvm/llvm-project/pull/84651 Hit this when trying upgrade an old project of mine. I couldn't find a corresponding existing issue for this when spelunking the open issues here on github. Thankfully I can work-around it today with the `[[clang::no_destroy]]` attribute for my use case. However it should still be properly fixed. ### Issue and History ### https://godbolt.org/z/EYnhce8MK for reference. All subsequent text below refers to the example in the godbolt above. Anonymous unions never have their destructor invoked automatically. Therefore we can skip vtable initialization of the destructor of a dynamic class if that destructor effectively does no work. This worked previously as the following check would be hit and return true for the trivial anonymous union, https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGClass.cpp#L1348, resulting in the code skipping vtable initialization. This was broken here https://github.com/llvm/llvm-project/commit/982bbf404eba2d968afda5c674d4821652159c53 in relation to comments made on this review here https://reviews.llvm.org/D10508. ### Fixes ### The check the code is doing is correct however the return value is inverted. We want to return true here since a field with anonymous union never has its destructor invoked and thus effectively has a trivial destructor body from the perspective of requiring vtable init in the parent dynamic class. Also added some extra missing unit tests to test for this use case. >From 28cbaad3c16e985306c7b977cb7d9e8e89c39a07 Mon Sep 17 00:00:00 2001 From: MaxEW707 <82551778+maxew...@users.noreply.github.com> Date: Sat, 9 Mar 2024 15:40:52 -0500 Subject: [PATCH] Fix `CanSkipVTablePointerInitialization` for dynamic classes with an anonymous union --- clang/lib/CodeGen/CGClass.cpp | 2 +- .../skip-vtable-pointer-initialization.cpp| 63 +++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index d18f186ce5b415..ca3ac7142af9c0 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1395,7 +1395,7 @@ FieldHasTrivialDestructorBody(ASTContext &Context, // The destructor for an implicit anonymous union member is never invoked. if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion()) -return false; +return true; return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl); } diff --git a/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp b/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp index eb8f21b57aa7b6..d99a45869fdb54 100644 --- a/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp +++ b/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -emit-llvm -o - | FileCheck %s // See Test9 for test description. // CHECK: @_ZTTN5Test91BE = linkonce_odr unnamed_addr constant @@ -198,3 +199,65 @@ struct C : virtual B { C::~C() {} } + +namespace Test10 { + +// Check that we don't initialize the vtable pointer in A::~A(), since the class has an anonymous union which +// never has its destructor invoked. +struct A { +virtual void f(); +~A(); + +union +{ +int i; +unsigned u; +}; +}; + +// CHECK-LABEL: define{{.*}} void @_ZN6Test101AD2Ev +// CHECK-NOT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN6Test101AE, i32 0, inrange i32 0, i32 2), ptr +A::~A() { +} + +} + +namespace Test11 { + +// Check that we don't initialize the vtable pointer in A::~A(), even if the base class has a non trivial destructor. +struct Field { +~Field(); +}; + +struct A : public Field { +virtual void f(); +~A(); +}; + +// CHECK-LABEL: define{{.*}} void @_ZN6Test111AD2Ev +// CHECK-NOT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN6Test111AE, i32 0, inrange i32 0, i32 2), ptr +A::~A() { +} + +} + +namespace Test12 { + +// Check that we don't initialize the vtable pointer in A::~A(), since the class has an anonymous struct with trivial fields. +struct A { +virtual void f(); +~A(); + +struct +{ +int i; +unsigned u; +}; +}; + +// CHECK-LABEL: define{{.*}} void @_ZN6Test121AD2Ev +// CHECK-NOT: store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN6Test121AE, i32 0, inrange i32 0, i32 2), ptr +A::~A() { +} + +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen] Fix `CanSkipVTablePointerInitialization` for dynamic classes with a trivial anonymous union (PR #84651)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/84651 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)
MaxEW707 wrote: I will need someone to commit on my behalf since I do not have write access. > lgtm, and good to land provided you do a quick re-check to confirm that this > doesn't tank compile times now with that part included. Thanks! The include times below are done with the following source file using a locally release build of clang, `-ftime-trace`, and msvc stl shipped with MSVC 1939. ``` #include #include #include ``` clang-cl.exe without `yvals_core.h` shadowing takes ~1,344 ms in the frontend. `intrin.h` took ~955 ms to parse. clang-cl.exe with `yvals_core.h` shadowing takes ~395 ms in the frontend. `intrin0.h` took ~1.4 ms to parse. https://github.com/llvm/llvm-project/pull/75711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)
@@ -0,0 +1,26 @@ +/* === vadefs.h ---=== + * + * 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 + * + *===---=== + */ + +/* Only include this if we are aiming for MSVC compatibility. */ MaxEW707 wrote: We do not need `/* */`. I was just copying from the other files in this folder for the copyright header and clang-format didn't complain. I'll give the style guide a read and get this fixed :). https://github.com/llvm/llvm-project/pull/75711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/75711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)
MaxEW707 wrote: Just want to say thanks for everyone taking the time to review the PR and providing feedback :). Looking forward to using this in the next release of clang-cl. > I'm a bit worried that we don't have any test coverage for this file to begin > with, so it's a bit hard to validate that the changes are correct, but we're > early enough in a release cycle that I think we'll get feedback with plenty > of time to address unintentional fallout. I'll look into adding unit tests next week in a separate PR. If not it will be closer towards the end of March due to personal things. If any issues pop up feel free to @ me. I don't intend to commit and dash :). > The changes should come with a release note in clang/docs/ReleaseNotes.rst so > that users know about the compile time performance improvements. Done. Feel free to reword the release notes as necessary. I believe I landed on something that is informative but succinct. https://github.com/llvm/llvm-project/pull/75711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)
MaxEW707 wrote: Ping https://github.com/llvm/llvm-project/pull/76646 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add `clang::behaves_like_std(...)` attribute (PR #76596)
MaxEW707 wrote: > It's not ready, but I have a draft for a much more general attribute: #78071 I was playing around with your draft PR and I do prefer your solution over mine. It will even help to cleanup my custom `xmmintrin.h` header that we have to reduce include times from SSE headers. Let me know if you want me to close this our in favour of your PR. https://github.com/llvm/llvm-project/pull/76596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Fix MSVC 1920+ auto NTTP mangling for pointers to members (PR #97007)
https://github.com/MaxEW707 closed https://github.com/llvm/llvm-project/pull/97007 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Adds an arbitrary pseudonym to clang"s windows mangler... (PR #97792)
MaxEW707 wrote: @memory-thrasher Godbolt for reference: https://godbolt.org/z/b9v8KhPET I don't follow that MSVC 1920+ does not support this mangling properly. It appears that it does. I haven't dug too deep into the C++20 MSVC mangling for NTTP yet but it does appear MSVC does support this properly in its mangling scheme. I am not opposed to doing our own ad-hoc mangling for now to just get this working but in general `-msvc` triple is supposed to adhere to msvc mangling including all its bugs. I'll try to get to this PR sometime this weekend under the assumption we will use the current custom ad-hoc mangling that isn't MSVC compatible in the interim. Funnily enough we were just discussing this here, https://github.com/llvm/llvm-project/issues/94650#issuecomment-2209626547, and I was about to write up a discourse on such a discussion tomorrow morning. https://github.com/llvm/llvm-project/pull/97792 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix Microsoft ABI inheritance model when member pointer is used in a base specifier (PR #91990)
@@ -598,7 +599,9 @@ class CXXRecordDecl : public RecordDecl { return !hasDefinition() || !isDynamicClass() || hasAnyDependentBases(); } - void setIsParsingBaseSpecifiers() { data().IsParsingBaseSpecifiers = true; } + void setIsParsingBaseSpecifiers(bool to = true) { MaxEW707 wrote: ```suggestion void setIsParsingBaseSpecifiers(bool To = true) { ``` I am surprised clang-format didn't complain about starting with a lowercase for variables. I can't think of a better name. I respond here if I do :). https://github.com/llvm/llvm-project/pull/91990 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix Microsoft ABI inheritance model when member pointer is used in a base specifier (PR #91990)
https://github.com/MaxEW707 approved this pull request. LGTM. @MitalAshok I noticed in your commit messages you mentioned reworking -fcomplete-member-pointers. Will that include fixing clang incorrectly warning when an inheritance model is explicitly specified. Godbolt for reference: https://godbolt.org/z/rYaWz6sra. https://github.com/llvm/llvm-project/pull/91990 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix Microsoft ABI inheritance model when member pointer is used in a base specifier (PR #91990)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/91990 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Driver] Support `-jmc` for `*-windows-msvc` target in non cl driver modes (PR #107177)
https://github.com/MaxEW707 created https://github.com/llvm/llvm-project/pull/107177 Allow `-jmc` to be used if the target triple is targeting msvc, `*-windows-msvc`, irrelevant of the driver mode used. In general the driver mode shouldn't control the target triple. Also in our custom build system I am trying to just treat clang as clang. This is because while the `cl` driver mode emulates msvc interface quite well there are still a lot of operations that are just clang specific. The optimization modes do not map directly from msvc to clang. Warnings do not map from msvc to clang. Instead of wrapping options with `/clang:` when targeting `clang-cl.exe` it is just easier to target the clang driver always irrelevant of the target triple. >From 5c35200f2db964c33f47485d2f9ea9aba627ec26 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Tue, 3 Sep 2024 18:26:14 -0700 Subject: [PATCH] Support `-jmc` for `*-windows-msvc` target in non cl driver modes --- clang/lib/Driver/ToolChains/Clang.cpp | 3 ++- clang/test/Driver/clang_f_opts.c | 6 -- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index df86941950e46e..4e3096e2fb039d 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4853,7 +4853,8 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, // This controls whether or not we perform JustMyCode instrumentation. if (Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false)) { -if (TC.getTriple().isOSBinFormatELF() || D.IsCLMode()) { +if (TC.getTriple().isOSBinFormatELF() || +TC.getTriple().isWindowsMSVCEnvironment()) { if (DebugInfoKind >= llvm::codegenoptions::DebugInfoConstructor) CmdArgs.push_back("-fjmc"); else if (D.IsCLMode()) diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index d69cd199ac61d7..335fa546a13887 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -600,10 +600,12 @@ // CHECK_NO_DISABLE_DIRECT-NOT: -fobjc-disable-direct-methods-for-testing // RUN: %clang -### -S -fjmc -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN,CHECK_NOJMC %s -// RUN: %clang -### -S -fjmc -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN_NOT_ELF,CHECK_NOJMC %s +// RUN: %clang -### -S -fjmc -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN,CHECK_NOJMC %s +// RUN: %clang -### -S -fjmc -g -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefix=CHECK_JMC %s +// RUN: %clang -### -S -fjmc -g -fno-jmc -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefix=CHECK_NOJMC %s // RUN: %clang -### -S -fjmc -g -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefix=CHECK_JMC %s // RUN: %clang -### -S -fjmc -g -fno-jmc -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefix=CHECK_NOJMC %s -// RUN: %clang -### -fjmc -g -flto -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN_NOT_ELF,CHECK_NOJMC_LTO %s +// RUN: %clang -### -fjmc -g -flto -target x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefix=CHECK_NOJMC_LTO %s // RUN: %clang -### -fjmc -g -flto -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefix=CHECK_JMC_LTO %s // RUN: %clang -### -fjmc -g -flto -fno-jmc -target x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefix=CHECK_NOJMC_LTO %s // CHECK_JMC_WARN: -fjmc requires debug info. Use -g or debug options that enable debugger's stepping function; option ignored ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Driver] Support `-fjmc` for `*-windows-msvc` target in non cl driver modes (PR #107177)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/107177 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Driver] Support `-fjmc` for `*-windows-msvc` target in non cl driver modes (PR #107177)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/107177 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Driver] Support `-fjmc` for `*-windows-msvc` target in non cl driver modes (PR #107177)
https://github.com/MaxEW707 closed https://github.com/llvm/llvm-project/pull/107177 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Driver] Ensure `-fms-volatile` is set for x86 for `*-windows-msvc` triple on non cl driver modes (PR #107509)
https://github.com/MaxEW707 created https://github.com/llvm/llvm-project/pull/107509 Similar reasoning as this PR: https://github.com/llvm/llvm-project/pull/107177 `-fms-volatile` should be set by default for x86 targets as long as the triple is `*-windows-msvc`. The driver mode shouldn't dictate the triple when targeting msvc compatibility. >From 967a6b841993f756ae4230a92aa8db2d71d20d24 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Wed, 4 Sep 2024 23:37:45 -0700 Subject: [PATCH] Ensure `ms-volatile` is set for x86 for `*-windows-msvc` triple on non cl driver modes --- clang/lib/Driver/ToolChains/Clang.cpp | 2 +- clang/test/Driver/clang_f_opts.c | 4 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index df86941950e46e..93f9e2af2e0df4 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6003,7 +6003,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } if (Args.hasFlag(options::OPT_fms_volatile, options::OPT_fno_ms_volatile, - Triple.isX86() && D.IsCLMode())) + Triple.isX86() && IsWindowsMSVC)) CmdArgs.push_back("-fms-volatile"); // Non-PIC code defaults to -fdirect-access-external-data while PIC code diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index d69cd199ac61d7..5047c28e30d667 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -621,6 +621,10 @@ // RUN: %clang -### --target=aarch64-windows-msvc %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MS-VOLATILE %s // RUN: %clang -### --target=aarch64-windows-msvc -fms-volatile %s 2>&1 | FileCheck -check-prefix=CHECK-MS-VOLATILE %s // RUN: %clang -### --target=aarch64-windows-msvc -fno-ms-volatile %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MS-VOLATILE %s +// RUN: %clang -### --target=x86_64-windows-msvc %s 2>&1 | FileCheck -check-prefix=CHECK-MS-VOLATILE %s +// RUN: %clang -### --target=x86_64-windows-msvc -fno-ms-volatile %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MS-VOLATILE %s +// RUN: %clang -### --target=i686-windows-msvc %s 2>&1 | FileCheck -check-prefix=CHECK-MS-VOLATILE %s +// RUN: %clang -### --target=i686-windows-msvc -fno-ms-volatile %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MS-VOLATILE %s // CHECK-MS-VOLATILE: -fms-volatile // CHECK-NO-MS-VOLATILE-NOT: -fms-volatile ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix Microsoft ABI inheritance model when member pointer is used in a base specifier (PR #91990)
MaxEW707 wrote: @rnk @zmodem Sorry for the ping. Its been a bit since this got reviewed and I recently hit this ABI case when moving some parts of a larger project to clang. https://github.com/llvm/llvm-project/pull/91990 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Driver] Ensure `-fms-volatile` is set for x86 for `*-windows-msvc` triple on non cl driver modes (PR #107509)
MaxEW707 wrote: > I don't have a very strong opinion. I find it surprising in that the clang > driver is supposed to be gcc-compatible, and having to use `clang > -fstrict-aliasing` (but only when targeting Windows) to get the default > behavior looks a bit surprising. > > (I agree it's a better default, but imho it's a better default on non-Windows > too, and nobody found that convincing apparently ;)) I guess that depends on what the intention is with the driver vs the target triple. From the code and the [driver docs](https://clang.llvm.org/docs/DriverInternals.html) it appears the intention is that the driver interface should be agnostic to the triple. I can understand the view point where that gets fuzzy with options like `strict-aliasing` which the c and c++ standards allow and most compilers do opt to do this optimization by default which I also agree that I prefer the opposite being the default instead :). I can also understand the view point where projects compiling entirely with clang on windows would prefer more saner defaults from the toolchain than what msvc has as defaults. For my statements below I do want to make it clear that I am referring to the target triple, `[arch]-windows-msvc`, and not the target triple, `[arch]-windows-gnu`. I would expect the `-gnu`, mingw, triple to have all the default gnu compiler behaviours. My coworkers and I found it more confusing that we couldn't just build msvc compatible source files with `clang` out of the box with the correct `[arch]-windows-msvc` triple targeting msvc compatibility. Especially around options like `-fjmc` which until my previous PR would just error unless the driver mode was `cl`. Part of this expectation comes from us internally treating clang as clang in our source code and in our custom build system. We only need to check if we are android clang, sony clang, apple clang, etc in rare cases in the code. Usually it is bugs that happen due to vendors branching clang some commits before the final public release so the version numbers are identical but the vendor clang is missing some bug fix commits. Part of this expectation also comes from the [cross-compile](https://clang.llvm.org/docs/CrossCompilation.html#general-cross-compilation-options-in-clang) model of clang where we can build any target from any machine. We do have one team building a small win32 tool on Linux VMs (yes we ran into many issues with case insensitivity in the Windows headers but symlinks solve that :)). I wouldn't be surprised if we start looking at building more win32 code on Linux machines due to the easier management, the much lower process creation overhead and filesystem overhead compared to Windows which adds to build times on Windows builders. I even worked at places where Linux builds were built on Windows with a packaged clang toolchain plus dependent libs. Games are a win32 shop first, less today overall, so building Linux server executables on Windows that you can run in WSL and debug from VS is a workflow many users are more familiar with when doing day to day dev. Plus you avoid the overhead of the even slower WSL filesystem when accessing your checked out code via the mountpoints into your Windows volumes. Some targets today do enable non gcc options in the clang driver mode. To be compatible with IBM XL, https://github.com/llvm/llvm-project/blob/main/clang/lib/Driver/ToolChains/AIX.cpp#L556, enables the xl pragma pack behaviour when the target triple is AIX. Similarly the Sony targets enable `-fdeclspec` by default and also allow some Microsoft extensions hidden behind `-fms-extensions`, https://github.com/llvm/llvm-project/commit/fd4db5331e512d23d2d1c832065acbe226e7616d#diff-fabe5169278c853cdf933a1b8269d2e102e0f814d685e7cdde59f48731d28721L298. In the `windows-msvc` target mode we also enable `-fdelayed-template-parsing` by default as does msvc, https://github.com/llvm/llvm-project/blob/main/clang/lib/Driver/ToolChains/Clang.cpp#L7306. If we are concerned about `-fms-volatile` and `-fstrict-aliasing` then I am assuming non conforming two phase lookup by default would also be a concern. All of our code targeting msvc on pc sets `/permissive-` to get `/Zc:twoPhase`, https://learn.microsoft.com/en-us/cpp/build/reference/zc-twophase?view=msvc-170, conforming behaviour since newer Windows SDK headers are fixed to work under conforming behaviour. Likewise in our build system we set `-fno-delayed-template-parsing` for code I am trying to move from msvc to clang to get the same conforming behaviour with the clang driver as with the cl driver on pc builds. Unfortunately some console builds still require non conforming behaviour due to system headers. My point of view is if a user is building with the `-windows-msvc` target and thus using the Windows SDK headers, ATL headers, MFC headers, msvc stl, msvc headers provided by a VS Toolchain install, etc then I think we should conform to msvc's behav
[clang] [Clang] [AST] Fix placeholder return type name mangling for MSVC 1920+ / VS2019+ (PR #102848)
https://github.com/MaxEW707 created https://github.com/llvm/llvm-project/pull/102848 Partial fix for https://github.com/llvm/llvm-project/issues/92204. This PR just fixes VS2019+ since that is the suite of compilers that I require link compatibility with at the moment. I still intend to fix VS2017 and to update llvm-undname in future PRs. Once those are also finished and merged I'll close out https://github.com/llvm/llvm-project/issues/92204. I am hoping to get the llvm-undname PR up in a couple of weeks to be able to demangle the VS2019+ name mangling. MSVC 1920+ mangles placeholder return types for non-templated functions with "@". For example `auto foo() { return 0; }` is mangled as `?foo@@YA@XZ`. MSVC 1920+ mangles placeholder return types for templated functions as the qualifiers of the AutoType followed by "_P" for `auto` and "_T" for `decltype(auto)`. For example `template auto foo() { return 0; }` is mangled as `??$foo@H@@YA?A_PXZ` when `foo` is instantiated as follows `foo()`. Lambdas with placeholder return types are still mangled with clang's custom mangling since MSVC lambda mangling hasn't been deciphered yet. Similarly any pointers in the return type with an address space are mangled with clang's custom mangling since that is a clang extension. We cannot augment `mangleType` to support this mangling scheme as the mangling schemes for variables and functions differ. auto variables are encoded with the fully deduced type where auto return types are not. The following two functions with a static variable are mangled the same ``` template int test() { static int i = 0; // "?i@?1???$test@H@@YAHXZ@4HA" return i; } template int test() { static auto i = 0; // "?i@?1???$test@H@@YAHXZ@4HA" return i; } ``` Inside `mangleType` once we get to mangling the `AutoType` we have no context if we are from a variable encoding or some other encoding. Therefore it was easier to handle any special casing for `AutoType` return types with a separate function instead of using the `mangleType` infrastructure. >From e5071bd3be7607730654e5aa815a535db130fdee Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Sun, 11 Aug 2024 16:50:58 -0700 Subject: [PATCH 1/3] Fix placeholder return type name mangling for MSVC 1920+ --- clang/lib/AST/MicrosoftMangle.cpp | 172 - .../test/CodeGenCXX/mangle-ms-auto-return.cpp | 358 ++ .../mangle-ms-auto-templates-memptrs.cpp | 12 +- .../mangle-ms-auto-templates-nullptr.cpp | 2 +- .../CodeGenCXX/mangle-ms-auto-templates.cpp | 6 +- 5 files changed, 531 insertions(+), 19 deletions(-) create mode 100644 clang/test/CodeGenCXX/mangle-ms-auto-return.cpp diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 28f66e71c2f2de..ecbddc1aacc073 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -408,6 +408,9 @@ class MicrosoftCXXNameMangler { void mangleSourceName(StringRef Name); void mangleNestedName(GlobalDecl GD); + void mangleAutoReturnType(QualType T, SourceRange Range, +QualifierMangleMode QMM); + private: bool isStructorDecl(const NamedDecl *ND) const { return ND == Structor || getStructor(ND) == Structor; @@ -477,6 +480,15 @@ class MicrosoftCXXNameMangler { SourceRange Range); void mangleObjCKindOfType(const ObjCObjectType *T, Qualifiers Quals, SourceRange Range); + + void mangleAutoReturnType(const MemberPointerType *T, Qualifiers Quals, +SourceRange Range); + void mangleAutoReturnType(const PointerType *T, Qualifiers Quals, +SourceRange Range); + void mangleAutoReturnType(const LValueReferenceType *T, Qualifiers Quals, +SourceRange Range); + void mangleAutoReturnType(const RValueReferenceType *T, Qualifiers Quals, +SourceRange Range); }; } @@ -2494,8 +2506,61 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T, mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {"__clang"}); } +void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType T, + SourceRange Range, + QualifierMangleMode QMM) { + assert(getASTContext().getLangOpts().isCompatibleWithMSVC( + LangOptions::MSVC2019) && + "Cannot mangle MSVC 2017 auto return types!"); + + if (isa(T)) { +const auto *AT = T->getContainedAutoType(); +Qualifiers Quals = T.getLocalQualifiers(); + +if (QMM == QMM_Result) + Out << '?'; +if (QMM != QMM_Drop) + mangleQualifiers(Quals, false); +Out << (AT->isDecltypeAuto() ? "_T" : "_P"); +return; + } + + T = T.getDesugaredType(getASTContext()); + Qualifiers Quals = T.getLocalQualifiers(); + + switch (QMM) { + case QMM_Drop: + case QMM_Res
[clang] [Clang] [Sema] Error on reference types inside a union with msvc 1910+ (PR #102851)
https://github.com/MaxEW707 created https://github.com/llvm/llvm-project/pull/102851 Godbolt for reference: https://godbolt.org/z/ovKjvWc46 I definitely remember this being an extension in older versions of VS around VS 2012 but don't know when MSVC no longer exactly removed support for this extension wholesale. I no longer have licenses for VS2015 and VS2013. I can confirm that this extension is no longer valid in VS2017, VS2019 and VS2022 under `/permissive` and `/permissive-` I'll continue to spelunk MSDN and see if I can dig up one of old personal VS2015 licenses. >From e6b925894066656a2773278a093dbf709ba66319 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Sun, 11 Aug 2024 22:37:55 -0700 Subject: [PATCH] Error on reference inside a union with msvc 1910+ --- clang/lib/Sema/SemaDecl.cpp| 14 +- clang/test/SemaCXX/MicrosoftExtensions.cpp | 21 - 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 694a754646f274..0386560e337618 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18467,11 +18467,15 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, // the program is ill-formed, except when compiling with MSVC extensions // enabled. if (EltTy->isReferenceType()) { -Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ? -diag::ext_union_member_of_reference_type : -diag::err_union_member_of_reference_type) - << NewFD->getDeclName() << EltTy; -if (!getLangOpts().MicrosoftExt) +const bool HaveMSExt = +getLangOpts().MicrosoftExt && +!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2017); + +Diag(NewFD->getLocation(), + HaveMSExt ? diag::ext_union_member_of_reference_type + : diag::err_union_member_of_reference_type) +<< NewFD->getDeclName() << EltTy; +if (!HaveMSExt) NewFD->setInvalidDecl(); } } diff --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp b/clang/test/SemaCXX/MicrosoftExtensions.cpp index 98c19975095bbe..8601f32f064b33 100644 --- a/clang/test/SemaCXX/MicrosoftExtensions.cpp +++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp @@ -3,6 +3,8 @@ // RUN: %clang_cc1 -std=c++11 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fms-extensions -fexceptions -fcxx-exceptions -DTEST1 // RUN: %clang_cc1 -std=c++14 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fexceptions -fcxx-exceptions -DTEST2 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -fms-compatibility -verify -DTEST3 +// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify -fms-extensions -fms-compatibility-version=19.00 -DTEST4 +// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify -fms-extensions -fms-compatibility-version=19.10 -DTEST5 #if TEST1 @@ -384,11 +386,6 @@ void TestSP9() { c3.h(); // Overloaded unary op operand } -union u { - int *i1; - int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}} -}; - // Property getter using reference. struct SP11 { __declspec(property(get=GetV)) int V; @@ -619,6 +616,20 @@ template struct A {}; template struct B : A> { A::C::D d; }; // expected-warning {{implicit 'typename' is a C++20 extension}} } +#elif TEST4 + +union u { +int *i1; +int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}} +}; + +#elif TEST5 + +union u { +int *i1; +int &i2; // expected-error {{union member 'i2' has reference type 'int &'}} +}; + #else #error Unknown test mode ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Sema] Error on reference types inside a union with msvc 1910+ (PR #102851)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/102851 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Sema] Error on reference types inside a union with msvc 1910+ (PR #102851)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/102851 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Sema] Error on reference types inside a union with msvc 1910+ (PR #102851)
MaxEW707 wrote: > > I definitely remember this being an extension in older versions of VS > > around VS 2012 but don't know when MSVC no longer exactly removed support > > for this extension wholesale. > > This was definitely required for MFC headers; I remember implementing this > horrible nonsense ages ago, see #14109 -- I can verify that `CComControlBase` > no longer has the terrible union in it, but I'm not certain when it lost it. I went through the atlmfc headers shipped with MSVC 1914, 1929 and 1940 and didn't find any uses of references inside a union. I finally managed to find this documented after some MSDN spelunking. https://learn.microsoft.com/en-us/cpp/porting/visual-cpp-what-s-new-2003-through-2015?view=msvc-170 Look for the section titled, "Union data members". It says, "Data members of unions can no longer have reference types. The following code compiled successfully in Visual Studio 2013, but produces an error in Visual Studio 2015.". I think it is safe to say starting with VS2015 this is no longer supported and thus any headers shipped will not be using references inside unions. https://github.com/llvm/llvm-project/pull/102851 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [AST] Fix placeholder return type name mangling for MSVC 1920+ / VS2019+ (PR #102848)
@@ -2494,6 +2506,58 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T, mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {"__clang"}); } +void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType T, + SourceRange Range, + QualifierMangleMode QMM) { + assert(getASTContext().getLangOpts().isCompatibleWithMSVC( MaxEW707 wrote: The assert is here because the VS2017 path still takes the incorrect manglings path. I want to ensure any potential changing of the code doesn't call this function when mangling for VS2017 or earlier. That happens here, https://github.com/llvm/llvm-project/pull/102848/files#diff-f5b0f26263c3f9e2967ea9e3911d88ce9c4b3e990cbbab10627429435305bb96R2997, where we check if we are VS2019 otherwise do the incorrect mangling. https://github.com/llvm/llvm-project/pull/102848 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [AST] Fix placeholder return type name mangling for MSVC 1920+ / VS2019+ (PR #102848)
@@ -408,6 +408,9 @@ class MicrosoftCXXNameMangler { void mangleSourceName(StringRef Name); void mangleNestedName(GlobalDecl GD); + void mangleAutoReturnType(QualType T, SourceRange Range, MaxEW707 wrote: Argh you are correct. This is holdover from development code that I forgot to remove. I'll fix this. https://github.com/llvm/llvm-project/pull/102848 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [AST] Fix placeholder return type name mangling for MSVC 1920+ / VS2019+ (PR #102848)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/102848 >From e5071bd3be7607730654e5aa815a535db130fdee Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Sun, 11 Aug 2024 16:50:58 -0700 Subject: [PATCH 1/4] Fix placeholder return type name mangling for MSVC 1920+ --- clang/lib/AST/MicrosoftMangle.cpp | 172 - .../test/CodeGenCXX/mangle-ms-auto-return.cpp | 358 ++ .../mangle-ms-auto-templates-memptrs.cpp | 12 +- .../mangle-ms-auto-templates-nullptr.cpp | 2 +- .../CodeGenCXX/mangle-ms-auto-templates.cpp | 6 +- 5 files changed, 531 insertions(+), 19 deletions(-) create mode 100644 clang/test/CodeGenCXX/mangle-ms-auto-return.cpp diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 28f66e71c2f2de..ecbddc1aacc073 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -408,6 +408,9 @@ class MicrosoftCXXNameMangler { void mangleSourceName(StringRef Name); void mangleNestedName(GlobalDecl GD); + void mangleAutoReturnType(QualType T, SourceRange Range, +QualifierMangleMode QMM); + private: bool isStructorDecl(const NamedDecl *ND) const { return ND == Structor || getStructor(ND) == Structor; @@ -477,6 +480,15 @@ class MicrosoftCXXNameMangler { SourceRange Range); void mangleObjCKindOfType(const ObjCObjectType *T, Qualifiers Quals, SourceRange Range); + + void mangleAutoReturnType(const MemberPointerType *T, Qualifiers Quals, +SourceRange Range); + void mangleAutoReturnType(const PointerType *T, Qualifiers Quals, +SourceRange Range); + void mangleAutoReturnType(const LValueReferenceType *T, Qualifiers Quals, +SourceRange Range); + void mangleAutoReturnType(const RValueReferenceType *T, Qualifiers Quals, +SourceRange Range); }; } @@ -2494,8 +2506,61 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T, mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {"__clang"}); } +void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType T, + SourceRange Range, + QualifierMangleMode QMM) { + assert(getASTContext().getLangOpts().isCompatibleWithMSVC( + LangOptions::MSVC2019) && + "Cannot mangle MSVC 2017 auto return types!"); + + if (isa(T)) { +const auto *AT = T->getContainedAutoType(); +Qualifiers Quals = T.getLocalQualifiers(); + +if (QMM == QMM_Result) + Out << '?'; +if (QMM != QMM_Drop) + mangleQualifiers(Quals, false); +Out << (AT->isDecltypeAuto() ? "_T" : "_P"); +return; + } + + T = T.getDesugaredType(getASTContext()); + Qualifiers Quals = T.getLocalQualifiers(); + + switch (QMM) { + case QMM_Drop: + case QMM_Result: +break; + case QMM_Mangle: +mangleQualifiers(Quals, false); +break; + default: +llvm_unreachable("QMM_Escape unexpected"); + } + + const Type *ty = T.getTypePtr(); + switch (ty->getTypeClass()) { + case Type::MemberPointer: +mangleAutoReturnType(cast(ty), Quals, Range); +break; + case Type::Pointer: +mangleAutoReturnType(cast(ty), Quals, Range); +break; + case Type::LValueReference: +mangleAutoReturnType(cast(ty), Quals, Range); +break; + case Type::RValueReference: +mangleAutoReturnType(cast(ty), Quals, Range); +break; + default: +llvm_unreachable("Invalid type expected"); + } +} + void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range, QualifierMangleMode QMM) { + // Don't use the canonical types. MSVC includes things like 'const' on // pointer arguments to function pointers that canonicalization strips away. T = T.getDesugaredType(getASTContext()); @@ -2900,17 +2965,51 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, // can differ by their calling convention and are typically deduced. So // we make sure that this type gets mangled properly. mangleType(ResultType, Range, QMM_Result); -} else if (const auto *AT = dyn_cast_or_null( - ResultType->getContainedAutoType())) { - Out << '?'; - mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false); - Out << '?'; +} else if (IsInLambda) { + if (const auto *AT = ResultType->getContainedAutoType()) { +assert(AT->getKeyword() == AutoTypeKeyword::Auto && + "should only need to mangle auto!"); +Out << '?'; +mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false); +Out << '?'; +mangleSourceName(""); +Out << '@'; + } else { +Out << '@'; + } +} else if (const auto *AT = Result
[clang] [Clang] [AST] Fix placeholder return type name mangling for MSVC 1920+ / VS2019+ (PR #102848)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/102848 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Sema] Error on reference types inside a union with msvc 1910+ (PR #102851)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/102851 >From e6b925894066656a2773278a093dbf709ba66319 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Sun, 11 Aug 2024 22:37:55 -0700 Subject: [PATCH 1/2] Error on reference inside a union with msvc 1910+ --- clang/lib/Sema/SemaDecl.cpp| 14 +- clang/test/SemaCXX/MicrosoftExtensions.cpp | 21 - 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 694a754646f274..0386560e337618 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18467,11 +18467,15 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, // the program is ill-formed, except when compiling with MSVC extensions // enabled. if (EltTy->isReferenceType()) { -Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ? -diag::ext_union_member_of_reference_type : -diag::err_union_member_of_reference_type) - << NewFD->getDeclName() << EltTy; -if (!getLangOpts().MicrosoftExt) +const bool HaveMSExt = +getLangOpts().MicrosoftExt && +!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2017); + +Diag(NewFD->getLocation(), + HaveMSExt ? diag::ext_union_member_of_reference_type + : diag::err_union_member_of_reference_type) +<< NewFD->getDeclName() << EltTy; +if (!HaveMSExt) NewFD->setInvalidDecl(); } } diff --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp b/clang/test/SemaCXX/MicrosoftExtensions.cpp index 98c19975095bbe..8601f32f064b33 100644 --- a/clang/test/SemaCXX/MicrosoftExtensions.cpp +++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp @@ -3,6 +3,8 @@ // RUN: %clang_cc1 -std=c++11 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fms-extensions -fexceptions -fcxx-exceptions -DTEST1 // RUN: %clang_cc1 -std=c++14 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fexceptions -fcxx-exceptions -DTEST2 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -fms-compatibility -verify -DTEST3 +// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify -fms-extensions -fms-compatibility-version=19.00 -DTEST4 +// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify -fms-extensions -fms-compatibility-version=19.10 -DTEST5 #if TEST1 @@ -384,11 +386,6 @@ void TestSP9() { c3.h(); // Overloaded unary op operand } -union u { - int *i1; - int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}} -}; - // Property getter using reference. struct SP11 { __declspec(property(get=GetV)) int V; @@ -619,6 +616,20 @@ template struct A {}; template struct B : A> { A::C::D d; }; // expected-warning {{implicit 'typename' is a C++20 extension}} } +#elif TEST4 + +union u { +int *i1; +int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}} +}; + +#elif TEST5 + +union u { +int *i1; +int &i2; // expected-error {{union member 'i2' has reference type 'int &'}} +}; + #else #error Unknown test mode >From 114a0417e0a8d975168b01f6c33477056b4588ad Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 12 Aug 2024 21:48:53 -0700 Subject: [PATCH 2/2] Switch to VS2015 --- clang/lib/Sema/SemaDecl.cpp| 2 +- clang/test/SemaCXX/MicrosoftExtensions.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0386560e337618..d90b9eca4ab0a1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18469,7 +18469,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, if (EltTy->isReferenceType()) { const bool HaveMSExt = getLangOpts().MicrosoftExt && -!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2017); +!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015); Diag(NewFD->getLocation(), HaveMSExt ? diag::ext_union_member_of_reference_type diff --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp b/clang/test/SemaCXX/MicrosoftExtensions.cpp index 8601f32f064b33..08e3af34d45d6d 100644 --- a/clang/test/SemaCXX/MicrosoftExtensions.cpp +++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp @@ -3,8 +3,8 @@ // RUN: %clang_cc1 -std=c++11 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fms-extensions -fexceptions -fcxx-exceptions -DTEST1 // RUN: %clang_cc1 -std=c++14 %s -triple i686-pc-win32 -fsyntax-only
[clang] [Clang] [Sema] Error on reference types inside a union with msvc 1900+ (PR #102851)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/102851 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [AST] Fix placeholder return type name mangling for MSVC 1920+ / VS2019+ (PR #102848)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/102848 >From e5071bd3be7607730654e5aa815a535db130fdee Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Sun, 11 Aug 2024 16:50:58 -0700 Subject: [PATCH 1/5] Fix placeholder return type name mangling for MSVC 1920+ --- clang/lib/AST/MicrosoftMangle.cpp | 172 - .../test/CodeGenCXX/mangle-ms-auto-return.cpp | 358 ++ .../mangle-ms-auto-templates-memptrs.cpp | 12 +- .../mangle-ms-auto-templates-nullptr.cpp | 2 +- .../CodeGenCXX/mangle-ms-auto-templates.cpp | 6 +- 5 files changed, 531 insertions(+), 19 deletions(-) create mode 100644 clang/test/CodeGenCXX/mangle-ms-auto-return.cpp diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 28f66e71c2f2de..ecbddc1aacc073 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -408,6 +408,9 @@ class MicrosoftCXXNameMangler { void mangleSourceName(StringRef Name); void mangleNestedName(GlobalDecl GD); + void mangleAutoReturnType(QualType T, SourceRange Range, +QualifierMangleMode QMM); + private: bool isStructorDecl(const NamedDecl *ND) const { return ND == Structor || getStructor(ND) == Structor; @@ -477,6 +480,15 @@ class MicrosoftCXXNameMangler { SourceRange Range); void mangleObjCKindOfType(const ObjCObjectType *T, Qualifiers Quals, SourceRange Range); + + void mangleAutoReturnType(const MemberPointerType *T, Qualifiers Quals, +SourceRange Range); + void mangleAutoReturnType(const PointerType *T, Qualifiers Quals, +SourceRange Range); + void mangleAutoReturnType(const LValueReferenceType *T, Qualifiers Quals, +SourceRange Range); + void mangleAutoReturnType(const RValueReferenceType *T, Qualifiers Quals, +SourceRange Range); }; } @@ -2494,8 +2506,61 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T, mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {"__clang"}); } +void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType T, + SourceRange Range, + QualifierMangleMode QMM) { + assert(getASTContext().getLangOpts().isCompatibleWithMSVC( + LangOptions::MSVC2019) && + "Cannot mangle MSVC 2017 auto return types!"); + + if (isa(T)) { +const auto *AT = T->getContainedAutoType(); +Qualifiers Quals = T.getLocalQualifiers(); + +if (QMM == QMM_Result) + Out << '?'; +if (QMM != QMM_Drop) + mangleQualifiers(Quals, false); +Out << (AT->isDecltypeAuto() ? "_T" : "_P"); +return; + } + + T = T.getDesugaredType(getASTContext()); + Qualifiers Quals = T.getLocalQualifiers(); + + switch (QMM) { + case QMM_Drop: + case QMM_Result: +break; + case QMM_Mangle: +mangleQualifiers(Quals, false); +break; + default: +llvm_unreachable("QMM_Escape unexpected"); + } + + const Type *ty = T.getTypePtr(); + switch (ty->getTypeClass()) { + case Type::MemberPointer: +mangleAutoReturnType(cast(ty), Quals, Range); +break; + case Type::Pointer: +mangleAutoReturnType(cast(ty), Quals, Range); +break; + case Type::LValueReference: +mangleAutoReturnType(cast(ty), Quals, Range); +break; + case Type::RValueReference: +mangleAutoReturnType(cast(ty), Quals, Range); +break; + default: +llvm_unreachable("Invalid type expected"); + } +} + void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range, QualifierMangleMode QMM) { + // Don't use the canonical types. MSVC includes things like 'const' on // pointer arguments to function pointers that canonicalization strips away. T = T.getDesugaredType(getASTContext()); @@ -2900,17 +2965,51 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, // can differ by their calling convention and are typically deduced. So // we make sure that this type gets mangled properly. mangleType(ResultType, Range, QMM_Result); -} else if (const auto *AT = dyn_cast_or_null( - ResultType->getContainedAutoType())) { - Out << '?'; - mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false); - Out << '?'; +} else if (IsInLambda) { + if (const auto *AT = ResultType->getContainedAutoType()) { +assert(AT->getKeyword() == AutoTypeKeyword::Auto && + "should only need to mangle auto!"); +Out << '?'; +mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false); +Out << '?'; +mangleSourceName(""); +Out << '@'; + } else { +Out << '@'; + } +} else if (const auto *AT = Result
[clang] [Clang] [Sema] Error on reference types inside a union with msvc 1900+ (PR #102851)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/102851 >From e6b925894066656a2773278a093dbf709ba66319 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Sun, 11 Aug 2024 22:37:55 -0700 Subject: [PATCH 1/3] Error on reference inside a union with msvc 1910+ --- clang/lib/Sema/SemaDecl.cpp| 14 +- clang/test/SemaCXX/MicrosoftExtensions.cpp | 21 - 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 694a754646f274..0386560e337618 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18467,11 +18467,15 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, // the program is ill-formed, except when compiling with MSVC extensions // enabled. if (EltTy->isReferenceType()) { -Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ? -diag::ext_union_member_of_reference_type : -diag::err_union_member_of_reference_type) - << NewFD->getDeclName() << EltTy; -if (!getLangOpts().MicrosoftExt) +const bool HaveMSExt = +getLangOpts().MicrosoftExt && +!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2017); + +Diag(NewFD->getLocation(), + HaveMSExt ? diag::ext_union_member_of_reference_type + : diag::err_union_member_of_reference_type) +<< NewFD->getDeclName() << EltTy; +if (!HaveMSExt) NewFD->setInvalidDecl(); } } diff --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp b/clang/test/SemaCXX/MicrosoftExtensions.cpp index 98c19975095bbe..8601f32f064b33 100644 --- a/clang/test/SemaCXX/MicrosoftExtensions.cpp +++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp @@ -3,6 +3,8 @@ // RUN: %clang_cc1 -std=c++11 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fms-extensions -fexceptions -fcxx-exceptions -DTEST1 // RUN: %clang_cc1 -std=c++14 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fexceptions -fcxx-exceptions -DTEST2 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -fms-compatibility -verify -DTEST3 +// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify -fms-extensions -fms-compatibility-version=19.00 -DTEST4 +// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify -fms-extensions -fms-compatibility-version=19.10 -DTEST5 #if TEST1 @@ -384,11 +386,6 @@ void TestSP9() { c3.h(); // Overloaded unary op operand } -union u { - int *i1; - int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}} -}; - // Property getter using reference. struct SP11 { __declspec(property(get=GetV)) int V; @@ -619,6 +616,20 @@ template struct A {}; template struct B : A> { A::C::D d; }; // expected-warning {{implicit 'typename' is a C++20 extension}} } +#elif TEST4 + +union u { +int *i1; +int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}} +}; + +#elif TEST5 + +union u { +int *i1; +int &i2; // expected-error {{union member 'i2' has reference type 'int &'}} +}; + #else #error Unknown test mode >From 114a0417e0a8d975168b01f6c33477056b4588ad Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 12 Aug 2024 21:48:53 -0700 Subject: [PATCH 2/3] Switch to VS2015 --- clang/lib/Sema/SemaDecl.cpp| 2 +- clang/test/SemaCXX/MicrosoftExtensions.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0386560e337618..d90b9eca4ab0a1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18469,7 +18469,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, if (EltTy->isReferenceType()) { const bool HaveMSExt = getLangOpts().MicrosoftExt && -!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2017); +!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015); Diag(NewFD->getLocation(), HaveMSExt ? diag::ext_union_member_of_reference_type diff --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp b/clang/test/SemaCXX/MicrosoftExtensions.cpp index 8601f32f064b33..08e3af34d45d6d 100644 --- a/clang/test/SemaCXX/MicrosoftExtensions.cpp +++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp @@ -3,8 +3,8 @@ // RUN: %clang_cc1 -std=c++11 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fms-extensions -fexceptions -fcxx-exceptions -DTEST1 // RUN: %clang_cc1 -std=c++14 %s -triple i686-pc-win32 -fsyntax-only
[clang] [Clang] [Sema] Error on reference types inside a union with msvc 1900+ (PR #102851)
@@ -619,6 +616,20 @@ template struct A {}; template struct B : A> { A::C::D d; }; // expected-warning {{implicit 'typename' is a C++20 extension}} } +#elif TEST4 + +union u { +int *i1; +int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}} +}; + +#elif TEST5 + +union u { +int *i1; +int &i2; // expected-error {{union member 'i2' has reference type 'int &'}} +}; + MaxEW707 wrote: The more you know. Putting this into my notes. I'll get this cleaned up :). https://github.com/llvm/llvm-project/pull/102851 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Sema] Error on reference types inside a union with msvc 1900+ (PR #102851)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/102851 >From e6b925894066656a2773278a093dbf709ba66319 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Sun, 11 Aug 2024 22:37:55 -0700 Subject: [PATCH 1/4] Error on reference inside a union with msvc 1910+ --- clang/lib/Sema/SemaDecl.cpp| 14 +- clang/test/SemaCXX/MicrosoftExtensions.cpp | 21 - 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 694a754646f274..0386560e337618 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18467,11 +18467,15 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, // the program is ill-formed, except when compiling with MSVC extensions // enabled. if (EltTy->isReferenceType()) { -Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ? -diag::ext_union_member_of_reference_type : -diag::err_union_member_of_reference_type) - << NewFD->getDeclName() << EltTy; -if (!getLangOpts().MicrosoftExt) +const bool HaveMSExt = +getLangOpts().MicrosoftExt && +!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2017); + +Diag(NewFD->getLocation(), + HaveMSExt ? diag::ext_union_member_of_reference_type + : diag::err_union_member_of_reference_type) +<< NewFD->getDeclName() << EltTy; +if (!HaveMSExt) NewFD->setInvalidDecl(); } } diff --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp b/clang/test/SemaCXX/MicrosoftExtensions.cpp index 98c19975095bbe..8601f32f064b33 100644 --- a/clang/test/SemaCXX/MicrosoftExtensions.cpp +++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp @@ -3,6 +3,8 @@ // RUN: %clang_cc1 -std=c++11 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fms-extensions -fexceptions -fcxx-exceptions -DTEST1 // RUN: %clang_cc1 -std=c++14 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fexceptions -fcxx-exceptions -DTEST2 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -fms-compatibility -verify -DTEST3 +// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify -fms-extensions -fms-compatibility-version=19.00 -DTEST4 +// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify -fms-extensions -fms-compatibility-version=19.10 -DTEST5 #if TEST1 @@ -384,11 +386,6 @@ void TestSP9() { c3.h(); // Overloaded unary op operand } -union u { - int *i1; - int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}} -}; - // Property getter using reference. struct SP11 { __declspec(property(get=GetV)) int V; @@ -619,6 +616,20 @@ template struct A {}; template struct B : A> { A::C::D d; }; // expected-warning {{implicit 'typename' is a C++20 extension}} } +#elif TEST4 + +union u { +int *i1; +int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}} +}; + +#elif TEST5 + +union u { +int *i1; +int &i2; // expected-error {{union member 'i2' has reference type 'int &'}} +}; + #else #error Unknown test mode >From 114a0417e0a8d975168b01f6c33477056b4588ad Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Mon, 12 Aug 2024 21:48:53 -0700 Subject: [PATCH 2/4] Switch to VS2015 --- clang/lib/Sema/SemaDecl.cpp| 2 +- clang/test/SemaCXX/MicrosoftExtensions.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0386560e337618..d90b9eca4ab0a1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18469,7 +18469,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, if (EltTy->isReferenceType()) { const bool HaveMSExt = getLangOpts().MicrosoftExt && -!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2017); +!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015); Diag(NewFD->getLocation(), HaveMSExt ? diag::ext_union_member_of_reference_type diff --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp b/clang/test/SemaCXX/MicrosoftExtensions.cpp index 8601f32f064b33..08e3af34d45d6d 100644 --- a/clang/test/SemaCXX/MicrosoftExtensions.cpp +++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp @@ -3,8 +3,8 @@ // RUN: %clang_cc1 -std=c++11 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fms-extensions -fexceptions -fcxx-exceptions -DTEST1 // RUN: %clang_cc1 -std=c++14 %s -triple i686-pc-win32 -fsyntax-only
[clang] [Clang] [AST] Fix placeholder return type name mangling for MSVC 1920+ / VS2019+ (PR #102848)
https://github.com/MaxEW707 closed https://github.com/llvm/llvm-project/pull/102848 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Sema] Error on reference types inside a union with msvc 1900+ (PR #102851)
https://github.com/MaxEW707 closed https://github.com/llvm/llvm-project/pull/102851 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ARM64EC] Fix compilation of intrin.h in ARM64EC mode. (PR #87717)
@@ -413,6 +413,7 @@ static __inline__ void __DEFAULT_FN_ATTRS __writecr3(unsigned __INTPTR_TYPE__ __cr3_val) { __asm__ ("mov {%0, %%cr3|cr3, %0}" : : "r"(__cr3_val) : "memory"); } +#endif MaxEW707 wrote: Nice catch. We should probably also ifdef these function declarations near the top of this file. https://github.com/llvm/llvm-project/blob/main/clang/lib/Headers/intrin.h#L96 https://github.com/llvm/llvm-project/blob/main/clang/lib/Headers/intrin.h#L126 https://github.com/llvm/llvm-project/pull/87717 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ARM64EC] Fix compilation of intrin.h in ARM64EC mode. (PR #87717)
MaxEW707 wrote: I didn't realize ARM64EC was supported by clang. You are missing one `#if defined(__x86_64__) && !defined(__arm64ec__)` check here, https://github.com/llvm/llvm-project/blob/main/clang/lib/Headers/intrin0.h#L47. Doesn't appear to be anyway to comment on lines that aren't in the diff view on github :(. > If we actually need some of these intrinsics in ARM64EC mode, we can revisit > later. For `intrin0.h` looks like we are missing a some intrinsics that msvc stl does use. Adding `__arm64ec__` to the following lines should match `intrin0.h` that is shipped with msvc 1939. https://github.com/llvm/llvm-project/blob/main/clang/lib/Headers/intrin0.h#L30 https://github.com/llvm/llvm-project/blob/main/clang/lib/Headers/intrin0.h#L86 Since we are intending to revisit adding missing intrinsics later I will do that over the weekend when I have some free time if you decide not to do it in this PR :). https://github.com/llvm/llvm-project/pull/87717 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ARM64EC] Fix compilation of intrin.h in ARM64EC mode. (PR #87717)
https://github.com/MaxEW707 approved this pull request. https://github.com/llvm/llvm-project/pull/87717 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ARM64EC] Add support for parsing __vectorcall (PR #87725)
MaxEW707 wrote: LGTM. >From memory, its been a while since I've had to ship on ARM64EC, all instances >of `__vectorcall` are supposed to be rejected by msvc. That also aligns with >the `__vectorcall` docs on MSDN. I am not sure what clang's policy is with potentially allowing code that "should" be rejected by msvc but since this errors when the function is actually generated this should be fine to support even if msvc gets more strict in the future. @CaseyCarter It feels like we are missing an arm64ec check here, https://github.com/microsoft/STL/blob/be81252ed1f5e5fc6d77faca0b5dbbbdae8143a2/stl/inc/type_traits#L398 unless this was intention and just not documented? https://github.com/llvm/llvm-project/pull/87725 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ARM64EC] Add support for parsing __vectorcall (PR #87725)
https://github.com/MaxEW707 approved this pull request. https://github.com/llvm/llvm-project/pull/87725 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-cl] [Driver] Fix clang-cl driver supported colon options (PR #88216)
https://github.com/MaxEW707 created https://github.com/llvm/llvm-project/pull/88216 Tested locally against msvc 1939. MSVC supports the colon form of various options that take a path even though that isn't documented for all options on MSDN. I added the colon form for all supported msvc options that clang-cl does not intentionally ignore due to being unsupported. I also fixed the existing colon options by ensure we use `JoinedOrSeparate`. `/F[x]` argument must used within the same command line argument. However, `/F[x]:` arguments are allowed to span a command line argument. The following is valid `/F[x]: path` which is 2 separate command line arguments. You can see this documented here, https://learn.microsoft.com/en-us/cpp/build/reference/fo-object-file-name?view=msvc-170, where it says `/Fo:[ ]"pathname"`. This behaviour works for all colon options that take a path and I tested it locally against msvc 1939 for all the option changes in this PR. >From 22c37dbc2d9b18f5ea18b525c37f4ba5771365f6 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Tue, 9 Apr 2024 19:27:44 -0400 Subject: [PATCH] Fix clang-cl driver supported colon options --- clang/include/clang/Driver/Options.td | 6 -- clang/test/Driver/cl-outputs.c| 4 clang/test/Driver/cl-pch.cpp | 6 ++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index f745e573eb2686..bc7041c7830984 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -8331,14 +8331,15 @@ def _SLASH_FI : CLJoinedOrSeparate<"FI">, def _SLASH_Fe : CLJoined<"Fe">, HelpText<"Set output executable file name">, MetaVarName<"">; -def _SLASH_Fe_COLON : CLJoined<"Fe:">, Alias<_SLASH_Fe>; +def _SLASH_Fe_COLON : CLJoinedOrSeparate<"Fe:">, Alias<_SLASH_Fe>; def _SLASH_Fi : CLCompileJoined<"Fi">, HelpText<"Set preprocess output file name (with /P)">, MetaVarName<"">; +def _SLASH_Fi_COLON : CLJoinedOrSeparate<"Fi:">, Alias<_SLASH_Fi>; def _SLASH_Fo : CLCompileJoined<"Fo">, HelpText<"Set output object file (with /c)">, MetaVarName<"">; -def _SLASH_Fo_COLON : CLCompileJoined<"Fo:">, Alias<_SLASH_Fo>; +def _SLASH_Fo_COLON : CLCompileJoinedOrSeparate<"Fo:">, Alias<_SLASH_Fo>; def _SLASH_guard : CLJoined<"guard:">, HelpText<"Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks. " "Enable EH Continuation Guard with /guard:ehcont">; @@ -8433,6 +8434,7 @@ def _SLASH_Zc_dllexportInlines_ : CLFlag<"Zc:dllexportInlines-">, HelpText<"Do not dllexport/dllimport inline member functions of dllexport/import classes">; def _SLASH_Fp : CLJoined<"Fp">, HelpText<"Set pch file name (with /Yc and /Yu)">, MetaVarName<"">; +def _SLASH_Fp_COLON : CLJoinedOrSeparate<"Fp:">, Alias<_SLASH_Fp>; def _SLASH_Gd : CLFlag<"Gd">, HelpText<"Set __cdecl as a default calling convention">; diff --git a/clang/test/Driver/cl-outputs.c b/clang/test/Driver/cl-outputs.c index 4d58f0fb548b57..4298657ac49f5c 100644 --- a/clang/test/Driver/cl-outputs.c +++ b/clang/test/Driver/cl-outputs.c @@ -118,6 +118,7 @@ // RUN: %clang_cl /Fefoo.ext -### -- %s 2>&1 | FileCheck -check-prefix=FeEXT %s // RUN: %clang_cl /Fe:foo.ext -### -- %s 2>&1 | FileCheck -check-prefix=FeEXT %s +// RUN: %clang_cl /Fe: foo.ext -### -- %s 2>&1 | FileCheck -check-prefix=FeEXT %s // FeEXT: "-out:foo.ext" // RUN: %clang_cl /LD /Fefoo.ext -### -- %s 2>&1 | FileCheck -check-prefix=FeEXTDLL %s @@ -270,6 +271,8 @@ // P: "-o" "cl-outputs.i" // RUN: %clang_cl /P /Fifoo -### -- %s 2>&1 | FileCheck -check-prefix=Fi1 %s +// RUN: %clang_cl /P /Fi:foo -### -- %s 2>&1 | FileCheck -check-prefix=Fi1 %s +// RUN: %clang_cl /P /Fi: foo -### -- %s 2>&1 | FileCheck -check-prefix=Fi1 %s // Fi1: "-E" // Fi1: "-o" "foo.i" @@ -302,6 +305,7 @@ // RELATIVE_OBJPATH1: "-object-file-name=a.obj" // RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Fo:a.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH1_COLON %s +// RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Fo: a.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH1_COLON %s // RELATIVE_OBJPATH1_COLON: "-object-file-name=a.obj" // RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Fofoo/a.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH2 %s diff --git a/clang/test/Driver/cl-pch.cpp b/clang/test/Driver/cl-pch.cpp index d09b177eb617de..cc4fc435a61c20 100644 --- a/clang/test/Driver/cl-pch.cpp +++ b/clang/test/Driver/cl-pch.cpp @@ -99,6 +99,12 @@ // /Yu /Fpout.pch => out.pch is filename // RUN: %clang_cl -Werror /Yupchfile.h /FIpchfile.h /Fpout.pch /c -### -- %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-YUFP1 %s +// /Yu /Fp:out.pch => out.pch is filename +// RUN: %clang_cl -Werror /Yupchfile.h /FIpchfile.h /Fp:out.pch /c -### -- %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-YUFP1 %s +// /Yu /Fp: out.pch => out.pch is f
[clang] [clang-cl] [Driver] Fix clang-cl driver supported colon options (PR #88216)
MaxEW707 wrote: CC @rnk https://github.com/llvm/llvm-project/pull/88216 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-cl][AST] Fix auto NTTP MSVC 1920+ mangling for pointer types (PR #92477)
MaxEW707 wrote: Friendly ping @rnk @efriedma-quic @zmodem https://github.com/llvm/llvm-project/pull/92477 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-cl][AST] Fix auto NTTP MSVC 1920+ mangling for pointer types (PR #92477)
MaxEW707 wrote: > Will llvm/lib/Demangle/MicrosoftDemangle.cpp also need to be updated? (That > could be done separately) Possibly. I didn't realize the llvm-project implemented demangling as well. I'll take a look at the demangle code after I merge this PR and get a separate PR up if it needs updating. > Your commit message mentions variables, function pointers, and member > function pointers... is there anything else we need to handle? Null pointers? > Integers? auto return functions that have NTTP parameters need fixing: https://github.com/llvm/llvm-project/issues/92204 Integers were fixed in this commit here: https://github.com/llvm/llvm-project/commit/83286a1a8f059d1664b64341854676a36a85cecd I need to check null pointers. I haven't checked C++20 float point or literal class types either. https://github.com/llvm/llvm-project/pull/92477 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-cl][AST] Fix auto NTTP MSVC 1920+ mangling for pointer types (PR #92477)
https://github.com/MaxEW707 closed https://github.com/llvm/llvm-project/pull/92477 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [SEH] Ignore async exception flag when the environment is not MSVC (PR #88101)
https://github.com/MaxEW707 approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/88101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-cl] [Driver] Fix clang-cl driver supported colon options (PR #88216)
MaxEW707 wrote: > Thank you for polishing this corner of the driver interface! It's interesting > that they have an alternative separate spelling. I always felt like the > /Fopath.cpp pattern was a bit unreadable. Thanks for the review. I will need you to commit on my behalf. I think its about time I figure out what conditions I need to meet in-order to get commit after approval rights. `/Fopath.cpp` is super unreadable. Unfortunately, I don't remember when the colon spelling came into existence but anything from VS2017 definitely has the colon alternative spelling. https://github.com/llvm/llvm-project/pull/88216 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-cl] [Sema] Support MSVC non-const lvalue to user-defined temporary reference (PR #99833)
https://github.com/MaxEW707 edited https://github.com/llvm/llvm-project/pull/99833 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-cl] [Sema] Support MSVC non-const lvalue to user-defined temporary reference (PR #99833)
MaxEW707 wrote: > This should be controllable via -fms-extensions/-fno-ms-extensions; having > its own dialect flag is a bit novel but I'm not strongly opposed. CC @MaskRay > @jansvoboda11 for driver/options opinions For this feedback I intentionally didn't do this because this ms extension isn't one intended to be always enabled. -fms-extensions enables extensions that are always valid to use with msvc such as the `__try` and `__finally` keywords for SEH. MSVC allows controlling this option independently here, [/Zc:ReferenceBinding](https://learn.microsoft.com/en-us/cpp/build/reference/zc-referencebinding-enforce-reference-binding-rules?view=msvc-170). MSVC `/permissive-` disables this reference binding extension, however `__try` and friends are still available as they are vital for operating within a Win32 environment. Newer C++ modes like C++20 also implicitly disable this reference binding extension in MSVC as they move towards proper C++ conformance by default. This is a one off extension similar to -fms-volatile or -fms-define-stdc. I would like to keep it a separate option that can be individually controlled instead of grouping it with -fms-extensions. https://github.com/llvm/llvm-project/pull/99833 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-cl] [Sema] Support MSVC non-const lvalue to user-defined temporary reference (PR #99833)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/99833 >From e0528ecc441e33822426b8b3d6522d056c95bb54 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Fri, 21 Jun 2024 20:37:40 -0700 Subject: [PATCH 1/5] Support MSVC lvalue to temporary reference binding --- clang/docs/ReleaseNotes.rst | 4 + clang/include/clang/Basic/LangOptions.def | 1 + clang/include/clang/Driver/Options.td | 12 +++ clang/include/clang/Sema/Sema.h | 2 + clang/lib/Driver/ToolChains/Clang.cpp | 5 + clang/lib/Driver/ToolChains/MSVC.cpp| 1 + clang/lib/Sema/SemaInit.cpp | 22 +++-- clang/lib/Sema/SemaOverload.cpp | 16 ++- clang/test/Driver/cl-permissive.c | 7 ++ clang/test/Driver/cl-zc.cpp | 2 + clang/test/SemaCXX/ms-reference-binding.cpp | 102 11 files changed, 165 insertions(+), 9 deletions(-) create mode 100644 clang/test/SemaCXX/ms-reference-binding.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4638b91b48f95..567effa83f845 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -486,6 +486,10 @@ New Compiler Flags - ``-fpointer-tbaa`` enables emission of distinct type-based alias analysis tags for incompatible pointers. +- ``-fms-reference-binding`` and its clang-cl counterpart ``/Zc:referenceBinding``. + Implements the MSVC extension where expressions that bind a user-defined type temporary + to a non-const lvalue reference are allowed. + Deprecated Compiler Flags - diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index a6f36b23f07dc..188cea2c900c7 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -306,6 +306,7 @@ LANGOPT(HIPStdParInterposeAlloc, 1, 0, "Replace allocations / deallocations with LANGOPT(OpenACC , 1, 0, "OpenACC Enabled") LANGOPT(MSVCEnableStdcMacro , 1, 0, "Define __STDC__ with '-fms-compatibility'") +LANGOPT(MSVCReferenceBinding , 1, 0, "Accept expressions that bind a non-const lvalue reference to a temporary") LANGOPT(SizedDeallocation , 1, 0, "sized deallocation") LANGOPT(AlignedAllocation , 1, 0, "aligned allocation") LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 8707e71f2a319..cd568c9f8f60f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3036,6 +3036,12 @@ def fms_extensions : Flag<["-"], "fms-extensions">, Group, Visibility<[ClangOption, CC1Option, CLOption]>, HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">, MarshallingInfoFlag>, ImpliedByAnyOf<[fms_compatibility.KeyPath]>; +def fms_reference_binding : Flag<["-"], "fms-reference-binding">, Group, + Visibility<[ClangOption, CC1Option, CLOption]>, + HelpText<"Accept expressions that bind a non-const lvalue reference to a user-defined type temporary as supported by the Microsoft Compiler">, + MarshallingInfoFlag>; +def fno_ms_reference_binding : Flag<["-"], "fno-ms-reference-binding">, Group, + Visibility<[ClangOption, CLOption]>; defm asm_blocks : BoolFOption<"asm-blocks", LangOpts<"AsmBlocks">, Default, PosFlag, @@ -8467,6 +8473,12 @@ def _SLASH_Zc_wchar_t : CLFlag<"Zc:wchar_t">, HelpText<"Enable C++ builtin type wchar_t (default)">; def _SLASH_Zc_wchar_t_ : CLFlag<"Zc:wchar_t-">, HelpText<"Disable C++ builtin type wchar_t">; +def _SLASH_Zc_referenceBinding : CLFlag<"Zc:referenceBinding">, + HelpText<"Do not accept expressions that bind a non-const lvalue reference to a user-defined type temporary">, + Alias; +def _SLASH_Zc_referenceBinding_ : CLFlag<"Zc:referenceBinding-">, + HelpText<"Accept expressions that bind a non-const lvalue reference to a user-defined type temporary">, + Alias; def _SLASH_Z7 : CLFlag<"Z7">, Alias, HelpText<"Enable CodeView debug information in object files">; def _SLASH_ZH_MD5 : CLFlag<"ZH:MD5">, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d638d31e050dc..34ea43c3fa2e2 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10158,6 +10158,8 @@ class Sema final : public SemaBase { CompareReferenceRelationship(SourceLocation Loc, QualType T1, QualType T2, ReferenceConversions *Conv = nullptr); + bool AllowMSLValueReferenceBinding(Qualifiers Quals, QualType QT); + /// AddOverloadCandidate - Adds the given function to the set of /// candidate functions, using the given function call arguments. If /// @p SuppressUserConversions, then don't allow user-defined diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 71cd
[clang] [clang-cl] [Sema] Support MSVC non-const lvalue to user-defined temporary reference (PR #99833)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/99833 >From e0528ecc441e33822426b8b3d6522d056c95bb54 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Fri, 21 Jun 2024 20:37:40 -0700 Subject: [PATCH 1/6] Support MSVC lvalue to temporary reference binding --- clang/docs/ReleaseNotes.rst | 4 + clang/include/clang/Basic/LangOptions.def | 1 + clang/include/clang/Driver/Options.td | 12 +++ clang/include/clang/Sema/Sema.h | 2 + clang/lib/Driver/ToolChains/Clang.cpp | 5 + clang/lib/Driver/ToolChains/MSVC.cpp| 1 + clang/lib/Sema/SemaInit.cpp | 22 +++-- clang/lib/Sema/SemaOverload.cpp | 16 ++- clang/test/Driver/cl-permissive.c | 7 ++ clang/test/Driver/cl-zc.cpp | 2 + clang/test/SemaCXX/ms-reference-binding.cpp | 102 11 files changed, 165 insertions(+), 9 deletions(-) create mode 100644 clang/test/SemaCXX/ms-reference-binding.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4638b91b48f95..567effa83f845 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -486,6 +486,10 @@ New Compiler Flags - ``-fpointer-tbaa`` enables emission of distinct type-based alias analysis tags for incompatible pointers. +- ``-fms-reference-binding`` and its clang-cl counterpart ``/Zc:referenceBinding``. + Implements the MSVC extension where expressions that bind a user-defined type temporary + to a non-const lvalue reference are allowed. + Deprecated Compiler Flags - diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index a6f36b23f07dc..188cea2c900c7 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -306,6 +306,7 @@ LANGOPT(HIPStdParInterposeAlloc, 1, 0, "Replace allocations / deallocations with LANGOPT(OpenACC , 1, 0, "OpenACC Enabled") LANGOPT(MSVCEnableStdcMacro , 1, 0, "Define __STDC__ with '-fms-compatibility'") +LANGOPT(MSVCReferenceBinding , 1, 0, "Accept expressions that bind a non-const lvalue reference to a temporary") LANGOPT(SizedDeallocation , 1, 0, "sized deallocation") LANGOPT(AlignedAllocation , 1, 0, "aligned allocation") LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 8707e71f2a319..cd568c9f8f60f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3036,6 +3036,12 @@ def fms_extensions : Flag<["-"], "fms-extensions">, Group, Visibility<[ClangOption, CC1Option, CLOption]>, HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">, MarshallingInfoFlag>, ImpliedByAnyOf<[fms_compatibility.KeyPath]>; +def fms_reference_binding : Flag<["-"], "fms-reference-binding">, Group, + Visibility<[ClangOption, CC1Option, CLOption]>, + HelpText<"Accept expressions that bind a non-const lvalue reference to a user-defined type temporary as supported by the Microsoft Compiler">, + MarshallingInfoFlag>; +def fno_ms_reference_binding : Flag<["-"], "fno-ms-reference-binding">, Group, + Visibility<[ClangOption, CLOption]>; defm asm_blocks : BoolFOption<"asm-blocks", LangOpts<"AsmBlocks">, Default, PosFlag, @@ -8467,6 +8473,12 @@ def _SLASH_Zc_wchar_t : CLFlag<"Zc:wchar_t">, HelpText<"Enable C++ builtin type wchar_t (default)">; def _SLASH_Zc_wchar_t_ : CLFlag<"Zc:wchar_t-">, HelpText<"Disable C++ builtin type wchar_t">; +def _SLASH_Zc_referenceBinding : CLFlag<"Zc:referenceBinding">, + HelpText<"Do not accept expressions that bind a non-const lvalue reference to a user-defined type temporary">, + Alias; +def _SLASH_Zc_referenceBinding_ : CLFlag<"Zc:referenceBinding-">, + HelpText<"Accept expressions that bind a non-const lvalue reference to a user-defined type temporary">, + Alias; def _SLASH_Z7 : CLFlag<"Z7">, Alias, HelpText<"Enable CodeView debug information in object files">; def _SLASH_ZH_MD5 : CLFlag<"ZH:MD5">, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d638d31e050dc..34ea43c3fa2e2 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10158,6 +10158,8 @@ class Sema final : public SemaBase { CompareReferenceRelationship(SourceLocation Loc, QualType T1, QualType T2, ReferenceConversions *Conv = nullptr); + bool AllowMSLValueReferenceBinding(Qualifiers Quals, QualType QT); + /// AddOverloadCandidate - Adds the given function to the set of /// candidate functions, using the given function call arguments. If /// @p SuppressUserConversions, then don't allow user-defined diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 71cd
[clang] [clang-cl] [Sema] Support MSVC non-const lvalue to user-defined temporary reference (PR #99833)
https://github.com/MaxEW707 updated https://github.com/llvm/llvm-project/pull/99833 >From e0528ecc441e33822426b8b3d6522d056c95bb54 Mon Sep 17 00:00:00 2001 From: MaxEW707 Date: Fri, 21 Jun 2024 20:37:40 -0700 Subject: [PATCH 1/7] Support MSVC lvalue to temporary reference binding --- clang/docs/ReleaseNotes.rst | 4 + clang/include/clang/Basic/LangOptions.def | 1 + clang/include/clang/Driver/Options.td | 12 +++ clang/include/clang/Sema/Sema.h | 2 + clang/lib/Driver/ToolChains/Clang.cpp | 5 + clang/lib/Driver/ToolChains/MSVC.cpp| 1 + clang/lib/Sema/SemaInit.cpp | 22 +++-- clang/lib/Sema/SemaOverload.cpp | 16 ++- clang/test/Driver/cl-permissive.c | 7 ++ clang/test/Driver/cl-zc.cpp | 2 + clang/test/SemaCXX/ms-reference-binding.cpp | 102 11 files changed, 165 insertions(+), 9 deletions(-) create mode 100644 clang/test/SemaCXX/ms-reference-binding.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4638b91b48f95..567effa83f845 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -486,6 +486,10 @@ New Compiler Flags - ``-fpointer-tbaa`` enables emission of distinct type-based alias analysis tags for incompatible pointers. +- ``-fms-reference-binding`` and its clang-cl counterpart ``/Zc:referenceBinding``. + Implements the MSVC extension where expressions that bind a user-defined type temporary + to a non-const lvalue reference are allowed. + Deprecated Compiler Flags - diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index a6f36b23f07dc..188cea2c900c7 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -306,6 +306,7 @@ LANGOPT(HIPStdParInterposeAlloc, 1, 0, "Replace allocations / deallocations with LANGOPT(OpenACC , 1, 0, "OpenACC Enabled") LANGOPT(MSVCEnableStdcMacro , 1, 0, "Define __STDC__ with '-fms-compatibility'") +LANGOPT(MSVCReferenceBinding , 1, 0, "Accept expressions that bind a non-const lvalue reference to a temporary") LANGOPT(SizedDeallocation , 1, 0, "sized deallocation") LANGOPT(AlignedAllocation , 1, 0, "aligned allocation") LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 8707e71f2a319..cd568c9f8f60f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3036,6 +3036,12 @@ def fms_extensions : Flag<["-"], "fms-extensions">, Group, Visibility<[ClangOption, CC1Option, CLOption]>, HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">, MarshallingInfoFlag>, ImpliedByAnyOf<[fms_compatibility.KeyPath]>; +def fms_reference_binding : Flag<["-"], "fms-reference-binding">, Group, + Visibility<[ClangOption, CC1Option, CLOption]>, + HelpText<"Accept expressions that bind a non-const lvalue reference to a user-defined type temporary as supported by the Microsoft Compiler">, + MarshallingInfoFlag>; +def fno_ms_reference_binding : Flag<["-"], "fno-ms-reference-binding">, Group, + Visibility<[ClangOption, CLOption]>; defm asm_blocks : BoolFOption<"asm-blocks", LangOpts<"AsmBlocks">, Default, PosFlag, @@ -8467,6 +8473,12 @@ def _SLASH_Zc_wchar_t : CLFlag<"Zc:wchar_t">, HelpText<"Enable C++ builtin type wchar_t (default)">; def _SLASH_Zc_wchar_t_ : CLFlag<"Zc:wchar_t-">, HelpText<"Disable C++ builtin type wchar_t">; +def _SLASH_Zc_referenceBinding : CLFlag<"Zc:referenceBinding">, + HelpText<"Do not accept expressions that bind a non-const lvalue reference to a user-defined type temporary">, + Alias; +def _SLASH_Zc_referenceBinding_ : CLFlag<"Zc:referenceBinding-">, + HelpText<"Accept expressions that bind a non-const lvalue reference to a user-defined type temporary">, + Alias; def _SLASH_Z7 : CLFlag<"Z7">, Alias, HelpText<"Enable CodeView debug information in object files">; def _SLASH_ZH_MD5 : CLFlag<"ZH:MD5">, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d638d31e050dc..34ea43c3fa2e2 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10158,6 +10158,8 @@ class Sema final : public SemaBase { CompareReferenceRelationship(SourceLocation Loc, QualType T1, QualType T2, ReferenceConversions *Conv = nullptr); + bool AllowMSLValueReferenceBinding(Qualifiers Quals, QualType QT); + /// AddOverloadCandidate - Adds the given function to the set of /// candidate functions, using the given function call arguments. If /// @p SuppressUserConversions, then don't allow user-defined diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 71cd
[clang] [clang-cl] [Sema] Support MSVC non-const lvalue to user-defined temporary reference (PR #99833)
MaxEW707 wrote: > The scenario I am thinking about is when the user passed -fms-extensions and > no other individual flags. I think that mode should enable all of the > Microsoft extensions. Then users can opt out of whatever extensions they > don't want to enable. But I think it's confusing if -fms-extensions still > requires the user to explicitly opt in to other Microsoft-specific extensions. That is a fair point. I did some further digging. Starting with C++20 MSVC starting enforcing various C++ conformance options by default. For example `/permissive-` is the default now meaning `/Zc:referenceBinding` is set. MSVC does not allow its custom reference binding rules by default anymore. Godbolt for reference: https://godbolt.org/z/6hTeGeb6x. We already do similar behaviour in the driver for the `delayed-template-parsing` extension. `delayed-template-parsing`, called `/Zc:twoPhase-` in MSVC driver parlance, is enabled by default if we are windows msvc and not C++20 since MSVC does two-phase lookup by default in C++20 onwards. In this PR I now enable `ms-reference-binding` by default if we are windows msvc and not C++20 as well to imitate MSVC behaviour. `ms-reference-binding` is still an individual controllable option and is also properly set if you use the `/permissive` or `/permissive-` larger group option in the cl driver mode. I wrote up a small gist here about what `-fms-extensions` covers, https://gist.github.com/MaxEW707/3fbb3a223710b6aa9269f7ffbdccbfc9. Most of it are things that you always want if you are targeting msvc which include the implicit `_GUID` struct, calling convention identifiers like `__stdcall`, SEH identifiers like `__finally`, Microsoft pragma support, builtin macros like `_WCHAR_T_DEFINED`, imitating MSVC PP token pasting behaviour, handling ^Z EOF in the lexer, etc. It also includes Microsoft extensions that do not have a conformance mode toggle currently in MSVC such as allowing a static declaration to follow an extern declaration, allowing inline function definitions on pure virtual methods, allowing type definitions inside an anonymous union/struct, etc. Most of these extensions in this category so far are fairly benign and don't alter the language semantics much compared to two-phase lookup or reference binding for example. Let me know if this is a satisfactory compromise :). I think it models what seems to be the precedent especially around two-phase lookup. https://github.com/llvm/llvm-project/pull/99833 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits