[PATCH] D18510: [cxx1z-constexpr-lambda] Make conversion function constexpr

Faisal Vali via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 5 19:32:50 PDT 2016


faisalv updated the summary for this revision.
faisalv updated this revision to Diff 62814.
faisalv added a comment.

Mark the lambda's conversion to function-pointer as incontrovertibly constexpr.

auto L = [](auto a) { return a; };
constexpr int* (*fp)(int*) = L; // This is now allowed.

Instead of inserting the extension/compatibility-warning into the same list that houses the notes that identify errors that occurred during constant-folding (and subsequently modifying the logic to ignore such warnings when determining the result of constant folding), I resorted to the simple approach used to emit a warning for integer-overflow (during constant folding) by invoking getDiagnostics().Report.

Richard I hope you're OK with this approach - I know in Oulu I was leaning towards inserting the warning into the same list that houses the error-notes (or potentially creating another one, or having EvalInfo track whether an error-note truly occurred instead of relying simply on the size of the list) - and while doable (and potentially cleaner) - that change is a larger one that requires handing some subtleties, and can be done at a later time, if you feel strongly about it.


http://reviews.llvm.org/D18510

Files:
  include/clang/Basic/DiagnosticASTKinds.td
  lib/AST/ExprConstant.cpp
  lib/Sema/SemaLambda.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
@@ -2,7 +2,9 @@
 // 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++1z -verify -fsyntax-only -fblocks -Wc++14-compat %s -DCHECK_COMPATIBILITY_WARNING
 
+#ifndef CHECK_COMPATIBILITY_WARNING
 namespace test_constexpr_checking {
 
 namespace ns1 {
@@ -33,4 +35,17 @@
       L(3); //expected-note{{non-constexpr function}}
 } 
 
-} // end ns test_constexpr_call
\ No newline at end of file
+} // end ns test_constexpr_call
+#endif
+
+#ifdef CHECK_COMPATIBILITY_WARNING
+//expected-warning at +6{{incompatible with C++ standards before C++1z}}
+//expected-warning at +6{{incompatible with C++ standards before C++1z}}
+#endif
+
+namespace ns4 {
+auto L = [](auto a) { return a; };
+constexpr int (*fp1)(int) = L;  
+constexpr int* (*fp2)(int*) = L; 
+
+} // end ns4
\ No newline at end of file
Index: lib/Sema/SemaLambda.cpp
===================================================================
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -1261,7 +1261,7 @@
                                 ConvTy, 
                                 ConvTSI,
                                 /*isInline=*/true, /*isExplicit=*/false,
-                                /*isConstexpr=*/false, 
+                                /*isConstexpr=*/true, 
                                 CallOperator->getBody()->getLocEnd());
   Conversion->setAccess(AS_public);
   Conversion->setImplicit(true);
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -4353,6 +4353,17 @@
         if (!EvaluateObjectArgument(Info, ME->getBase(), ThisVal))
           return false;
         Member = ME->getMemberDecl();
+        // If this is a non-capturing lambda's closure type's conversion
+        // operator that results in a pointer-to-function, remind users that the
+        // conversion operator itself was made 'constexpr' in C++1z.
+        if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(Member))
+          if (Conv->getParent()->isLambda()) {
+            Info.Ctx.getDiagnostics().Report(
+                E->getExprLoc(),
+                !Info.Ctx.getLangOpts().CPlusPlus1z
+                    ? diag::ext_constexpr_conversion_on_lambda_cxx1z
+                    : diag::warn_cxx14_compat_constexpr_conversion_on_lambda);
+          }
         This = &ThisVal;
         HasQualifier = ME->hasQualifier();
       } else if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
Index: include/clang/Basic/DiagnosticASTKinds.td
===================================================================
--- include/clang/Basic/DiagnosticASTKinds.td
+++ include/clang/Basic/DiagnosticASTKinds.td
@@ -162,8 +162,17 @@
 // implementation is complete, and like the preceding constexpr notes belongs
 // in Sema.
 def note_unimplemented_constexpr_lambda_feature_ast : Note<
-    "unimplemented constexpr lambda feature: %0 (coming soon!)">;
+  "unimplemented constexpr lambda feature: %0 (coming soon!)">;
 
+// C++1z constexpr lambda expressions
+def warn_cxx14_compat_constexpr_conversion_on_lambda : Warning<
+  "constexpr conversion to pointer-to-function on lambdas is "
+  "incompatible with C++ standards before C++1z">,
+  InGroup<CXXPre1zCompat>, DefaultIgnore;
+def ext_constexpr_conversion_on_lambda_cxx1z : ExtWarn<
+  "constexpr conversion to pointer-to-function on lambdas is "
+  "a C++1z extension">, InGroup<CXX1z>;
+
 // inline asm related.
 let CategoryName = "Inline Assembly Issue" in {
   def err_asm_invalid_escape : Error<


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18510.62814.patch
Type: text/x-patch
Size: 4025 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160706/4541ea7e/attachment.bin>


More information about the cfe-commits mailing list