<div dir="ltr"><div>I don't see how the resolution of Core Issue 2140 changes the status of nullptr_t lvalue-to-rvalue conversion for constexpr evaluation. PR42440 has been opened concerning the change to constexpr evaluation.</div><div><br></div><div>-- HT<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jun 14, 2019 at 1:43 PM Richard Smith via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: rsmith<br>
Date: Fri Jun 14 10:46:38 2019<br>
New Revision: 363429<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=363429&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=363429&view=rev</a><br>
Log:<br>
PR23833, DR2140: an lvalue-to-rvalue conversion on a glvalue of type<br>
nullptr_t does not access memory.<br>
<br>
We now reuse CK_NullToPointer to represent a conversion from a glvalue<br>
of type nullptr_t to a prvalue of nullptr_t where necessary.<br>
<br>
This reinstates r363337, reverted in r363352.<br>
<br>
Modified:<br>
    cfe/trunk/lib/AST/Expr.cpp<br>
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp<br>
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.cpp<br>
    cfe/trunk/lib/Sema/SemaInit.cpp<br>
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp<br>
    cfe/trunk/test/Analysis/nullptr.cpp<br>
    cfe/trunk/test/CXX/drs/dr21xx.cpp<br>
    cfe/trunk/test/CodeGenCXX/nullptr.cpp<br>
    cfe/trunk/www/cxx_dr_status.html<br>
<br>
Modified: cfe/trunk/lib/AST/Expr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=363429&r1=363428&r2=363429&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=363429&r1=363428&r2=363429&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/Expr.cpp (original)<br>
+++ cfe/trunk/lib/AST/Expr.cpp Fri Jun 14 10:46:38 2019<br>
@@ -1885,6 +1885,11 @@ ImplicitCastExpr *ImplicitCastExpr::Crea<br>
                                            ExprValueKind VK) {<br>
   unsigned PathSize = (BasePath ? BasePath->size() : 0);<br>
   void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));<br>
+  // Per C++ [conv.lval]p3, lvalue-to-rvalue conversions on class and<br>
+  // std::nullptr_t have special semantics not captured by CK_LValueToRValue.<br>
+  assert((Kind != CK_LValueToRValue ||<br>
+          !(T->isNullPtrType() || T->getAsCXXRecordDecl())) &&<br>
+         "invalid type for lvalue-to-rvalue conversion");<br>
   ImplicitCastExpr *E =<br>
     new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, VK);<br>
   if (PathSize)<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=363429&r1=363428&r2=363429&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=363429&r1=363428&r2=363429&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Fri Jun 14 10:46:38 2019<br>
@@ -1352,7 +1352,8 @@ static bool isSimpleZero(const Expr *E,<br>
   // (int*)0 - Null pointer expressions.<br>
   if (const CastExpr *ICE = dyn_cast<CastExpr>(E))<br>
     return ICE->getCastKind() == CK_NullToPointer &&<br>
-        CGF.getTypes().isPointerZeroInitializable(E->getType());<br>
+           CGF.getTypes().isPointerZeroInitializable(E->getType()) &&<br>
+           !E->HasSideEffects(CGF.getContext());<br>
   // '\0'<br>
   if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E))<br>
     return CL->getValue() == 0;<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=363429&r1=363428&r2=363429&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=363429&r1=363428&r2=363429&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Fri Jun 14 10:46:38 2019<br>
@@ -2148,14 +2148,14 @@ Value *ScalarExprEmitter::VisitCastExpr(<br>
<br>
   case CK_NullToPointer:<br>
     if (MustVisitNullValue(E))<br>
-      (void) Visit(E);<br>
+      CGF.EmitIgnoredExpr(E);<br>
<br>
     return CGF.CGM.getNullPointer(cast<llvm::PointerType>(ConvertType(DestTy)),<br>
                               DestTy);<br>
<br>
   case CK_NullToMemberPointer: {<br>
     if (MustVisitNullValue(E))<br>
-      (void) Visit(E);<br>
+      CGF.EmitIgnoredExpr(E);<br>
<br>
     const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>();<br>
     return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT);<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=363429&r1=363428&r2=363429&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=363429&r1=363428&r2=363429&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jun 14 10:46:38 2019<br>
@@ -635,8 +635,10 @@ ExprResult Sema::DefaultLvalueConversion<br>
   if (E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)<br>
     Cleanup.setExprNeedsCleanups(true);<br>
<br>
-  Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E, nullptr,<br>
-                                 VK_RValue);<br>
+  // C++ [conv.lval]p3:<br>
+  //   If T is cv std::nullptr_t, the result is a null pointer constant.<br>
+  CastKind CK = T->isNullPtrType() ? CK_NullToPointer : CK_LValueToRValue;<br>
+  Res = ImplicitCastExpr::Create(Context, T, CK, E, nullptr, VK_RValue);<br>
<br>
   // C11 6.3.2.1p2:<br>
   //   ... if the lvalue has atomic type, the value has the non-atomic version<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaInit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=363429&r1=363428&r2=363429&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=363429&r1=363428&r2=363429&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Jun 14 10:46:38 2019<br>
@@ -7779,9 +7779,13 @@ ExprResult InitializationSequence::Perfo<br>
<br>
     case SK_LValueToRValue: {<br>
       assert(CurInit.get()->isGLValue() && "cannot load from a prvalue");<br>
-      CurInit = ImplicitCastExpr::Create(S.Context, Step->Type,<br>
-                                         CK_LValueToRValue, CurInit.get(),<br>
-                                         /*BasePath=*/nullptr, VK_RValue);<br>
+      // C++ [conv.lval]p3:<br>
+      //   If T is cv std::nullptr_t, the result is a null pointer constant.<br>
+      CastKind CK =<br>
+          Step->Type->isNullPtrType() ? CK_NullToPointer : CK_LValueToRValue;<br>
+      CurInit =<br>
+          ImplicitCastExpr::Create(S.Context, Step->Type, CK, CurInit.get(),<br>
+                                   /*BasePath=*/nullptr, VK_RValue);<br>
       break;<br>
     }<br>
<br>
<br>
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=363429&r1=363428&r2=363429&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=363429&r1=363428&r2=363429&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original)<br>
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Fri Jun 14 10:46:38 2019<br>
@@ -378,7 +378,6 @@ void ExprEngine::VisitCast(const CastExp<br>
       case CK_BitCast:<br>
       case CK_AddressSpaceConversion:<br>
       case CK_BooleanToSignedIntegral:<br>
-      case CK_NullToPointer:<br>
       case CK_IntegralToPointer:<br>
       case CK_PointerToIntegral: {<br>
         SVal V = state->getSVal(Ex, LCtx);<br>
@@ -503,6 +502,12 @@ void ExprEngine::VisitCast(const CastExp<br>
         Bldr.generateNode(CastE, Pred, state);<br>
         continue;<br>
       }<br>
+      case CK_NullToPointer: {<br>
+        SVal V = svalBuilder.makeNull();<br>
+        state = state->BindExpr(CastE, LCtx, V);<br>
+        Bldr.generateNode(CastE, Pred, state);<br>
+        continue;<br>
+      }<br>
       case CK_NullToMemberPointer: {<br>
         SVal V = svalBuilder.getMemberPointer(nullptr);<br>
         state = state->BindExpr(CastE, LCtx, V);<br>
<br>
Modified: cfe/trunk/test/Analysis/nullptr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/nullptr.cpp?rev=363429&r1=363428&r2=363429&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/nullptr.cpp?rev=363429&r1=363428&r2=363429&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Analysis/nullptr.cpp (original)<br>
+++ cfe/trunk/test/Analysis/nullptr.cpp Fri Jun 14 10:46:38 2019<br>
@@ -128,18 +128,10 @@ void shouldNotCrash() {<br>
   decltype(nullptr) p; // expected-note{{'p' declared without an initial value}}<br>
   if (getSymbol()) // expected-note   {{Assuming the condition is false}}<br>
                    // expected-note@-1{{Taking false branch}}<br>
-                   // expected-note@-2{{Assuming the condition is false}}<br>
-                   // expected-note@-3{{Taking false branch}}<br>
-                   // expected-note@-4{{Assuming the condition is true}}<br>
-                   // expected-note@-5{{Taking true branch}}<br>
-    invokeF(p); // expected-warning{{1st function call argument is an uninitialized value}}<br>
-                // expected-note@-1{{1st function call argument is an uninitialized value}}<br>
-  if (getSymbol()) // expected-note   {{Assuming the condition is false}}<br>
-                   // expected-note@-1{{Taking false branch}}<br>
                    // expected-note@-2{{Assuming the condition is true}}<br>
                    // expected-note@-3{{Taking true branch}}<br>
-    invokeF(nullptr); // expected-note   {{Calling 'invokeF'}}<br>
-                      // expected-note@-1{{Passing null pointer value via 1st parameter 'x'}}<br>
+    invokeF(p);    // expected-note   {{Calling 'invokeF'}}<br>
+                   // expected-note@-1{{Passing null pointer value via 1st parameter 'x'}}<br>
   if (getSymbol()) {  // expected-note  {{Assuming the condition is true}}<br>
                       // expected-note@-1{{Taking true branch}}<br>
     X *xx = Type().x; // expected-note   {{Null pointer value stored to field 'x'}}<br>
<br>
Modified: cfe/trunk/test/CXX/drs/dr21xx.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr21xx.cpp?rev=363429&r1=363428&r2=363429&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr21xx.cpp?rev=363429&r1=363428&r2=363429&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CXX/drs/dr21xx.cpp (original)<br>
+++ cfe/trunk/test/CXX/drs/dr21xx.cpp Fri Jun 14 10:46:38 2019<br>
@@ -32,6 +32,16 @@ namespace dr2120 { // dr2120: 7<br>
   static_assert(!__is_standard_layout(E), "");<br>
 }<br>
<br>
+namespace dr2140 { // dr2140: 9<br>
+#if __cplusplus >= 201103L<br>
+  union U { int a; decltype(nullptr) b; };<br>
+  constexpr int *test(U u) {<br>
+    return u.b;<br>
+  }<br>
+  static_assert(!test({123}), "u.b should be valid even when b is inactive");<br>
+#endif<br>
+}<br>
+<br>
 namespace dr2170 { // dr2170: 9<br>
 #if __cplusplus >= 201103L<br>
   void f() {<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/nullptr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/nullptr.cpp?rev=363429&r1=363428&r2=363429&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/nullptr.cpp?rev=363429&r1=363428&r2=363429&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/nullptr.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/nullptr.cpp Fri Jun 14 10:46:38 2019<br>
@@ -22,3 +22,50 @@ void g() {<br>
 const std::type_info& f2() {<br>
   return typeid(nullptr_t);<br>
 }<br>
+<br>
+union U {<br>
+  int n;<br>
+  nullptr_t b;<br>
+};<br>
+// CHECK-LABEL: define {{.*}}pr23833_a<br>
+// CHECK: store<br>
+// CHECK: load<br>
+// CHECK-NOT: load<br>
+// CHECK: ret i1 false<br>
+bool pr23833_a(U &u) { return u.b; }<br>
+<br>
+// CHECK-LABEL: define {{.*}}pr23833_b<br>
+// CHECK: store<br>
+// CHECK: load<br>
+// CHECK-NOT: load<br>
+// CHECK: ret i8* null<br>
+nullptr_t pr23833_b(nullptr_t &n) { return n; }<br>
+<br>
+struct X1 { operator int*(); };<br>
+struct X2 { operator const nullptr_t&(); };<br>
+<br>
+// CHECK-LABEL: define {{.*}}pr23833_c<br>
+// CHECK: call {{.*}}X1<br>
+// CHECK: call {{.*}}X2<br>
+// CHECK-NOT: load<br>
+// CHECK: ret i32<br>
+int pr23833_c() {<br>
+  return X1() != X2();<br>
+}<br>
+<br>
+// CHECK-LABEL: define {{.*}}pr23833_d<br>
+// CHECK: call {{.*}}X2<br>
+// CHECK-NOT: load<br>
+// CHECK: store<br>
+// CHECK: load<br>
+// CHECK: ret i32*<br>
+int *pr23833_d() {<br>
+  int *p = X2();<br>
+  return p;<br>
+}<br>
+<br>
+namespace PR39528 {<br>
+  constexpr nullptr_t null = nullptr;<br>
+  void f(nullptr_t);<br>
+  void g() { f(null); }<br>
+}<br>
<br>
Modified: cfe/trunk/www/cxx_dr_status.html<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=363429&r1=363428&r2=363429&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=363429&r1=363428&r2=363429&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/www/cxx_dr_status.html (original)<br>
+++ cfe/trunk/www/cxx_dr_status.html Fri Jun 14 10:46:38 2019<br>
@@ -12655,7 +12655,7 @@ and <I>POD class</I></td><br>
     <td><a href="<a href="http://wg21.link/cwg2140" rel="noreferrer" target="_blank">http://wg21.link/cwg2140</a>">2140</a></td><br>
     <td>CD4</td><br>
     <td>Lvalue-to-rvalue conversion of <TT>std::nullptr_t</TT></td><br>
-    <td class="none" align="center">Unknown</td><br>
+    <td class="svn" align="center">SVN</td><br>
   </tr><br>
   <tr id="2141"><br>
     <td><a href="<a href="http://wg21.link/cwg2141" rel="noreferrer" target="_blank">http://wg21.link/cwg2141</a>">2141</a></td><br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>