<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>