[clang] [clang] Add `intrin0.h` header to mimic `intrin0.h` used by MSVC STL for clang-cl (PR #75711)

2023-12-18 Thread Max Winkler via cfe-commits

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)

2023-12-18 Thread Max Winkler via cfe-commits

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)

2023-12-19 Thread Max Winkler via cfe-commits

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)

2023-12-19 Thread Max Winkler via cfe-commits

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)

2023-12-19 Thread Max Winkler via cfe-commits

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)

2023-12-19 Thread Max Winkler via cfe-commits

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)

2023-12-19 Thread Max Winkler via cfe-commits


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

2023-12-19 Thread Max Winkler via cfe-commits

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)

2023-12-19 Thread Max Winkler via cfe-commits

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)

2023-12-19 Thread Max Winkler via cfe-commits

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)

2023-12-19 Thread Max Winkler via cfe-commits

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)

2023-12-19 Thread Max Winkler via cfe-commits

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)

2023-12-19 Thread Max Winkler via cfe-commits


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

2023-12-19 Thread Max Winkler via cfe-commits

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)

2023-12-20 Thread Max Winkler via cfe-commits

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)

2023-12-20 Thread Max Winkler via cfe-commits

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)

2023-12-24 Thread Max Winkler via cfe-commits

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)

2023-12-24 Thread Max Winkler via cfe-commits

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)

2023-12-24 Thread Max Winkler via cfe-commits

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)

2023-12-29 Thread Max Winkler via cfe-commits

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)

2023-12-29 Thread Max Winkler via cfe-commits

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)

2023-12-29 Thread Max Winkler via cfe-commits

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)

2023-12-29 Thread Max Winkler via cfe-commits

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)

2023-12-29 Thread Max Winkler via cfe-commits

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)

2023-12-29 Thread Max Winkler via cfe-commits

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)

2023-12-29 Thread Max Winkler via cfe-commits

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)

2023-12-29 Thread Max Winkler via cfe-commits

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)

2023-12-29 Thread Max Winkler via cfe-commits

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)

2023-12-30 Thread Max Winkler via cfe-commits

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)

2023-12-30 Thread Max Winkler via cfe-commits

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)

2023-12-30 Thread Max Winkler via cfe-commits

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)

2023-12-31 Thread Max Winkler via cfe-commits

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)

2023-12-31 Thread Max Winkler via cfe-commits

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)

2024-01-08 Thread Max Winkler via cfe-commits

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)

2024-01-10 Thread Max Winkler via cfe-commits

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)

2024-01-10 Thread Max Winkler via cfe-commits

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)

2024-03-31 Thread Max Winkler via cfe-commits

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)

2024-03-31 Thread Max Winkler via cfe-commits

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)

2024-03-31 Thread Max Winkler via cfe-commits

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)

2024-04-01 Thread Max Winkler via cfe-commits


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

2024-04-01 Thread Max Winkler via cfe-commits

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)

2024-02-13 Thread Max Winkler via cfe-commits

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)

2024-03-05 Thread Max Winkler via cfe-commits

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)

2024-03-06 Thread Max Winkler via cfe-commits

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)

2024-03-07 Thread Max Winkler via cfe-commits

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)

2024-03-09 Thread Max Winkler via cfe-commits

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)

2024-03-09 Thread Max Winkler via cfe-commits

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)

2024-02-24 Thread Max Winkler via cfe-commits

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)

2024-02-24 Thread Max Winkler via cfe-commits


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

2024-02-24 Thread Max Winkler via cfe-commits

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)

2024-03-03 Thread Max Winkler via cfe-commits

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)

2024-01-29 Thread Max Winkler via cfe-commits

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)

2024-01-15 Thread Max Winkler via cfe-commits

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)

2024-07-04 Thread Max Winkler via cfe-commits

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)

2024-07-05 Thread Max Winkler via cfe-commits

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)

2024-07-05 Thread Max Winkler via cfe-commits


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

2024-07-07 Thread Max Winkler via cfe-commits

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)

2024-07-07 Thread Max Winkler via cfe-commits

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)

2024-09-03 Thread Max Winkler via cfe-commits

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)

2024-09-03 Thread Max Winkler via cfe-commits

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)

2024-09-03 Thread Max Winkler via cfe-commits

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)

2024-09-04 Thread Max Winkler via cfe-commits

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)

2024-09-05 Thread Max Winkler via cfe-commits

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)

2024-09-05 Thread Max Winkler via cfe-commits

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)

2024-09-08 Thread Max Winkler via cfe-commits

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)

2024-08-11 Thread Max Winkler via cfe-commits

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)

2024-08-11 Thread Max Winkler via cfe-commits

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)

2024-08-11 Thread Max Winkler via cfe-commits

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)

2024-08-11 Thread Max Winkler via cfe-commits

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)

2024-08-12 Thread Max Winkler via cfe-commits

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)

2024-08-12 Thread Max Winkler via cfe-commits


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

2024-08-12 Thread Max Winkler via cfe-commits


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

2024-08-12 Thread Max Winkler via cfe-commits

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)

2024-08-12 Thread Max Winkler via cfe-commits

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)

2024-08-12 Thread Max Winkler via cfe-commits

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)

2024-08-12 Thread Max Winkler via cfe-commits

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)

2024-08-13 Thread Max Winkler via cfe-commits

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)

2024-08-13 Thread Max Winkler via cfe-commits

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)

2024-08-14 Thread Max Winkler via cfe-commits


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

2024-08-14 Thread Max Winkler via cfe-commits

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)

2024-08-14 Thread Max Winkler via cfe-commits

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)

2024-08-15 Thread Max Winkler via cfe-commits

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)

2024-04-04 Thread Max Winkler via cfe-commits


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

2024-04-04 Thread Max Winkler via cfe-commits

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)

2024-04-04 Thread Max Winkler via cfe-commits

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)

2024-04-07 Thread Max Winkler via cfe-commits

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)

2024-04-07 Thread Max Winkler via cfe-commits

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)

2024-04-09 Thread Max Winkler via cfe-commits

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)

2024-04-09 Thread Max Winkler via cfe-commits

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)

2024-06-17 Thread Max Winkler via cfe-commits

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)

2024-06-18 Thread Max Winkler via cfe-commits

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)

2024-06-20 Thread Max Winkler via cfe-commits

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)

2024-04-15 Thread Max Winkler via cfe-commits

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)

2024-04-16 Thread Max Winkler via cfe-commits

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)

2024-07-24 Thread Max Winkler via cfe-commits

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)

2024-07-26 Thread Max Winkler via cfe-commits

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)

2024-07-29 Thread Max Winkler via cfe-commits

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)

2024-07-29 Thread Max Winkler via cfe-commits

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)

2024-07-29 Thread Max Winkler via cfe-commits

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)

2024-07-29 Thread Max Winkler via cfe-commits

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


  1   2   >