aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard@metafoo.co.uk>2020-02-11 06:09:18 -0800
committerRichard Smith <richard@metafoo.co.uk>2020-02-11 06:52:45 -0800
commit9ce6dc9872be4081fb98f6161c28581e1cbbe7dc (patch)
tree05f598a62d1aa5c52d0e587bd1cdaec1f78f0856 /clang/lib/Sema/SemaInit.cpp
parent7ef45f45f6721af4942f0e0bc38329e236b468cd (diff)
downloadllvm-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.cpp25
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