diff options
| author | Hans Wennborg <hans@hanshq.net> | 2013-11-21 03:17:44 +0000 |
|---|---|---|
| committer | Hans Wennborg <hans@hanshq.net> | 2013-11-21 03:17:44 +0000 |
| commit | 84fe12d1e954a344b24069367bd5282b6a08dcc7 (patch) | |
| tree | e99320b901340bed5833cf680ec1f7f35018c76d | |
| parent | 4a4b5dcb7d76eb852d620fff9924a29cb0f63afa (diff) | |
| download | bcm5719-llvm-84fe12d1e954a344b24069367bd5282b6a08dcc7.tar.gz bcm5719-llvm-84fe12d1e954a344b24069367bd5282b6a08dcc7.zip | |
Provide better diagnostic wording for initializers on static
data member definitions when the variable has an initializer
in its declaration.
For the following code:
struct S {
static const int x = 42;
};
const int S::x = 42;
This patch changes the diagnostic from:
a.cc:4:14: error: redefinition of 'x'
const int S::x = 42;
^
a.cc:2:20: note: previous definition is here
static const int x = 42;
^
to:
a.cc:4:18: error: static data member 'x' already has an initializer
const int S::x = 42;
^
a.cc:2:24: note: previous initialization is here
static const int x = 42;
^
Differential Revision: http://llvm-reviews.chandlerc.com/D2235
llvm-svn: 195306
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 6 | ||||
| -rw-r--r-- | clang/test/CXX/class/class.static/class.static.data/p4.cpp | 9 | ||||
| -rw-r--r-- | clang/test/CXX/drs/dr0xx.cpp | 5 | ||||
| -rw-r--r-- | clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp | 8 |
5 files changed, 15 insertions, 15 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5963ec4e0fb..b84293c6794 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3520,6 +3520,8 @@ def note_declaration_not_a_prototype : Note< def warn_missing_variable_declarations : Warning< "no previous extern declaration for non-static variable %0">, InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore; +def err_static_data_member_reinitialization : + Error<"static data member %0 already has an initializer">; def err_redefinition : Error<"redefinition of %0">; def err_alias_after_tentative : Error<"alias definition of %0 after tentative definition">; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index cd643118ee9..6d5e0f01268 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -8184,9 +8184,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // data members we also need to check whether there was an in-class // declaration with an initializer. if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) { - Diag(VDecl->getLocation(), diag::err_redefinition) - << VDecl->getDeclName(); - Diag(PrevInit->getLocation(), diag::note_previous_definition); + Diag(Init->getExprLoc(), diag::err_static_data_member_reinitialization) + << VDecl->getDeclName(); + Diag(PrevInit->getInit()->getExprLoc(), diag::note_previous_initializer) << 0; return; } diff --git a/clang/test/CXX/class/class.static/class.static.data/p4.cpp b/clang/test/CXX/class/class.static/class.static.data/p4.cpp index 2b1eca74193..85d18c6b5fa 100644 --- a/clang/test/CXX/class/class.static/class.static.data/p4.cpp +++ b/clang/test/CXX/class/class.static/class.static.data/p4.cpp @@ -10,15 +10,14 @@ struct OutOfClassInitializerOnly { int const OutOfClassInitializerOnly::i = 0; struct InClassInitializerAndOutOfClassCopyInitializer { - static const int i = 0; // expected-note{{previous definition is here}} + static const int i = 0; // expected-note{{previous initialization is here}} }; -int const InClassInitializerAndOutOfClassCopyInitializer::i = 0; // expected-error{{redefinition of 'i'}} +int const InClassInitializerAndOutOfClassCopyInitializer::i = 0; // expected-error{{static data member 'i' already has an initializer}} struct InClassInitializerAndOutOfClassDirectInitializer { - static const int i = 0; // expected-note{{previous definition is here}} + static const int i = 0; // expected-note{{previous initialization is here}} }; -int const InClassInitializerAndOutOfClassDirectInitializer::i(0); // expected-error{{redefinition of 'i'}} - +int const InClassInitializerAndOutOfClassDirectInitializer::i(0); // expected-error{{static data member 'i' already has an initializer}} int main() { } diff --git a/clang/test/CXX/drs/dr0xx.cpp b/clang/test/CXX/drs/dr0xx.cpp index 265a52d9261..57e3a754c54 100644 --- a/clang/test/CXX/drs/dr0xx.cpp +++ b/clang/test/CXX/drs/dr0xx.cpp @@ -919,11 +919,10 @@ namespace dr87 { // dr87: no namespace dr88 { // dr88: yes template<typename T> struct S { - static const int a = 1; + static const int a = 1; // expected-note {{previous}} static const int b; }; - // FIXME: This diagnostic is pretty bad. - template<> const int S<int>::a = 4; // expected-error {{redefinition}} expected-note {{previous}} + template<> const int S<int>::a = 4; // expected-error {{already has an initializer}} template<> const int S<int>::b = 4; } diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp index 94d0f16f06e..1e959364280 100644 --- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp +++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp @@ -39,11 +39,11 @@ namespace out_of_line { template<typename T> CONST T B1::right<T,int> = T(5); class B2 { - template<typename T, typename T0> static CONST T right = T(100); // expected-note {{previous definition is here}} - template<typename T> static CONST T right<T,int> = T(5); // expected-note {{previous definition is here}} + template<typename T, typename T0> static CONST T right = T(100); // expected-note {{previous initialization is here}} + template<typename T> static CONST T right<T,int> = T(5); // expected-note {{previous initialization is here}} }; - template<typename T, typename T0> CONST T B2::right = T(100); // expected-error {{redefinition of 'right'}} - template<typename T> CONST T B2::right<T,int> = T(5); // expected-error {{redefinition of 'right'}} + template<typename T, typename T0> CONST T B2::right = T(100); // expected-error {{static data member 'right' already has an initializer}} + template<typename T> CONST T B2::right<T,int> = T(5); // expected-error {{static data member 'right' already has an initializer}} class B3 { template<typename T, typename T0> static CONST T right = T(100); |

