diff options
author | Richard Smith <richard@metafoo.co.uk> | 2020-02-11 06:09:18 -0800 |
---|---|---|
committer | Richard Smith <richard@metafoo.co.uk> | 2020-02-11 06:52:45 -0800 |
commit | 9ce6dc9872be4081fb98f6161c28581e1cbbe7dc (patch) | |
tree | 05f598a62d1aa5c52d0e587bd1cdaec1f78f0856 /clang/lib/Sema/SemaInit.cpp | |
parent | 7ef45f45f6721af4942f0e0bc38329e236b468cd (diff) | |
download | llvm-9ce6dc9872be4081fb98f6161c28581e1cbbe7dc.zip llvm-9ce6dc9872be4081fb98f6161c28581e1cbbe7dc.tar.gz llvm-9ce6dc9872be4081fb98f6161c28581e1cbbe7dc.tar.bz2 |
CWG1423: don't permit implicit conversion of nullptr_t to bool.
The C++ rules briefly allowed this, but the rule changed nearly 10 years
ago and we never updated our implementation to match. However, we've
warned on this by default for a long time, and no other compiler accepts
(even as an extension).
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 61b7c16..61bb1f0 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -4420,16 +4420,20 @@ static void TryListInitialization(Sema &S, // direct-list-initialization and copy-initialization otherwise. // We can't use InitListChecker for this, because it always performs // copy-initialization. This only matters if we might use an 'explicit' - // conversion operator, so we only need to handle the cases where the source - // is of record type. - if (InitList->getInit(0)->getType()->isRecordType()) { + // conversion operator, or for the special case conversion of nullptr_t to + // bool, so we only need to handle those cases. + // + // FIXME: Why not do this in all cases? + Expr *Init = InitList->getInit(0); + if (Init->getType()->isRecordType() || + (Init->getType()->isNullPtrType() && DestType->isBooleanType())) { InitializationKind SubKind = Kind.getKind() == InitializationKind::IK_DirectList ? InitializationKind::CreateDirect(Kind.getLocation(), InitList->getLBraceLoc(), InitList->getRBraceLoc()) : Kind; - Expr *SubInit[1] = { InitList->getInit(0) }; + Expr *SubInit[1] = { Init }; Sequence.InitializeFrom(S, Entity, SubKind, SubInit, /*TopLevelOfInitList*/true, TreatUnavailableAsInvalid); @@ -5854,6 +5858,19 @@ void InitializationSequence::InitializeFrom(Sema &S, return; } + // - Otherwise, if the initialization is direct-initialization, the source + // type is std::nullptr_t, and the destination type is bool, the initial + // value of the object being initialized is false. + if (!SourceType.isNull() && SourceType->isNullPtrType() && + DestType->isBooleanType() && + Kind.getKind() == InitializationKind::IK_Direct) { + AddConversionSequenceStep( + ImplicitConversionSequence::getNullptrToBool(SourceType, DestType, + Initializer->isGLValue()), + DestType); + return; + } + // - Otherwise, the initial value of the object being initialized is the // (possibly converted) value of the initializer expression. Standard // conversions (Clause 4) will be used, if necessary, to convert the |