This revision was automatically updated to reflect the committed changes.
Closed by commit rL280838: Try contextually converting condition of constexpr 
if to Boolean value (authored by ismailp).

Changed prior to commit:
  https://reviews.llvm.org/D24158?vs=70561&id=70577#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D24158

Files:
  cfe/trunk/lib/Sema/SemaOverload.cpp
  cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
  cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp

Index: cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
===================================================================
--- cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
+++ cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
@@ -46,6 +46,11 @@
     if constexpr (N) {} // expected-error {{cannot be narrowed}}
   }
   template void g<5>(); // expected-note {{instantiation of}}
+  void h() {
+    if constexpr (4.3) {} // expected-error{{conversion from 'double' to 
'bool' is not allowed in a converted constant expression}}
+    constexpr void *p = nullptr;
+    if constexpr (p) {} // expected-error{{conversion from 'void *const' to 
'bool' is not allowed in a converted constant expression}}
+  }
 }
 
 namespace generic_lambda {
Index: cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp
===================================================================
--- cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp
+++ cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp
@@ -2,7 +2,15 @@
 
 void should_be_used_1();
 void should_be_used_2();
+void should_be_used_3();
 void should_not_be_used();
+
+struct A {
+  constexpr explicit operator bool() const {
+    return true;
+  }
+};
+
 void f() {
   if constexpr (false)
     should_not_be_used();
@@ -15,7 +23,12 @@
     goto foo;
 foo: should_not_be_used();
   }
+  if constexpr (A())
+    should_be_used_3();
+  else
+    should_not_be_used();
 }
 
 // CHECK: should_be_used_1
 // CHECK: should_be_used_2
+// CHECK: should_be_used_3
Index: cfe/trunk/lib/Sema/SemaOverload.cpp
===================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp
+++ cfe/trunk/lib/Sema/SemaOverload.cpp
@@ -5164,12 +5164,18 @@
   //  implicitly converted to type T, where the converted
   //  expression is a constant expression and the implicit conversion
   //  sequence contains only [... list of conversions ...].
+  // C++1z [stmt.if]p2:
+  //  If the if statement is of the form if constexpr, the value of the
+  //  condition shall be a contextually converted constant expression of type
+  //  bool.
   ImplicitConversionSequence ICS =
-    TryCopyInitialization(S, From, T,
-                          /*SuppressUserConversions=*/false,
-                          /*InOverloadResolution=*/false,
-                          /*AllowObjcWritebackConversion=*/false,
-                          /*AllowExplicit=*/false);
+      CCE == Sema::CCEK_ConstexprIf
+          ? TryContextuallyConvertToBool(S, From)
+          : TryCopyInitialization(S, From, T,
+                                  /*SuppressUserConversions=*/false,
+                                  /*InOverloadResolution=*/false,
+                                  /*AllowObjcWritebackConversion=*/false,
+                                  /*AllowExplicit=*/false);
   StandardConversionSequence *SCS = nullptr;
   switch (ICS.getKind()) {
   case ImplicitConversionSequence::StandardConversion:


Index: cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
===================================================================
--- cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
+++ cfe/trunk/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
@@ -46,6 +46,11 @@
     if constexpr (N) {} // expected-error {{cannot be narrowed}}
   }
   template void g<5>(); // expected-note {{instantiation of}}
+  void h() {
+    if constexpr (4.3) {} // expected-error{{conversion from 'double' to 'bool' is not allowed in a converted constant expression}}
+    constexpr void *p = nullptr;
+    if constexpr (p) {} // expected-error{{conversion from 'void *const' to 'bool' is not allowed in a converted constant expression}}
+  }
 }
 
 namespace generic_lambda {
Index: cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp
===================================================================
--- cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp
+++ cfe/trunk/test/CodeGenCXX/cxx1z-constexpr-if.cpp
@@ -2,7 +2,15 @@
 
 void should_be_used_1();
 void should_be_used_2();
+void should_be_used_3();
 void should_not_be_used();
+
+struct A {
+  constexpr explicit operator bool() const {
+    return true;
+  }
+};
+
 void f() {
   if constexpr (false)
     should_not_be_used();
@@ -15,7 +23,12 @@
     goto foo;
 foo: should_not_be_used();
   }
+  if constexpr (A())
+    should_be_used_3();
+  else
+    should_not_be_used();
 }
 
 // CHECK: should_be_used_1
 // CHECK: should_be_used_2
+// CHECK: should_be_used_3
Index: cfe/trunk/lib/Sema/SemaOverload.cpp
===================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp
+++ cfe/trunk/lib/Sema/SemaOverload.cpp
@@ -5164,12 +5164,18 @@
   //  implicitly converted to type T, where the converted
   //  expression is a constant expression and the implicit conversion
   //  sequence contains only [... list of conversions ...].
+  // C++1z [stmt.if]p2:
+  //  If the if statement is of the form if constexpr, the value of the
+  //  condition shall be a contextually converted constant expression of type
+  //  bool.
   ImplicitConversionSequence ICS =
-    TryCopyInitialization(S, From, T,
-                          /*SuppressUserConversions=*/false,
-                          /*InOverloadResolution=*/false,
-                          /*AllowObjcWritebackConversion=*/false,
-                          /*AllowExplicit=*/false);
+      CCE == Sema::CCEK_ConstexprIf
+          ? TryContextuallyConvertToBool(S, From)
+          : TryCopyInitialization(S, From, T,
+                                  /*SuppressUserConversions=*/false,
+                                  /*InOverloadResolution=*/false,
+                                  /*AllowObjcWritebackConversion=*/false,
+                                  /*AllowExplicit=*/false);
   StandardConversionSequence *SCS = nullptr;
   switch (ICS.getKind()) {
   case ImplicitConversionSequence::StandardConversion:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to