From 64ecacf6cb4d69a81bfe4bd71f367ff5194239ab Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 19 Feb 2015 00:39:05 +0000 Subject: [PATCH] PR22566: a conversion from a floating-point type to bool is a narrowing conversion. llvm-svn: 229792 --- clang/lib/Sema/SemaOverload.cpp | 20 ++++++++++++------- .../dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp | 3 +++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 53ebdd793b70..0728f783aad8 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -286,6 +286,16 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, QualType FromType = getToType(0); QualType ToType = getToType(1); switch (Second) { + // 'bool' is an integral type; dispatch to the right place to handle it. + case ICK_Boolean_Conversion: + if (FromType->isRealFloatingType()) + goto FloatingIntegralConversion; + if (FromType->isIntegralOrUnscopedEnumerationType()) + goto IntegralConversion; + // Boolean conversions can be from pointers and pointers to members + // [conv.bool], and those aren't considered narrowing conversions. + return NK_Not_Narrowing; + // -- from a floating-point type to an integer type, or // // -- from an integer type or unscoped enumeration type to a floating-point @@ -293,6 +303,7 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, // value after conversion will fit into the target type and will produce // the original value when converted back to the original type, or case ICK_Floating_Integral: + FloatingIntegralConversion: if (FromType->isRealFloatingType() && ToType->isIntegralType(Ctx)) { return NK_Type_Narrowing; } else if (FromType->isIntegralType(Ctx) && ToType->isRealFloatingType()) { @@ -357,13 +368,8 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, // the source is a constant expression and the actual value after // conversion will fit into the target type and will produce the original // value when converted back to the original type. - case ICK_Boolean_Conversion: // Bools are integers too. - if (!FromType->isIntegralOrUnscopedEnumerationType()) { - // Boolean conversions can be from pointers and pointers to members - // [conv.bool], and those aren't considered narrowing conversions. - return NK_Not_Narrowing; - } // Otherwise, fall through to the integral case. - case ICK_Integral_Conversion: { + case ICK_Integral_Conversion: + IntegralConversion: { assert(FromType->isIntegralOrUnscopedEnumerationType()); assert(ToType->isIntegralOrUnscopedEnumerationType()); const bool FromSigned = FromType->isSignedIntegerOrEnumerationType(); diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp index 42dee92b3ca3..48c5b23207c5 100644 --- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp @@ -57,6 +57,9 @@ void float_to_int() { Agg ce1 = { Convert(1.0) }; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{silence}} Agg ce2 = { ConvertVar() }; // expected-error {{type 'double' cannot be narrowed to 'char'}} expected-note {{silence}} + + bool b{1.0}; // expected-error {{type 'double' cannot be narrowed to 'bool'}} expected-note {{silence}} + Agg ab = {0.0}; // expected-error {{type 'double' cannot be narrowed to 'bool'}} expected-note {{silence}} } // * from long double to double or float, or from double to float, except where