[cfe-commits] r162229 - in /cfe/trunk: lib/Parse/ParseDecl.cpp test/SemaCXX/warn-thread-safety-parsing.cpp

DeLesley Hutchins delesley at google.com
Mon Aug 20 14:32:18 PDT 2012


Author: delesley
Date: Mon Aug 20 16:32:18 2012
New Revision: 162229

URL: http://llvm.org/viewvc/llvm-project?rev=162229&view=rev
Log:
Thread-safety analysis: fix scoping issues related to 'this', including an
ICE in friend functions.

Modified:
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=162229&r1=162228&r2=162229&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Aug 20 16:32:18 2012
@@ -851,10 +851,6 @@
     Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
                                                 Class.TagOrTemplate);
   if (!Class.LateParsedDeclarations.empty()) {
-    // Allow 'this' within late-parsed attributes.
-    Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,
-                                     /*TypeQuals=*/0);
-
     for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
       Class.LateParsedDeclarations[i]->ParseLexedAttributes();
     }
@@ -904,34 +900,43 @@
   ParsedAttributes Attrs(AttrFactory);
   SourceLocation endLoc;
 
-  if (LA.Decls.size() == 1) {
+  if (LA.Decls.size() > 0) {
     Decl *D = LA.Decls[0];
+    NamedDecl *ND  = dyn_cast<NamedDecl>(D);
+    RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
 
-    // If the Decl is templatized, add template parameters to scope.
-    bool HasTemplateScope = EnterScope && D->isTemplateDecl();
-    ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
-    if (HasTemplateScope)
-      Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
-
-    // If the Decl is on a function, add function parameters to the scope.
-    bool HasFunctionScope = EnterScope && D->isFunctionOrFunctionTemplate();
-    ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunctionScope);
-    if (HasFunctionScope)
-      Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
-
-    ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
-
-    if (HasFunctionScope) {
-      Actions.ActOnExitFunctionContext();
-      FnScope.Exit();  // Pop scope, and remove Decls from IdResolver
-    }
-    if (HasTemplateScope) {
-      TempScope.Exit();
-    }
-  } else if (LA.Decls.size() > 0) {
-    // If there are multiple decls, then the decl cannot be within the
-    // function scope.
-    ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
+    // Allow 'this' within late-parsed attributes.
+    Sema::CXXThisScopeRAII ThisScope(Actions, RD,
+                                     /*TypeQuals=*/0,
+                                     ND && RD && ND->isCXXInstanceMember());
+
+    if (LA.Decls.size() == 1) {
+      // If the Decl is templatized, add template parameters to scope.
+      bool HasTemplateScope = EnterScope && D->isTemplateDecl();
+      ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
+      if (HasTemplateScope)
+        Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
+
+      // If the Decl is on a function, add function parameters to the scope.
+      bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate();
+      ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunScope);
+      if (HasFunScope)
+        Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
+
+      ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
+
+      if (HasFunScope) {
+        Actions.ActOnExitFunctionContext();
+        FnScope.Exit();  // Pop scope, and remove Decls from IdResolver
+      }
+      if (HasTemplateScope) {
+        TempScope.Exit();
+      }
+    } else {
+      // If there are multiple decls, then the decl cannot be within the
+      // function scope.
+      ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
+    }
   } else {
     Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
   }

Modified: cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp?rev=162229&r1=162228&r2=162229&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp Mon Aug 20 16:32:18 2012
@@ -1255,7 +1255,7 @@
   void foo4(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu);
 
   static void foo5()    EXCLUSIVE_LOCKS_REQUIRED(mu); // \
-    // expected-error {{'this' cannot be implicitly used in a static member function declaration}}
+    // expected-error {{invalid use of member 'mu' in static member function}}
 
   template <class T>
   void foo6() EXCLUSIVE_LOCKS_REQUIRED(T::statmu) { }
@@ -1440,3 +1440,28 @@
 
 } // end namespace InvalidDeclTest
 
+
+namespace StaticScopeTest {
+
+class FooStream;
+
+class Foo {
+  mutable Mutex mu;
+  int a GUARDED_BY(mu);
+
+  static int si GUARDED_BY(mu); // \
+    // expected-error {{invalid use of non-static data member 'mu'}}
+
+  static void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \
+    // expected-error {{invalid use of member 'mu' in static member function}}
+
+  friend FooStream& operator<<(FooStream& s, const Foo& f)
+    EXCLUSIVE_LOCKS_REQUIRED(mu); // \
+    // expected-error {{invalid use of non-static data member 'mu'}}
+};
+
+
+} // end namespace StaticScopeTest
+
+
+





More information about the cfe-commits mailing list