cor3ntin updated this revision to Diff 355697.
cor3ntin added a comment.
Mark the feature as unreleased
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D105127/new/
https://reviews.llvm.org/D105127
Files:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaExprCXX.cpp
clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
clang/www/cxx_status.html
Index: clang/www/cxx_status.html
===================================================================
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1296,7 +1296,7 @@
<tr>
<td>Narrowing contextual conversions to bool</td>
<td><a href="https://wg21.link/P1401R5">P1401R5</a></td>
- <td class="none" align="center">No</td>
+ <td class="unreleased" align="center">Clang 13</td>
</tr>
<tr>
<td>Trimming whitespaces before line splicing</td>
Index: clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
===================================================================
--- clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
+++ clang/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -std=c++1z -verify %s
-// RUN: %clang_cc1 -std=c++1z -verify %s -DUNDEFINED
+// RUN: %clang_cc1 -std=c++1z -verify=expected,cxx17 %s
+// RUN: %clang_cc1 -std=c++1z -verify=expected,cxx17 %s -DUNDEFINED
+// RUN: %clang_cc1 -std=c++2b -verify=expected,cxx2b %s
+// RUN: %clang_cc1 -std=c++2b -verify=expected,cxx2b %s -DUNDEFINED
#ifdef UNDEFINED
// "used but not defined" errors don't get produced if we have more interesting
@@ -38,18 +40,43 @@
}
#else
namespace ccce {
+
+ struct S {
+ } s;
void f() {
if (5) {}
- if constexpr (5) {} // expected-error {{cannot be narrowed}}
+ if constexpr (5) { // cxx17-error {{cannot be narrowed}}
+ }
}
template<int N> void g() {
- if constexpr (N) {} // expected-error {{cannot be narrowed}}
+ if constexpr (N) { // cxx17-error {{cannot be narrowed}}
+ }
}
- template void g<5>(); // expected-note {{instantiation of}}
+ template void g<5>(); //cxx17-note {{instantiation of}}
void h() {
- if constexpr (4.3) {} // expected-error{{conversion from 'double' to 'bool' is not allowed in a converted constant expression}}
+ if constexpr (4.3) { // cxx17-error {{conversion from 'double' to 'bool' is not allowed in a converted constant expression}}
+ // cxx2b-warning@-1 {{implicit conversion from 'double' to 'bool' changes value}}
+ }
constexpr void *p = nullptr;
- if constexpr (p) {} // expected-error{{conversion from 'void *const' to 'bool' is not allowed in a converted constant expression}}
+ if constexpr (p) { // cxx17-error {{conversion from 'void *const' to 'bool' is not allowed in a converted constant expression}}
+ }
+ }
+
+ void not_constant(int b, S s) { // expected-note 2{{declared here}}
+ if constexpr (bool(b)) { // expected-error {{constexpr if condition is not a constant expression}} expected-note {{cannot be used in a constant expression}}
+ }
+ if constexpr (b) { // expected-error {{constexpr if condition is not a constant expression}} expected-note {{cannot be used in a constant expression}}
+ }
+ if constexpr (s) {
+ // cxx17-error@-1 {{value of type 'ccce::S' is not implicitly convertible to 'bool'}}
+ // cxx2b-error@-2 {{value of type 'ccce::S' is not contextually convertible to 'bool'}}
+ }
+
+ constexpr S constexprS;
+ if constexpr (constexprS) {
+ //cxx17-error@-1 {{value of type 'const ccce::S' is not implicitly convertible to 'bool'}}
+ //cxx2b-error@-2 {{value of type 'const ccce::S' is not contextually convertible to 'bool'}}
+ }
}
}
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -3911,7 +3911,7 @@
/// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.
ExprResult Sema::CheckCXXBooleanCondition(Expr *CondExpr, bool IsConstexpr) {
- // C++ 6.4p4:
+ // C++11 6.4p4:
// The value of a condition that is an initialized declaration in a statement
// other than a switch statement is the value of the declared variable
// implicitly converted to type bool. If that conversion is ill-formed, the
@@ -3919,12 +3919,27 @@
// The value of a condition that is an expression is the value of the
// expression, implicitly converted to bool.
//
+ // C++2b 8.5.2p2
+ // If the if statement is of the form if constexpr, the value of the condition
+ // is contextually converted to bool and the converted expression shall be
+ // a constant expression
+ //
// FIXME: Return this value to the caller so they don't need to recompute it.
- llvm::APSInt Value(/*BitWidth*/1);
- return (IsConstexpr && !CondExpr->isValueDependent())
- ? CheckConvertedConstantExpression(CondExpr, Context.BoolTy, Value,
- CCEK_ConstexprIf)
- : PerformContextuallyConvertToBool(CondExpr);
+
+ if (IsConstexpr && !LangOpts.CPlusPlus2b && !CondExpr->isValueDependent()) {
+ llvm::APSInt Value(/*BitWidth*/ 1);
+ return CheckConvertedConstantExpression(CondExpr, Context.BoolTy, Value,
+ CCEK_ConstexprIf);
+ }
+ ExprResult E = PerformContextuallyConvertToBool(CondExpr);
+ if (!IsConstexpr || !E.isUsable() || E.get()->isValueDependent())
+ return E;
+
+ llvm::APSInt Cond;
+ E = VerifyIntegerConstantExpression(
+ E.get(), &Cond,
+ diag::err_constexpr_if_condition_expression_is_not_constant);
+ return E;
}
/// Helper function to determine whether this is the (deprecated) C++
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1487,6 +1487,8 @@
// C++ declarations
def err_static_assert_expression_is_not_constant : Error<
"static_assert expression is not an integral constant expression">;
+def err_constexpr_if_condition_expression_is_not_constant : Error<
+ "constexpr if condition is not a constant expression convertible to bool">;
def err_static_assert_failed : Error<"static_assert failed%select{ %1|}0">;
def err_static_assert_requirement_failed : Error<
"static_assert failed due to requirement '%0'%select{ %2|}1">;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits