]> granicus.if.org Git - clang/commitdiff
Provide better diagnostic wording for initializers on static
authorHans Wennborg <hans@hanshq.net>
Thu, 21 Nov 2013 03:17:44 +0000 (03:17 +0000)
committerHans Wennborg <hans@hanshq.net>
Thu, 21 Nov 2013 03:17:44 +0000 (03:17 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195306 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/CXX/class/class.static/class.static.data/p4.cpp
test/CXX/drs/dr0xx.cpp
test/SemaCXX/cxx1y-variable-templates_in_class.cpp

index 5963ec4e0fb983cc84ac52576de4f50c7cd4b94c..b84293c6794b12590d2390ade398ff390ee384a2 100644 (file)
@@ -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">;
index cd643118ee968fdba6c8529a54304acf6675a1e4..6d5e0f01268d6d88bc54916be0309869d2114946 100644 (file)
@@ -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;
     }  
 
index 2b1eca7419374d59069da8bfd7ff8b64eb1404ad..85d18c6b5fac23d5bb29c27affd6ac1b3b941524 100644 (file)
@@ -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() { }
index 265a52d9261aa4c9feee309c9f18f2cff7492c00..57e3a754c54cc65a41de7be45cfc92f8b49504fe 100644 (file)
@@ -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;
 }
 
index 94d0f16f06ede436031ab262b6e6ab33bd5d44d8..1e959364280384c0e1107b1c4b6507f8adcc3ec2 100644 (file)
@@ -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);