<div dir="ltr">I like this change, but I wonder if we can come up with a better wording for the diagnostic than "re-initialization". Strawman:<div><br></div><div>"static data member %0 already has an initializer"</div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 20, 2013 at 2:44 PM, Hans Wennborg <span dir="ltr"><<a href="mailto:hans@chromium.org" target="_blank">hans@chromium.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi rsmith,<br>
<br>
+richard, because he put in the fixme in test/CXX/drs/dr0xx.cpp:925.<br>
<br>
For the following code:<br>
struct S {<br>
static const int x = 42;<br>
};<br>
const int S::x = 42;<br>
<br>
This patch changes the diagnostic from:<br>
<br>
a.cc:4:14: error: redefinition of 'x'<br>
const int S::x = 42;<br>
^<br>
a.cc:2:20: note: previous definition is here<br>
static const int x = 42;<br>
^<br>
to:<br>
<br>
a.cc:4:18: error: re-initialization of static data member 'x'<br>
const int S::x = 42;<br>
^<br>
a.cc:2:24: note: previous initialization is here<br>
static const int x = 42;<br>
^<br>
<br>
<a href="http://llvm-reviews.chandlerc.com/D2235" target="_blank">http://llvm-reviews.chandlerc.com/D2235</a><br>
<br>
Files:<br>
include/clang/Basic/DiagnosticSemaKinds.td<br>
lib/Sema/SemaDecl.cpp<br>
test/CXX/class/class.static/class.static.data/p4.cpp<br>
test/CXX/drs/dr0xx.cpp<br>
test/SemaCXX/cxx1y-variable-templates_in_class.cpp<br>
<br>
Index: include/clang/Basic/DiagnosticSemaKinds.td<br>
===================================================================<br>
--- include/clang/Basic/DiagnosticSemaKinds.td<br>
+++ include/clang/Basic/DiagnosticSemaKinds.td<br>
@@ -3525,6 +3525,8 @@<br>
def warn_missing_variable_declarations : Warning<<br>
"no previous extern declaration for non-static variable %0">,<br>
InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;<br>
+def err_static_data_member_reinitialization :<br>
+ Error<"re-initialization of static data member %0">;<br>
def err_redefinition : Error<"redefinition of %0">;<br>
def err_alias_after_tentative :<br>
Error<"alias definition of %0 after tentative definition">;<br>
Index: lib/Sema/SemaDecl.cpp<br>
===================================================================<br>
--- lib/Sema/SemaDecl.cpp<br>
+++ lib/Sema/SemaDecl.cpp<br>
@@ -8184,9 +8184,8 @@<br>
// data members we also need to check whether there was an in-class<br>
// declaration with an initializer.<br>
if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) {<br>
- Diag(VDecl->getLocation(), diag::err_redefinition)<br>
- << VDecl->getDeclName();<br>
- Diag(PrevInit->getLocation(), diag::note_previous_definition);<br>
+ Diag(Init->getExprLoc(), diag::err_static_data_member_reinitialization) << VDecl->getDeclName();<br>
+ Diag(PrevInit->getInit()->getExprLoc(), diag::note_previous_initializer) << 0;<br>
return;<br>
}<br>
<br>
Index: test/CXX/class/class.static/class.static.data/p4.cpp<br>
===================================================================<br>
--- test/CXX/class/class.static/class.static.data/p4.cpp<br>
+++ test/CXX/class/class.static/class.static.data/p4.cpp<br>
@@ -10,15 +10,14 @@<br>
int const OutOfClassInitializerOnly::i = 0;<br>
<br>
struct InClassInitializerAndOutOfClassCopyInitializer {<br>
- static const int i = 0; // expected-note{{previous definition is here}}<br>
+ static const int i = 0; // expected-note{{previous initialization is here}}<br>
};<br>
-int const InClassInitializerAndOutOfClassCopyInitializer::i = 0; // expected-error{{redefinition of 'i'}}<br>
+int const InClassInitializerAndOutOfClassCopyInitializer::i = 0; // expected-error{{re-initialization of static data member 'i'}}<br>
<br>
struct InClassInitializerAndOutOfClassDirectInitializer {<br>
- static const int i = 0; // expected-note{{previous definition is here}}<br>
+ static const int i = 0; // expected-note{{previous initialization is here}}<br>
};<br>
-int const InClassInitializerAndOutOfClassDirectInitializer::i(0); // expected-error{{redefinition of 'i'}}<br>
-<br>
+int const InClassInitializerAndOutOfClassDirectInitializer::i(0); // expected-error{{re-initialization of static data member 'i'}}<br>
<br>
<br>
int main() { }<br>
Index: test/CXX/drs/dr0xx.cpp<br>
===================================================================<br>
--- test/CXX/drs/dr0xx.cpp<br>
+++ test/CXX/drs/dr0xx.cpp<br>
@@ -919,11 +919,10 @@<br>
<br>
namespace dr88 { // dr88: yes<br>
template<typename T> struct S {<br>
- static const int a = 1;<br>
+ static const int a = 1; // expected-note {{previous}}<br>
static const int b;<br>
};<br>
- // FIXME: This diagnostic is pretty bad.<br>
- template<> const int S<int>::a = 4; // expected-error {{redefinition}} expected-note {{previous}}<br>
+ template<> const int S<int>::a = 4; // expected-error {{re-initialization}}<br>
template<> const int S<int>::b = 4;<br>
}<br>
<br>
Index: test/SemaCXX/cxx1y-variable-templates_in_class.cpp<br>
===================================================================<br>
--- test/SemaCXX/cxx1y-variable-templates_in_class.cpp<br>
+++ test/SemaCXX/cxx1y-variable-templates_in_class.cpp<br>
@@ -39,11 +39,11 @@<br>
template<typename T> CONST T B1::right<T,int> = T(5);<br>
<br>
class B2 {<br>
- template<typename T, typename T0> static CONST T right = T(100); // expected-note {{previous definition is here}}<br>
- template<typename T> static CONST T right<T,int> = T(5); // expected-note {{previous definition is here}}<br>
+ template<typename T, typename T0> static CONST T right = T(100); // expected-note {{previous initialization is here}}<br>
+ template<typename T> static CONST T right<T,int> = T(5); // expected-note {{previous initialization is here}}<br>
};<br>
- template<typename T, typename T0> CONST T B2::right = T(100); // expected-error {{redefinition of 'right'}}<br>
- template<typename T> CONST T B2::right<T,int> = T(5); // expected-error {{redefinition of 'right'}}<br>
+ template<typename T, typename T0> CONST T B2::right = T(100); // expected-error {{re-initialization of static data member 'right'}}<br>
+ template<typename T> CONST T B2::right<T,int> = T(5); // expected-error {{re-initialization of static data member 'right'}}<br>
<br>
class B3 {<br>
template<typename T, typename T0> static CONST T right = T(100);<br>
</blockquote></div><br></div>