[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