[cfe-commits] r139519 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/Modules/module-private.cpp

Douglas Gregor dgregor at apple.com
Mon Sep 12 11:37:39 PDT 2011


Author: dgregor
Date: Mon Sep 12 13:37:38 2011
New Revision: 139519

URL: http://llvm.org/viewvc/llvm-project?rev=139519&view=rev
Log:
Diagnose attempt to mark function-local declarations as __module_private__.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Modules/module-private.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=139519&r1=139518&r2=139519&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Sep 12 13:37:38 2011
@@ -4725,6 +4725,12 @@
 def err_module_private_specialization : Error<
   "%select{template|partial|member}0 specialization cannot be "
   "declared __module_private__">;
+def err_module_private_local : Error<
+  "%select{local variable|parameter|typedef}0 %1 cannot be declared "
+  "__module_private__">;
+def err_module_private_local_class : Error<
+  "local %select{struct|union|class|enum}0 cannot be declared "
+  "__module_private__">;
 }
 
 } // end of sema component.

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=139519&r1=139518&r2=139519&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Sep 12 13:37:38 2011
@@ -2373,6 +2373,12 @@
   if (DS.isExplicitSpecified())
     Diag(DS.getExplicitSpecLoc(), diag::warn_standalone_specifier) <<"explicit";
 
+  if (DS.isModulePrivateSpecified() && 
+      Tag && Tag->getDeclContext()->isFunctionOrMethod())
+    Diag(DS.getModulePrivateSpecLoc(), diag::err_module_private_local_class)
+      << Tag->getTagKind()
+      << FixItHint::CreateRemoval(DS.getModulePrivateSpecLoc());
+
   // FIXME: Warn on useless attributes
 
   return TagD;
@@ -3818,6 +3824,10 @@
     }
   }
 
+  // Set the lexical context. If the declarator has a C++ scope specifier, the
+  // lexical context will be different from the semantic context.
+  NewVD->setLexicalDeclContext(CurContext);
+
   if (D.getDeclSpec().isThreadSpecified()) {
     if (NewVD->hasLocalStorage())
       Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_thread_non_global);
@@ -3832,14 +3842,15 @@
       Diag(NewVD->getLocation(), diag::err_module_private_specialization)
         << 2
         << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc());
+    else if (NewVD->hasLocalStorage())
+      Diag(NewVD->getLocation(), diag::err_module_private_local)
+        << 0 << NewVD->getDeclName()
+        << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc())
+        << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc());
     else
       NewVD->setModulePrivate();
   }
 
-  // Set the lexical context. If the declarator has a C++ scope specifier, the
-  // lexical context will be different from the semantic context.
-  NewVD->setLexicalDeclContext(CurContext);
-
   // Handle attributes prior to checking for duplicates in MergeVarDecl
   ProcessDeclAttributes(S, NewVD, D);
 
@@ -6357,6 +6368,12 @@
 
   ProcessDeclAttributes(S, New, D);
 
+  if (D.getDeclSpec().isModulePrivateSpecified())
+    Diag(New->getLocation(), diag::err_module_private_local)
+      << 1 << New->getDeclName()
+      << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc())
+      << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc());
+
   if (New->hasAttr<BlocksAttr>()) {
     Diag(New->getLocation(), diag::err_block_on_nonlocal);
   }
@@ -7021,8 +7038,15 @@
     return NewTD;
   }
 
-  if (D.getDeclSpec().isModulePrivateSpecified())
-    NewTD->setModulePrivate();
+  if (D.getDeclSpec().isModulePrivateSpecified()) {
+    if (CurContext->isFunctionOrMethod())
+      Diag(NewTD->getLocation(), diag::err_module_private_local)
+        << 2 << NewTD->getDeclName()
+        << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc())
+        << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc());
+    else
+      NewTD->setModulePrivate();
+  }
   
   // C++ [dcl.typedef]p8:
   //   If the typedef declaration defines an unnamed class (or
@@ -7777,7 +7801,11 @@
         << FixItHint::CreateRemoval(ModulePrivateLoc);
     else if (PrevDecl && !PrevDecl->isModulePrivate())
       diagnoseModulePrivateRedeclaration(New, PrevDecl, ModulePrivateLoc);
-    else
+    // __module_private__ does not apply to local classes. However, we only
+    // diagnose this as an error when the declaration specifiers are
+    // freestanding. Here, we just ignore the __module_private__.
+    // foobar
+    else if (!SearchDC->isFunctionOrMethod())
       New->setModulePrivate();
   }
   

Modified: cfe/trunk/test/Modules/module-private.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/module-private.cpp?rev=139519&r1=139518&r2=139519&view=diff
==============================================================================
--- cfe/trunk/test/Modules/module-private.cpp (original)
+++ cfe/trunk/test/Modules/module-private.cpp Mon Sep 12 13:37:38 2011
@@ -119,4 +119,14 @@
 template<typename T>
 __module_private__ struct public_class<T *> { }; // expected-error{{partial specialization cannot be declared __module_private__}}
 
+// Check for attempts to make parameters and variables with automatic
+// storage module-private.
+
+void local_var_private(__module_private__ int param) { // expected-error{{parameter 'param' cannot be declared __module_private__}}
+  __module_private__ struct Local { int x, y; } local; //expected-error{{local variable 'local' cannot be declared __module_private__}}
+
+  __module_private__ struct OtherLocal { int x; }; // expected-error{{local struct cannot be declared __module_private__}}
+
+  typedef __module_private__ int local_typedef; // expected-error{{typedef 'local_typedef' cannot be declared __module_private__}}
+}
 #endif





More information about the cfe-commits mailing list