diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 394583090723..a0ce7663a827 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3344,10 +3344,15 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, // Note that a linkage-specification sets a storage class, but // 'extern "C" struct foo;' is actually valid and not theoretically // useless. - if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) - if (!DS.isExternInLinkageSpec() && SCS != DeclSpec::SCS_typedef) + if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) { + if (SCS == DeclSpec::SCS_mutable) + // Since mutable is not a viable storage class specifier in C, there is + // no reason to treat it as an extension. Instead, diagnose as an error. + Diag(DS.getStorageClassSpecLoc(), diag::err_mutable_nonmember); + else if (!DS.isExternInLinkageSpec() && SCS != DeclSpec::SCS_typedef) Diag(DS.getStorageClassSpecLoc(), DiagID) << DeclSpec::getSpecifierName(SCS); + } if (DeclSpec::TSCS TSCS = DS.getThreadStorageClassSpec()) Diag(DS.getThreadStorageClassSpecLoc(), DiagID) diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp index fd86276e8548..d7e7c52f3f70 100644 --- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -verify %s -// XFAIL: * +// RUN: %clang_cc1 -fsyntax-only -verify %s typedef const int T0; typedef int& T1; @@ -9,6 +8,6 @@ struct s0 { mutable T0 f1; // expected-error{{'mutable' and 'const' cannot be mixed}} mutable int &f2; // expected-error{{'mutable' cannot be applied to references}} mutable T1 f3; // expected-error{{'mutable' cannot be applied to references}} - mutable struct s1 {}; // expected-error{{'mutable' cannot be applied to non-data members}} + mutable struct s1 {}; // expected-error{{'mutable' can only be applied to member variables}} mutable void im0(); // expected-error{{'mutable' cannot be applied to functions}} };