From c55f729746794e33c789e49fac7c20b146f4fce1 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Wed, 4 Feb 2015 04:45:32 +0000 Subject: [PATCH] [MSVC2012] Allow 'mutable' references Some standard header files from MSVC2012 use 'mutable' on references, though it is directly prohibited by the standard. Fix for http://llvm.org/PR22444 Differential Revision: http://reviews.llvm.org/D7370 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@228113 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 3 +++ lib/Sema/SemaDecl.cpp | 9 ++++++--- test/SemaCXX/ms_mutable_reference_member.cpp | 13 +++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 test/SemaCXX/ms_mutable_reference_member.cpp diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index b17ebf6cf8..0ca9edfab7 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1241,6 +1241,9 @@ def err_storageclass_invalid_for_member : Error< "storage class specified for a member declaration">; def err_mutable_function : Error<"'mutable' cannot be applied to functions">; def err_mutable_reference : Error<"'mutable' cannot be applied to references">; +def ext_mutable_reference : ExtWarn< + "'mutable' on a reference type is a Microsoft extension">, + InGroup; def err_mutable_const : Error<"'mutable' and 'const' cannot be mixed">; def err_mutable_nonmember : Error< "'mutable' can only be applied to member variables">; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index eb21dff766..a5ce9a0277 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -12348,7 +12348,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, if (!InvalidDecl && Mutable) { unsigned DiagID = 0; if (T->isReferenceType()) - DiagID = diag::err_mutable_reference; + DiagID = getLangOpts().MSVCCompat ? diag::ext_mutable_reference + : diag::err_mutable_reference; else if (T.isConstQualified()) DiagID = diag::err_mutable_const; @@ -12357,8 +12358,10 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, if (D && D->getDeclSpec().getStorageClassSpecLoc().isValid()) ErrLoc = D->getDeclSpec().getStorageClassSpecLoc(); Diag(ErrLoc, DiagID); - Mutable = false; - InvalidDecl = true; + if (DiagID != diag::ext_mutable_reference) { + Mutable = false; + InvalidDecl = true; + } } } diff --git a/test/SemaCXX/ms_mutable_reference_member.cpp b/test/SemaCXX/ms_mutable_reference_member.cpp new file mode 100644 index 0000000000..ae1389d333 --- /dev/null +++ b/test/SemaCXX/ms_mutable_reference_member.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-compatibility + +struct S { + mutable int &a; // expected-warning {{'mutable' on a reference type is a Microsoft extension}} + S(int &b) : a(b) {} +}; + +int main() { + int a = 0; + const S s(a); + s.a = 10; + return s.a + a; +}