[PATCH] D22662: [cxx1z-constexpr-lambda] Make a lambda's closure type a literal type in C++1z.

Faisal Vali via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 21 20:55:02 PDT 2016


faisalv updated this revision to Diff 65026.
faisalv added a comment.

Factor out the diagnostic builder RAII creation (through Sema.Diag) and reduce repetition.


https://reviews.llvm.org/D22662

Files:
  include/clang/AST/DeclCXX.h
  lib/Sema/SemaType.cpp
  test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Index: test/SemaCXX/cxx1z-constexpr-lambdas.cpp
===================================================================
--- test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s 
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s 
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s 
+// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER
 
+#ifndef CPP14_AND_EARLIER
 namespace test_constexpr_checking {
 
 namespace ns1 {
@@ -33,4 +33,16 @@
       L(3); //expected-note{{non-constexpr function}}
 } 
 
-} // end ns test_constexpr_call
\ No newline at end of file
+} // end ns test_constexpr_call
+
+#endif
+
+namespace test_lambda_is_literal {
+#ifdef CPP14_AND_EARLIER
+//expected-error at +4{{not a literal type}}
+//expected-note at +2{{not an aggregate and has no constexpr constructors}}
+#endif
+auto L = [] { };
+constexpr int foo(decltype(L) l) { return 0; }
+
+}
\ No newline at end of file
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -7165,7 +7165,15 @@
           << I.getSourceRange();
   } else if (!RD->isAggregate() && !RD->hasConstexprNonCopyMoveConstructor() &&
              !RD->hasTrivialDefaultConstructor()) {
-    Diag(RD->getLocation(), diag::note_non_literal_no_constexpr_ctors) << RD;
+    // If the class does not have a name (for e.g. a lambda's closure class) use
+    // its type which we should know how to pretty-print, otherwise use the
+    // class's name.
+    auto &&DiagBuilder =
+        Diag(RD->getLocation(), diag::note_non_literal_no_constexpr_ctors);
+    if (!RD->getIdentifier())
+      DiagBuilder << Context.getRecordType(RD);
+    else
+      DiagBuilder << RD;
   } else if (RD->hasNonLiteralTypeFieldsOrBases()) {
     for (const auto &I : RD->bases()) {
       if (!I.getType()->isLiteralType(Context)) {
Index: include/clang/AST/DeclCXX.h
===================================================================
--- include/clang/AST/DeclCXX.h
+++ include/clang/AST/DeclCXX.h
@@ -536,11 +536,10 @@
         MethodTyInfo(Info) {
       IsLambda = true;
 
-      // C++11 [expr.prim.lambda]p3:
-      //   This class type is neither an aggregate nor a literal type.
+      // C++1z [expr.prim.lambda]p4:
+      //   This class type is not an aggregate type.
       Aggregate = false;
       PlainOldData = false;
-      HasNonLiteralTypeFieldsOrBases = true;
     }
 
     /// \brief Whether this lambda is known to be dependent, even if its
@@ -1339,11 +1338,15 @@
   ///
   /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
   /// treating types with trivial default constructors as literal types.
+  ///
+  /// Only in C++1z and beyond, are lambdas literal types.
   bool isLiteral() const {
     return hasTrivialDestructor() &&
-           (isAggregate() || hasConstexprNonCopyMoveConstructor() ||
-            hasTrivialDefaultConstructor()) &&
-           !hasNonLiteralTypeFieldsOrBases();
+           (!isLambda() || getASTContext().getLangOpts().CPlusPlus1z) &&
+           !hasNonLiteralTypeFieldsOrBases() &&
+           (isAggregate() || isLambda() ||
+            hasConstexprNonCopyMoveConstructor() ||
+            hasTrivialDefaultConstructor());
   }
 
   /// \brief If this record is an instantiation of a member class,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D22662.65026.patch
Type: text/x-patch
Size: 3634 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160722/5a3cc929/attachment-0001.bin>


More information about the cfe-commits mailing list