Re: r284685 - Refactor and simplify Sema::FindCompositePointerType. No functionality change intended.
Should hopefully be fixed by r284701. On Thu, Oct 20, 2016 at 12:55 AM, Richard Smithwrote: > I think I understand the MSVC bug here; workaround incoming. > > On Wed, Oct 19, 2016 at 11:54 PM, Mike Aizatsky > wrote: > >> I think this breaks windows bot: >> >> http://lab.llvm.org:8011/builders/sanitizer-windows/builds/ >> 30745/steps/build%20clang%20lld/logs/stdio >> >> C:\PROGRA~2\MICROS~1.0\VC\bin\AMD64_~2\cl.exe /nologo /TP >> -DCLANG_ENABLE_ARCMT -DCLANG_ENABLE_OBJC_REWRITER >> -DCLANG_ENABLE_STATIC_ANALYZER -DGTEST_HAS_RTTI=0 -DUNICODE >> -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS >> -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_GNU_SOURCE >> -D_HAS_EXCEPTIONS=0 -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS >> -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS >> -D__STDC_LIMIT_MACROS -Itools\clang\lib\Sema >> -IC:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema >> -IC:\b\slave\sanitizer-windows\llvm\tools\clang\include >> -Itools\clang\include -Iinclude -IC:\b\slave\sanitizer-windows\llvm\include >> /DWIN32 /D_WINDOWS /W4 -wd4141 -wd4146 -wd4180 -wd4244 -wd4258 -wd4267 >> -wd4291 -wd4345 -wd4351 -wd4355 -wd4456 -wd4457 -wd4458 -wd4459 -wd4503 >> -wd4624 -wd4722 -wd4800 -wd4100 -wd4127 -wd4512 -wd4505 -wd4610 -wd4510 >> -wd4702 -wd4245 -wd4706 -wd4310 -wd4701 -wd4703 -wd4389 -wd4611 -wd4805 >> -wd4204 -wd4577 -wd4091 -wd4592 -wd4319 -wd4324 -w14062 -we4238 /Zc:inline >> /Zc:strictStrings /Oi /Zc:rvalueCast /Zc:sizedDealloc- /MD /O2 /Ob2 >> -UNDEBUG /EHs-c- /GR- /showIncludes >> /Fotools\clang\lib\Sema\CMakeFiles\clangSema.dir\SemaExprCXX.cpp.obj >> /Fdtools\clang\lib\Sema\CMakeFiles\clangSema.dir\ /FS -c >> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp >> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp(5702): >> error C2326: >> 'clang::Sema::FindCompositePointerType::Conversion::Conversion(clang::Sema >> &,clang::SourceLocation,clang::Expr *&,clang::Expr *&,clang::QualType)': >> function cannot access 'Composite' >> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp(5702): >> error C2248: 'clang::InitializedEntity::InitializedEntity': cannot access >> private member declared in class 'clang::InitializedEntity' >> C:\b\slave\sanitizer-windows\llvm\tools\clang\include\clang/Sema/Initialization.h(163): >> note: see declaration of 'clang::InitializedEntity::InitializedEntity' >> C:\b\slave\sanitizer-windows\llvm\tools\clang\include\clang/Sema/Initialization.h(40): >> note: see declaration of 'clang::InitializedEntity' >> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp(5704): >> error C2326: >> 'clang::Sema::FindCompositePointerType::Conversion::Conversion(clang::Sema >> &,clang::SourceLocation,clang::Expr *&,clang::Expr *&,clang::QualType)': >> function cannot access 'Loc' >> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp(5704): >> error C2512: 'clang::InitializationKind::InitializationKind': no >> appropriate default constructor available >> 251843.519 [4/2/26] Building CXX object >> lib\Target\X86\CMakeFiles\LLVMX86CodeGen.dir\X86WinAllocaExpander.cpp.obj >> 251843.902 [4/1/27] Building CXX object >> lib\Target\X86\CMakeFiles\LLVMX86CodeGen.dir\X86TargetMachine.cpp.obj >> 251846.937 [4/0/28] Building CXX object >> lib\Target\X86\CMakeFiles\LLVMX86CodeGen.dir\X86ISelLowering.cpp.obj >> ninja: build stopped: subcommand failed. >> >> >> >> On Wed, Oct 19, 2016 at 6:29 PM Richard Smith via cfe-commits < >> cfe-commits@lists.llvm.org> wrote: >> >>> Author: rsmith >>> Date: Wed Oct 19 20:20:00 2016 >>> New Revision: 284685 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=284685=rev >>> Log: >>> Refactor and simplify Sema::FindCompositePointerType. No functionality >>> change intended. >>> >>> Modified: >>> cfe/trunk/lib/Sema/SemaExprCXX.cpp >>> >>> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp >>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaE >>> xprCXX.cpp?rev=284685=284684=284685=diff >>> >>> == >>> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) >>> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Oct 19 20:20:00 2016 >>> @@ -5520,7 +5520,7 @@ QualType Sema::CXXCheckConditionalOperan >>> /// \brief Find a merged pointer type and convert the two expressions >>> to it. >>> /// >>> /// This finds the composite pointer type (or member pointer type) for >>> @p E1 >>> -/// and @p E2 according to C++11 5.9p2. It converts both expressions to >>> this >>> +/// and @p E2 according to C++1z 5p14. It converts both expressions to >>> this >>> /// type and returns it. >>> /// It does not emit diagnostics. >>> /// >>> @@ -5538,69 +5538,87 @@ QualType Sema::FindCompositePointerType( >>> *NonStandardCompositeType = false; >>> >>>assert(getLangOpts().CPlusPlus &&
Re: r284685 - Refactor and simplify Sema::FindCompositePointerType. No functionality change intended.
I think I understand the MSVC bug here; workaround incoming. On Wed, Oct 19, 2016 at 11:54 PM, Mike Aizatskywrote: > I think this breaks windows bot: > > http://lab.llvm.org:8011/builders/sanitizer-windows/ > builds/30745/steps/build%20clang%20lld/logs/stdio > > C:\PROGRA~2\MICROS~1.0\VC\bin\AMD64_~2\cl.exe /nologo /TP > -DCLANG_ENABLE_ARCMT -DCLANG_ENABLE_OBJC_REWRITER > -DCLANG_ENABLE_STATIC_ANALYZER -DGTEST_HAS_RTTI=0 -DUNICODE > -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS > -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_GNU_SOURCE > -D_HAS_EXCEPTIONS=0 -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS > -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS > -D__STDC_LIMIT_MACROS -Itools\clang\lib\Sema > -IC:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema > -IC:\b\slave\sanitizer-windows\llvm\tools\clang\include -Itools\clang\include > -Iinclude -IC:\b\slave\sanitizer-windows\llvm\include /DWIN32 /D_WINDOWS > /W4 -wd4141 -wd4146 -wd4180 -wd4244 -wd4258 -wd4267 -wd4291 -wd4345 -wd4351 > -wd4355 -wd4456 -wd4457 -wd4458 -wd4459 -wd4503 -wd4624 -wd4722 -wd4800 > -wd4100 -wd4127 -wd4512 -wd4505 -wd4610 -wd4510 -wd4702 -wd4245 -wd4706 > -wd4310 -wd4701 -wd4703 -wd4389 -wd4611 -wd4805 -wd4204 -wd4577 -wd4091 > -wd4592 -wd4319 -wd4324 -w14062 -we4238 /Zc:inline /Zc:strictStrings /Oi > /Zc:rvalueCast /Zc:sizedDealloc- /MD /O2 /Ob2 -UNDEBUG /EHs-c- /GR- > /showIncludes > /Fotools\clang\lib\Sema\CMakeFiles\clangSema.dir\SemaExprCXX.cpp.obj > /Fdtools\clang\lib\Sema\CMakeFiles\clangSema.dir\ /FS -c > C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp > C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp(5702): > error C2326: > 'clang::Sema::FindCompositePointerType::Conversion::Conversion(clang::Sema > &,clang::SourceLocation,clang::Expr *&,clang::Expr *&,clang::QualType)': > function cannot access 'Composite' > C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp(5702): > error C2248: 'clang::InitializedEntity::InitializedEntity': cannot access > private member declared in class 'clang::InitializedEntity' > C:\b\slave\sanitizer-windows\llvm\tools\clang\include\clang/Sema/Initialization.h(163): > note: see declaration of 'clang::InitializedEntity::InitializedEntity' > C:\b\slave\sanitizer-windows\llvm\tools\clang\include\clang/Sema/Initialization.h(40): > note: see declaration of 'clang::InitializedEntity' > C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp(5704): > error C2326: > 'clang::Sema::FindCompositePointerType::Conversion::Conversion(clang::Sema > &,clang::SourceLocation,clang::Expr *&,clang::Expr *&,clang::QualType)': > function cannot access 'Loc' > C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp(5704): > error C2512: 'clang::InitializationKind::InitializationKind': no appropriate > default constructor available > 251843.519 [4/2/26] Building CXX object > lib\Target\X86\CMakeFiles\LLVMX86CodeGen.dir\X86WinAllocaExpander.cpp.obj > 251843.902 [4/1/27] Building CXX object > lib\Target\X86\CMakeFiles\LLVMX86CodeGen.dir\X86TargetMachine.cpp.obj > 251846.937 [4/0/28] Building CXX object > lib\Target\X86\CMakeFiles\LLVMX86CodeGen.dir\X86ISelLowering.cpp.obj > ninja: build stopped: subcommand failed. > > > > On Wed, Oct 19, 2016 at 6:29 PM Richard Smith via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > >> Author: rsmith >> Date: Wed Oct 19 20:20:00 2016 >> New Revision: 284685 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=284685=rev >> Log: >> Refactor and simplify Sema::FindCompositePointerType. No functionality >> change intended. >> >> Modified: >> cfe/trunk/lib/Sema/SemaExprCXX.cpp >> >> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/ >> SemaExprCXX.cpp?rev=284685=284684=284685=diff >> >> == >> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Oct 19 20:20:00 2016 >> @@ -5520,7 +5520,7 @@ QualType Sema::CXXCheckConditionalOperan >> /// \brief Find a merged pointer type and convert the two expressions to >> it. >> /// >> /// This finds the composite pointer type (or member pointer type) for >> @p E1 >> -/// and @p E2 according to C++11 5.9p2. It converts both expressions to >> this >> +/// and @p E2 according to C++1z 5p14. It converts both expressions to >> this >> /// type and returns it. >> /// It does not emit diagnostics. >> /// >> @@ -5538,69 +5538,87 @@ QualType Sema::FindCompositePointerType( >> *NonStandardCompositeType = false; >> >>assert(getLangOpts().CPlusPlus && "This function assumes C++"); >> + >> + // C++1z [expr]p14: >> + // The composite pointer type of two operands p1 and p2 having types >> T1 >> + // and T2 >>QualType T1 = E1->getType(), T2 = E2->getType(); >> >> -
Re: r284685 - Refactor and simplify Sema::FindCompositePointerType. No functionality change intended.
I think this breaks windows bot: http://lab.llvm.org:8011/builders/sanitizer-windows/builds/30745/steps/build%20clang%20lld/logs/stdio C:\PROGRA~2\MICROS~1.0\VC\bin\AMD64_~2\cl.exe /nologo /TP -DCLANG_ENABLE_ARCMT -DCLANG_ENABLE_OBJC_REWRITER -DCLANG_ENABLE_STATIC_ANALYZER -DGTEST_HAS_RTTI=0 -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_GNU_SOURCE -D_HAS_EXCEPTIONS=0 -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Itools\clang\lib\Sema -IC:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema -IC:\b\slave\sanitizer-windows\llvm\tools\clang\include -Itools\clang\include -Iinclude -IC:\b\slave\sanitizer-windows\llvm\include /DWIN32 /D_WINDOWS /W4 -wd4141 -wd4146 -wd4180 -wd4244 -wd4258 -wd4267 -wd4291 -wd4345 -wd4351 -wd4355 -wd4456 -wd4457 -wd4458 -wd4459 -wd4503 -wd4624 -wd4722 -wd4800 -wd4100 -wd4127 -wd4512 -wd4505 -wd4610 -wd4510 -wd4702 -wd4245 -wd4706 -wd4310 -wd4701 -wd4703 -wd4389 -wd4611 -wd4805 -wd4204 -wd4577 -wd4091 -wd4592 -wd4319 -wd4324 -w14062 -we4238 /Zc:inline /Zc:strictStrings /Oi /Zc:rvalueCast /Zc:sizedDealloc- /MD /O2 /Ob2 -UNDEBUG /EHs-c- /GR- /showIncludes /Fotools\clang\lib\Sema\CMakeFiles\clangSema.dir\SemaExprCXX.cpp.obj /Fdtools\clang\lib\Sema\CMakeFiles\clangSema.dir\ /FS -c C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp(5702): error C2326: 'clang::Sema::FindCompositePointerType::Conversion::Conversion(clang::Sema &,clang::SourceLocation,clang::Expr *&,clang::Expr *&,clang::QualType)': function cannot access 'Composite' C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp(5702): error C2248: 'clang::InitializedEntity::InitializedEntity': cannot access private member declared in class 'clang::InitializedEntity' C:\b\slave\sanitizer-windows\llvm\tools\clang\include\clang/Sema/Initialization.h(163): note: see declaration of 'clang::InitializedEntity::InitializedEntity' C:\b\slave\sanitizer-windows\llvm\tools\clang\include\clang/Sema/Initialization.h(40): note: see declaration of 'clang::InitializedEntity' C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp(5704): error C2326: 'clang::Sema::FindCompositePointerType::Conversion::Conversion(clang::Sema &,clang::SourceLocation,clang::Expr *&,clang::Expr *&,clang::QualType)': function cannot access 'Loc' C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\Sema\SemaExprCXX.cpp(5704): error C2512: 'clang::InitializationKind::InitializationKind': no appropriate default constructor available 251843.519 [4/2/26] Building CXX object lib\Target\X86\CMakeFiles\LLVMX86CodeGen.dir\X86WinAllocaExpander.cpp.obj 251843.902 [4/1/27] Building CXX object lib\Target\X86\CMakeFiles\LLVMX86CodeGen.dir\X86TargetMachine.cpp.obj 251846.937 [4/0/28] Building CXX object lib\Target\X86\CMakeFiles\LLVMX86CodeGen.dir\X86ISelLowering.cpp.obj ninja: build stopped: subcommand failed. On Wed, Oct 19, 2016 at 6:29 PM Richard Smith via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: rsmith > Date: Wed Oct 19 20:20:00 2016 > New Revision: 284685 > > URL: http://llvm.org/viewvc/llvm-project?rev=284685=rev > Log: > Refactor and simplify Sema::FindCompositePointerType. No functionality > change intended. > > Modified: > cfe/trunk/lib/Sema/SemaExprCXX.cpp > > Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=284685=284684=284685=diff > > == > --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Oct 19 20:20:00 2016 > @@ -5520,7 +5520,7 @@ QualType Sema::CXXCheckConditionalOperan > /// \brief Find a merged pointer type and convert the two expressions to > it. > /// > /// This finds the composite pointer type (or member pointer type) for @p > E1 > -/// and @p E2 according to C++11 5.9p2. It converts both expressions to > this > +/// and @p E2 according to C++1z 5p14. It converts both expressions to > this > /// type and returns it. > /// It does not emit diagnostics. > /// > @@ -5538,69 +5538,87 @@ QualType Sema::FindCompositePointerType( > *NonStandardCompositeType = false; > >assert(getLangOpts().CPlusPlus && "This function assumes C++"); > + > + // C++1z [expr]p14: > + // The composite pointer type of two operands p1 and p2 having types > T1 > + // and T2 >QualType T1 = E1->getType(), T2 = E2->getType(); > > - // C++11 5.9p2 > - // Pointer conversions and qualification conversions are performed on > - // pointer operands to bring them to their composite pointer type. If > - // one operand is a null pointer constant, the composite pointer type > is > - // std::nullptr_t if the other operand is also a null pointer > constant
r284685 - Refactor and simplify Sema::FindCompositePointerType. No functionality change intended.
Author: rsmith Date: Wed Oct 19 20:20:00 2016 New Revision: 284685 URL: http://llvm.org/viewvc/llvm-project?rev=284685=rev Log: Refactor and simplify Sema::FindCompositePointerType. No functionality change intended. Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=284685=284684=284685=diff == --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Oct 19 20:20:00 2016 @@ -5520,7 +5520,7 @@ QualType Sema::CXXCheckConditionalOperan /// \brief Find a merged pointer type and convert the two expressions to it. /// /// This finds the composite pointer type (or member pointer type) for @p E1 -/// and @p E2 according to C++11 5.9p2. It converts both expressions to this +/// and @p E2 according to C++1z 5p14. It converts both expressions to this /// type and returns it. /// It does not emit diagnostics. /// @@ -5538,69 +5538,87 @@ QualType Sema::FindCompositePointerType( *NonStandardCompositeType = false; assert(getLangOpts().CPlusPlus && "This function assumes C++"); + + // C++1z [expr]p14: + // The composite pointer type of two operands p1 and p2 having types T1 + // and T2 QualType T1 = E1->getType(), T2 = E2->getType(); - // C++11 5.9p2 - // Pointer conversions and qualification conversions are performed on - // pointer operands to bring them to their composite pointer type. If - // one operand is a null pointer constant, the composite pointer type is - // std::nullptr_t if the other operand is also a null pointer constant or, - // if the other operand is a pointer, the type of the other operand. - if (!T1->isAnyPointerType() && !T1->isMemberPointerType() && - !T2->isAnyPointerType() && !T2->isMemberPointerType()) { -if (T1->isNullPtrType() && -E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { - E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).get(); - return T1; -} -if (T2->isNullPtrType() && -E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { - E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).get(); - return T2; -} + // where at least one is a pointer or pointer to member type or + // std::nullptr_t is: + bool T1IsPointerLike = T1->isAnyPointerType() || T1->isMemberPointerType() || + T1->isNullPtrType(); + bool T2IsPointerLike = T2->isAnyPointerType() || T2->isMemberPointerType() || + T2->isNullPtrType(); + if (!T1IsPointerLike && !T2IsPointerLike) return QualType(); - } - if (E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { -if (T2->isMemberPointerType()) - E1 = ImpCastExprToType(E1, T2, CK_NullToMemberPointer).get(); -else - E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).get(); -return T2; - } - if (E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { -if (T1->isMemberPointerType()) - E2 = ImpCastExprToType(E2, T1, CK_NullToMemberPointer).get(); -else - E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).get(); + // - if both p1 and p2 are null pointer constants, std::nullptr_t; + // This can't actually happen, following the standard, but we also use this + // to implement the end of [expr.conv], which hits this case. + // + // - if either p1 or p2 is a null pointer constant, T2 or T1, respectively; + if (T1IsPointerLike && + E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { +E2 = ImpCastExprToType(E2, T1, T1->isMemberPointerType() + ? CK_NullToMemberPointer + : CK_NullToPointer).get(); return T1; } + if (T2IsPointerLike && + E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { +E1 = ImpCastExprToType(E1, T2, T2->isMemberPointerType() + ? CK_NullToMemberPointer + : CK_NullToPointer).get(); +return T2; + } // Now both have to be pointers or member pointers. - if ((!T1->isPointerType() && !T1->isMemberPointerType()) || - (!T2->isPointerType() && !T2->isMemberPointerType())) + if (!T1IsPointerLike || !T2IsPointerLike) return QualType(); + assert(!T1->isNullPtrType() && !T2->isNullPtrType() && + "nullptr_t should be a null pointer constant"); - // Otherwise, of one of the operands has type "pointer to cv1 void," then - // the other has type "pointer to cv2 T" and the composite pointer type is - // "pointer to cv12 void," where cv12 is the union of cv1 and cv2. - // Otherwise, the composite pointer type is a pointer type similar to the - // type of one of the operands, with a cv-qualification signature that is - // the