r278648 - Disable lambda-capture of decomposition declaration bindings for now, until CWG

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Sun Aug 14 19:34:24 PDT 2016


Author: rsmith
Date: Sun Aug 14 21:34:23 2016
New Revision: 278648

URL: http://llvm.org/viewvc/llvm-project?rev=278648&view=rev
Log:
Disable lambda-capture of decomposition declaration bindings for now, until CWG
agrees on how they're supposed to work.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=278648&r1=278647&r2=278648&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Aug 14 21:34:23 2016
@@ -7046,14 +7046,9 @@ def ext_ms_anonymous_record : ExtWarn<
   InGroup<MicrosoftAnonTag>;
 
 // C++ local classes
-def err_reference_to_local_var_in_enclosing_function : Error<
-  "reference to local variable %0 declared in enclosing function %1">;
-def err_reference_to_local_var_in_enclosing_block : Error<
-  "reference to local variable %0 declared in enclosing block literal">;
-def err_reference_to_local_var_in_enclosing_lambda : Error<
-  "reference to local variable %0 declared in enclosing lambda expression">;
-def err_reference_to_local_var_in_enclosing_context : Error<
-  "reference to local variable %0 declared in enclosing context">;
+def err_reference_to_local_in_enclosing_context : Error<
+  "reference to local %select{variable|binding}1 %0 declared in enclosing "
+  "%select{%3|block literal|lambda expression|context}2">;
 
 def err_static_data_member_not_allowed_in_local_class : Error<
   "static data member %0 not allowed in local class %1">; 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=278648&r1=278647&r2=278648&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Aug 14 21:34:23 2016
@@ -2838,6 +2838,10 @@ ExprResult Sema::BuildDeclarationNameExp
   return ULE;
 }
 
+static void
+diagnoseUncapturableValueReference(Sema &S, SourceLocation loc,
+                                   ValueDecl *var, DeclContext *DC);
+
 /// \brief Complete semantic analysis for a reference to the given declaration.
 ExprResult Sema::BuildDeclarationNameExpr(
     const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D,
@@ -2981,7 +2985,12 @@ ExprResult Sema::BuildDeclarationNameExp
       // These are always lvalues.
       valueKind = VK_LValue;
       type = type.getNonReferenceType();
-      // FIXME: Adjust cv-qualifiers for capture.
+      // FIXME: Support lambda-capture of BindingDecls, once CWG actually
+      // decides how that's supposed to work.
+      auto *BD = cast<BindingDecl>(VD);
+      if (BD->getDeclContext()->isFunctionOrMethod() &&
+          BD->getDeclContext() != CurContext)
+        diagnoseUncapturableValueReference(*this, Loc, BD, CurContext);
       break;
     }
         
@@ -13214,7 +13223,7 @@ void Sema::MarkFunctionReferenced(Source
 
 static void
 diagnoseUncapturableValueReference(Sema &S, SourceLocation loc,
-                                   VarDecl *var, DeclContext *DC) {
+                                   ValueDecl *var, DeclContext *DC) {
   DeclContext *VarDC = var->getDeclContext();
 
   //  If the parameter still belongs to the translation unit, then
@@ -13234,25 +13243,21 @@ diagnoseUncapturableValueReference(Sema
   if (!S.getLangOpts().CPlusPlus && !S.CurContext->isFunctionOrMethod())
     return;
 
+  unsigned ValueKind = isa<BindingDecl>(var) ? 1 : 0;
+  unsigned ContextKind = 3; // unknown
   if (isa<CXXMethodDecl>(VarDC) &&
       cast<CXXRecordDecl>(VarDC->getParent())->isLambda()) {
-    S.Diag(loc, diag::err_reference_to_local_var_in_enclosing_lambda)
-      << var->getIdentifier();
-  } else if (FunctionDecl *fn = dyn_cast<FunctionDecl>(VarDC)) {
-    S.Diag(loc, diag::err_reference_to_local_var_in_enclosing_function)
-      << var->getIdentifier() << fn->getDeclName();
+    ContextKind = 2;
+  } else if (isa<FunctionDecl>(VarDC)) {
+    ContextKind = 0;
   } else if (isa<BlockDecl>(VarDC)) {
-    S.Diag(loc, diag::err_reference_to_local_var_in_enclosing_block)
-      << var->getIdentifier();
-  } else {
-    // FIXME: Is there any other context where a local variable can be
-    // declared?
-    S.Diag(loc, diag::err_reference_to_local_var_in_enclosing_context)
-      << var->getIdentifier();
+    ContextKind = 1;
   }
 
+  S.Diag(loc, diag::err_reference_to_local_in_enclosing_context)
+    << var << ValueKind << ContextKind << VarDC;
   S.Diag(var->getLocation(), diag::note_entity_declared_at)
-      << var->getIdentifier();
+      << var;
 
   // FIXME: Add additional diagnostic info about class etc. which prevents
   // capture.

Modified: cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp?rev=278648&r1=278647&r2=278648&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1z-decomposition.cpp Sun Aug 14 21:34:23 2016
@@ -37,4 +37,14 @@ constexpr bool g(S &&s) {
 }
 static_assert(g({1, 2}));
 
+void enclosing() {
+  struct S { int a; };
+  auto [n] = S(); // expected-note 2{{'n' declared here}}
+
+  struct Q { int f() { return n; } }; // expected-error {{reference to local binding 'n' declared in enclosing function}}
+  // FIXME: This is probably supposed to be valid, but we do not have clear rules on how it's supposed to work.
+  (void) [&] { return n; }; // expected-error {{reference to local binding 'n' declared in enclosing function}}
+  (void) [n] {}; // expected-error {{'n' in capture list does not name a variable}}
+}
+
 // FIXME: by-value array copies




More information about the cfe-commits mailing list