// 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)
-// RUN: %clang_cc1 -verify %s
-// XFAIL: *
+// RUN: %clang_cc1 -fsyntax-only -verify %s
typedef const int T0;
typedef int& T1;
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}}
};