Skip to content

Commit 9088ac1

Browse files
authored
[Clang] [Sema] Error on reference types inside a union with msvc 1900+ (#102851)
Godbolt for reference: https://godbolt.org/z/ovKjvWc46 I can confirm that this extension is no longer valid in VS2017, VS2019 and VS2022 under `/permissive` and `/permissive-` MSDN, https://learn.microsoft.com/en-us/cpp/porting/visual-cpp-what-s-new-2003-through-2015?view=msvc-170, says this extension was officially removed in VS2015.
1 parent f861e33 commit 9088ac1

File tree

3 files changed

+29
-19
lines changed

3 files changed

+29
-19
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,12 @@ Android Support
321321
Windows Support
322322
^^^^^^^^^^^^^^^
323323

324+
- Clang no longer allows references inside a union when emulating MSVC 1900+ even if `fms-extensions` is enabled.
325+
Starting with VS2015, MSVC 1900, this Microsoft extension is no longer allowed and always results in an error.
326+
Clang now follows the MSVC behavior in this scenario.
327+
When `-fms-compatibility-version=18.00` or prior is set on the command line this Microsoft extension is still
328+
allowed as VS2013 and prior allow it.
329+
324330
LoongArch Support
325331
^^^^^^^^^^^^^^^^^
326332

clang/lib/Sema/SemaDecl.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18507,11 +18507,15 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
1850718507
// the program is ill-formed, except when compiling with MSVC extensions
1850818508
// enabled.
1850918509
if (EltTy->isReferenceType()) {
18510-
Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ?
18511-
diag::ext_union_member_of_reference_type :
18512-
diag::err_union_member_of_reference_type)
18513-
<< NewFD->getDeclName() << EltTy;
18514-
if (!getLangOpts().MicrosoftExt)
18510+
const bool HaveMSExt =
18511+
getLangOpts().MicrosoftExt &&
18512+
!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015);
18513+
18514+
Diag(NewFD->getLocation(),
18515+
HaveMSExt ? diag::ext_union_member_of_reference_type
18516+
: diag::err_union_member_of_reference_type)
18517+
<< NewFD->getDeclName() << EltTy;
18518+
if (!HaveMSExt)
1851518519
NewFD->setInvalidDecl();
1851618520
}
1851718521
}

clang/test/SemaCXX/MicrosoftExtensions.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
2-
// RUN: %clang_cc1 -std=c++98 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
3-
// 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
4-
// 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
5-
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -fms-compatibility -verify -DTEST3
1+
// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,ms-union-ext -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
2+
// RUN: %clang_cc1 -std=c++98 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17,ms-union-ext -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
3+
// RUN: %clang_cc1 -std=c++11 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17,ms-union-ext -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
4+
// RUN: %clang_cc1 -std=c++14 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17,ms-union-ext-disabled -fexceptions -fcxx-exceptions -DTEST2
5+
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -fms-compatibility -verify=expected,ms-union-ext -DTEST3
6+
// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify=ms-union-ext -fms-extensions -fms-compatibility-version=18.00
7+
// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify=ms-union-ext-disabled -fms-extensions -fms-compatibility-version=19.00
68

79
#if TEST1
810

@@ -384,11 +386,6 @@ void TestSP9() {
384386
c3.h(); // Overloaded unary op operand
385387
}
386388

387-
union u {
388-
int *i1;
389-
int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}}
390-
};
391-
392389
// Property getter using reference.
393390
struct SP11 {
394391
__declspec(property(get=GetV)) int V;
@@ -619,9 +616,12 @@ template<typename T> struct A {};
619616
template<typename T> struct B : A<A<T>> { A<T>::C::D d; }; // expected-warning {{implicit 'typename' is a C++20 extension}}
620617
}
621618

622-
#else
623-
624-
#error Unknown test mode
625-
626619
#endif
627620

621+
union u {
622+
int *i1;
623+
624+
// ms-union-ext-warning@+2 {{union member 'i2' has reference type 'int &', which is a Microsoft extension}}
625+
// ms-union-ext-disabled-error@+1 {{union member 'i2' has reference type 'int &'}}
626+
int &i2;
627+
};

0 commit comments

Comments
 (0)