From 3882aed80cbb38e007e4fb80076b400a9a4b8445 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 19 Jun 2013 13:41:54 +0000 Subject: [PATCH] Fix pr16354. We now reject things like struct ABC { static double a; }; register double ABC::a = 1.0; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184300 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaDecl.cpp | 22 +++++++++++++++++++++- test/SemaCXX/static-data-member.cpp | 17 +++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 test/SemaCXX/static-data-member.cpp diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 84f98a95d0..fd84b42e4f 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1110,6 +1110,8 @@ def err_explicit_non_ctor_or_conv_function : Error< def err_static_not_bitfield : Error<"static member %0 cannot be a bit-field">; def err_static_out_of_line : Error< "'static' can only be specified inside the class definition">; +def err_storage_class_for_static_member : Error< + "static data member definition cannot specify a storage class">; def err_typedef_not_bitfield : Error<"typedef member %0 cannot be a bit-field">; def err_not_integral_type_bitfield : Error< "bit-field %0 has non-integral type %1">; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 418a70a8ba..d9c5fe0af8 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4807,10 +4807,30 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } else { if (DC->isRecord() && !CurContext->isRecord()) { // This is an out-of-line definition of a static data member. - if (SC == SC_Static) { + switch (SC) { + case SC_None: + break; + case SC_Static: Diag(D.getDeclSpec().getStorageClassSpecLoc(), diag::err_static_out_of_line) << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc()); + break; + case SC_Auto: + case SC_Register: + case SC_Extern: + // [dcl.stc] p2: The auto or register specifiers shall be applied only + // to names of variables declared in a block or to function parameters. + // [dcl.stc] p6: The extern specifier cannot be used in the declaration + // of class members + + Diag(D.getDeclSpec().getStorageClassSpecLoc(), + diag::err_storage_class_for_static_member) + << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc()); + break; + case SC_PrivateExtern: + llvm_unreachable("C storage class in c++!"); + case SC_OpenCLWorkGroupLocal: + llvm_unreachable("OpenCL storage class in c++!"); } } if (SC == SC_Static && CurContext->isRecord()) { diff --git a/test/SemaCXX/static-data-member.cpp b/test/SemaCXX/static-data-member.cpp new file mode 100644 index 0000000000..9fe87b1c1d --- /dev/null +++ b/test/SemaCXX/static-data-member.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -w %s + +struct ABC { + static double a; + static double b; + static double c; + static double d; + static double e; + static double f; +}; + +double ABC::a = 1.0; +extern double ABC::b = 1.0; // expected-error {{static data member definition cannot specify a storage class}} +static double ABC::c = 1.0; // expected-error {{'static' can only be specified inside the class definition}} +__private_extern__ double ABC::d = 1.0; // expected-error {{static data member definition cannot specify a storage class}} +auto double ABC::e = 1.0; // expected-error {{static data member definition cannot specify a storage class}} +register double ABC::f = 1.0; // expected-error {{static data member definition cannot specify a storage class}} -- 2.40.0