<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>