[cfe-commits] r154073 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExprMember.cpp test/CXX/class/class.nest/p1.cpp test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp test/CXX/special/class.free/p1.cpp test/CXX/special/class.free/p6.cpp test/Parser/cxx-typeof.cpp test/SemaCXX/class.cpp test/SemaCXX/default2.cpp test/SemaCXX/qual-id-test.cpp test/SemaCXX/this.cpp

Richard Smith richard-llvm at metafoo.co.uk
Wed Apr 4 18:13:05 PDT 2012


Author: rsmith
Date: Wed Apr  4 20:13:04 2012
New Revision: 154073

URL: http://llvm.org/viewvc/llvm-project?rev=154073&view=rev
Log:
Improve diagnostics for invalid use of non-static members / this:

* s/nonstatic/non-static/ in the diagnostics, since the latter form outvoted
  the former by 28-2 in our diagnostics.
* Fix the "use of member in static member function" diagnostic to correctly
  detect this situation inside a block or lambda.
* Produce a more specific "invalid use of non-static member" diagnostic for
  the case where a nested class member refers to a member of a
  lexically-surrounding class.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExprMember.cpp
    cfe/trunk/test/CXX/class/class.nest/p1.cpp
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp
    cfe/trunk/test/CXX/special/class.free/p1.cpp
    cfe/trunk/test/CXX/special/class.free/p6.cpp
    cfe/trunk/test/Parser/cxx-typeof.cpp
    cfe/trunk/test/SemaCXX/class.cpp
    cfe/trunk/test/SemaCXX/default2.cpp
    cfe/trunk/test/SemaCXX/qual-id-test.cpp
    cfe/trunk/test/SemaCXX/this.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Apr  4 20:13:04 2012
@@ -3769,7 +3769,7 @@
   InGroup<DiagGroup<"null-arithmetic">>;
 
 def err_invalid_this_use : Error<
-  "invalid use of 'this' outside of a nonstatic member function">;
+  "invalid use of 'this' outside of a non-static member function">;
 def err_invalid_member_use_in_static_method : Error<
   "invalid use of member %0 in static member function">;
 def err_invalid_qualified_function_type : Error<
@@ -3785,7 +3785,10 @@
   "without a ref-qualifier|with ref-qualifier '&'|with ref-qualifier '&&'}1">;
 
 def err_invalid_non_static_member_use : Error<
-  "invalid use of nonstatic data member %0">;
+  "invalid use of non-static data member %0">;
+def err_nested_non_static_member_use : Error<
+  "%select{call to non-static member function|use of non-static data member}0 "
+  "%2 of %1 from nested type %3">;
 def warn_cxx98_compat_non_static_member_use : Warning<
   "use of non-static data member %0 in an unevaluated context is "
   "incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;

Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Wed Apr  4 20:13:04 2012
@@ -194,30 +194,38 @@
 }
 
 /// Diagnose a reference to a field with no object available.
-static void DiagnoseInstanceReference(Sema &SemaRef,
+static void diagnoseInstanceReference(Sema &SemaRef,
                                       const CXXScopeSpec &SS,
-                                      NamedDecl *rep,
+                                      NamedDecl *Rep,
                                       const DeclarationNameInfo &nameInfo) {
   SourceLocation Loc = nameInfo.getLoc();
   SourceRange Range(Loc);
   if (SS.isSet()) Range.setBegin(SS.getRange().getBegin());
-  
-  if (isa<FieldDecl>(rep) || isa<IndirectFieldDecl>(rep)) {
-    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(SemaRef.CurContext)) {
-      if (MD->isStatic()) {
-        // "invalid use of member 'x' in static member function"
-        SemaRef.Diag(Loc, diag::err_invalid_member_use_in_static_method)
-            << Range << nameInfo.getName();
-        return;
-      }
-    }
 
+  DeclContext *FunctionLevelDC = SemaRef.getFunctionLevelDeclContext();
+  CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FunctionLevelDC);
+  CXXRecordDecl *ContextClass = Method ? Method->getParent() : 0;
+  CXXRecordDecl *RepClass = dyn_cast<CXXRecordDecl>(Rep->getDeclContext());
+
+  bool InStaticMethod = Method && Method->isStatic();
+  bool IsField = isa<FieldDecl>(Rep) || isa<IndirectFieldDecl>(Rep);
+
+  if (IsField && InStaticMethod)
+    // "invalid use of member 'x' in static member function"
+    SemaRef.Diag(Loc, diag::err_invalid_member_use_in_static_method)
+        << Range << nameInfo.getName();
+  else if (ContextClass && RepClass && SS.isEmpty() && !InStaticMethod &&
+           !RepClass->Equals(ContextClass) && RepClass->Encloses(ContextClass))
+    // Unqualified lookup in a non-static member function found a member of an
+    // enclosing class.
+    SemaRef.Diag(Loc, diag::err_nested_non_static_member_use)
+      << IsField << RepClass << nameInfo.getName() << ContextClass << Range;
+  else if (IsField)
     SemaRef.Diag(Loc, diag::err_invalid_non_static_member_use)
-        << nameInfo.getName() << Range;
-    return;
-  }
-
-  SemaRef.Diag(Loc, diag::err_member_call_without_object) << Range;
+      << nameInfo.getName() << Range;
+  else
+    SemaRef.Diag(Loc, diag::err_member_call_without_object)
+      << Range;
 }
 
 /// Builds an expression which might be an implicit member expression.
@@ -248,7 +256,7 @@
 
   case IMA_Error_StaticContext:
   case IMA_Error_Unrelated:
-    DiagnoseInstanceReference(*this, SS, R.getRepresentativeDecl(),
+    diagnoseInstanceReference(*this, SS, R.getRepresentativeDecl(),
                               R.getLookupNameInfo());
     return ExprError();
   }
@@ -468,7 +476,7 @@
   // If this is an implicit member access, use a different set of
   // diagnostics.
   if (!BaseExpr)
-    return DiagnoseInstanceReference(SemaRef, SS, rep, nameInfo);
+    return diagnoseInstanceReference(SemaRef, SS, rep, nameInfo);
 
   SemaRef.Diag(nameInfo.getLoc(), diag::err_qualified_member_of_unrelated)
     << SS.getRange() << rep << BaseType;

Modified: cfe/trunk/test/CXX/class/class.nest/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.nest/p1.cpp?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.nest/p1.cpp (original)
+++ cfe/trunk/test/CXX/class/class.nest/p1.cpp Wed Apr  4 20:13:04 2012
@@ -5,9 +5,9 @@
   static int sx;
   int f();
 
-  // C++0x does relax this rule (see 5.1.1.10) in the first case, but we need to enforce it in C++03 mode.
+  // C++11 does relax this rule (see 5.1.1.10) in the first case, but we need to enforce it in C++03 mode.
   class Inner {
-    static char a[sizeof(x)]; // expected-error {{invalid use of nonstatic data member 'x'}}
+    static char a[sizeof(x)]; // expected-error {{invalid use of non-static data member 'x'}}
     static char b[sizeof(sx)]; // okay
     static char c[sizeof(f)]; // expected-error {{call to non-static member function without an object argument}}
   };

Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.general/p12-0x.cpp Wed Apr  4 20:13:04 2012
@@ -26,7 +26,7 @@
 }
 class Poly { virtual ~Poly(); };
 const std::type_info& k = typeid(S::m);
-const std::type_info& m = typeid(*(Poly*)S::m); // expected-error {{invalid use of nonstatic data member}}
+const std::type_info& m = typeid(*(Poly*)S::m); // expected-error {{invalid use of non-static data member}}
 const std::type_info& n = typeid(*(Poly*)(0*sizeof S::m)); 
 
 namespace PR11956 {

Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp Wed Apr  4 20:13:04 2012
@@ -2,9 +2,9 @@
 
 struct S {
   S *p = this; // ok
-  decltype(this) q; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+  decltype(this) q; // expected-error {{invalid use of 'this' outside of a non-static member function}}
 
-  int arr[sizeof(this)]; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+  int arr[sizeof(this)]; // expected-error {{invalid use of 'this' outside of a non-static member function}}
   int sz = sizeof(this); // ok
 };
 

Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp Wed Apr  4 20:13:04 2012
@@ -27,7 +27,7 @@
 
       static void static_bar() {
         (void)[this](){}; // expected-error{{'this' cannot be captured in this context}}
-        (void)[&](){i = 7; }; // expected-error{{invalid use of nonstatic data member 'i'}}
+        (void)[&](){i = 7; }; // expected-error{{invalid use of member 'i' in static member function}}
       }
     };
   }

Modified: cfe/trunk/test/CXX/special/class.free/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.free/p1.cpp?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/test/CXX/special/class.free/p1.cpp (original)
+++ cfe/trunk/test/CXX/special/class.free/p1.cpp Wed Apr  4 20:13:04 2012
@@ -3,9 +3,9 @@
 
 struct A {
   void *operator new(size_t) {
-    return this; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+    return this; // expected-error {{invalid use of 'this' outside of a non-static member function}}
   }
   void *operator new[](size_t) {
-    return this; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+    return this; // expected-error {{invalid use of 'this' outside of a non-static member function}}
   }
 };

Modified: cfe/trunk/test/CXX/special/class.free/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.free/p6.cpp?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/test/CXX/special/class.free/p6.cpp (original)
+++ cfe/trunk/test/CXX/special/class.free/p6.cpp Wed Apr  4 20:13:04 2012
@@ -3,9 +3,9 @@
 
 struct A {
   void operator delete(void*) {
-    (void)this; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+    (void)this; // expected-error {{invalid use of 'this' outside of a non-static member function}}
   }
   void operator delete[](void*) {
-    (void)this; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+    (void)this; // expected-error {{invalid use of 'this' outside of a non-static member function}}
   }
 };

Modified: cfe/trunk/test/Parser/cxx-typeof.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-typeof.cpp?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-typeof.cpp (original)
+++ cfe/trunk/test/Parser/cxx-typeof.cpp Wed Apr  4 20:13:04 2012
@@ -9,5 +9,5 @@
 // Part of rdar://problem/8347416;  from the gcc test suite.
 struct S {
   int i;
-  __typeof(S::i) foo(); // expected-error {{invalid use of nonstatic data member 'i'}}
+  __typeof(S::i) foo(); // expected-error {{invalid use of non-static data member 'i'}}
 };

Modified: cfe/trunk/test/SemaCXX/class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class.cpp?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/class.cpp (original)
+++ cfe/trunk/test/SemaCXX/class.cpp Wed Apr  4 20:13:04 2012
@@ -7,16 +7,18 @@
 
   static void sm() {
     sx = 0;
-    this->x = 0; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+    this->x = 0; // expected-error {{invalid use of 'this' outside of a non-static member function}}
     x = 0; // expected-error {{invalid use of member 'x' in static member function}}
   }
 
   class NestedC {
   public:
     NestedC(int);
-    void m() {
+    void f() {
       sx = 0;
-      x = 0; // expected-error {{invalid use of nonstatic data member 'x'}}
+      x = 0; // expected-error {{use of non-static data member 'x' of 'C' from nested type 'NestedC'}}
+      sm();
+      m(); // expected-error {{call to non-static member function 'm' of 'C' from nested type 'NestedC'}}
     }
   };
 
@@ -186,7 +188,7 @@
 };
 
 void f() {
-    S::c; // expected-error {{invalid use of nonstatic data member}}
+    S::c; // expected-error {{invalid use of non-static data member}}
 }
 }
 

Modified: cfe/trunk/test/SemaCXX/default2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/default2.cpp?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/default2.cpp (original)
+++ cfe/trunk/test/SemaCXX/default2.cpp Wed Apr  4 20:13:04 2012
@@ -28,7 +28,7 @@
 void g2(int x, int y, int z = x + y); // expected-error {{default argument references parameter 'x'}} expected-error {{default argument references parameter 'y'}}
 
 class X {
-  void f(X* x = this); // expected-error{{invalid use of 'this' outside of a nonstatic member function}}
+  void f(X* x = this); // expected-error{{invalid use of 'this' outside of a non-static member function}}
 
   void g() { 
     int f(X* x = this); // expected-error{{default argument references 'this'}}
@@ -55,7 +55,7 @@
 // C++ [dcl.fct.default]p9
 struct Y { 
   int a; 
-  int mem1(int i = a); // expected-error{{invalid use of nonstatic data member 'a'}}
+  int mem1(int i = a); // expected-error{{invalid use of non-static data member 'a'}}
   int mem2(int i = b); // OK; use Y::b 
   int mem3(int i);
   int mem4(int i);
@@ -64,8 +64,8 @@
     int mem5(int i = b, // OK; use Y::b
              int j = c, // OK; use Y::Nested::c
              int k = j, // expected-error{{default argument references parameter 'j'}}
-             int l = a,  // expected-error{{invalid use of nonstatic data member 'a'}}
-             Nested* self = this, // expected-error{{invalid use of 'this' outside of a nonstatic member function}}
+             int l = a,  // expected-error{{invalid use of non-static data member 'a'}}
+             Nested* self = this, // expected-error{{invalid use of 'this' outside of a non-static member function}}
              int m); // expected-error{{missing default argument on parameter 'm'}}
     static int c;
     Nested(int i = 42);
@@ -78,7 +78,7 @@
 
 int Y::mem3(int i = b) { return i; } // OK; use X::b
 
-int Y::mem4(int i = a) // expected-error{{invalid use of nonstatic data member 'a'}}
+int Y::mem4(int i = a) // expected-error{{invalid use of non-static data member 'a'}}
 { return i; }
 
 

Modified: cfe/trunk/test/SemaCXX/qual-id-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/qual-id-test.cpp?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/qual-id-test.cpp (original)
+++ cfe/trunk/test/SemaCXX/qual-id-test.cpp Wed Apr  4 20:13:04 2012
@@ -137,7 +137,7 @@
 
 a a;
 
-int a::sa = a.a; // expected-error {{invalid use of nonstatic data member 'a'}}
+int a::sa = a.a; // expected-error {{invalid use of non-static data member 'a'}}
 
 
 namespace PR6645 {

Modified: cfe/trunk/test/SemaCXX/this.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/this.cpp?rev=154073&r1=154072&r2=154073&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/this.cpp (original)
+++ cfe/trunk/test/SemaCXX/this.cpp Wed Apr  4 20:13:04 2012
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s 
-int x = this; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+int x = this; // expected-error {{invalid use of 'this' outside of a non-static member function}}
 
 void f() {
-  int x = this; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
+  int x = this; // expected-error {{invalid use of 'this' outside of a non-static member function}}
 }





More information about the cfe-commits mailing list