From: Richard Smith Date: Thu, 19 Feb 2015 00:39:05 +0000 (+0000) Subject: PR22566: a conversion from a floating-point type to bool is a narrowing conversion. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6443e006c6a93a8eb0d8a1ab8c0a5cbe248b98cc;p=clang PR22566: a conversion from a floating-point type to bool is a narrowing conversion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@229792 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 53ebdd793b..0728f783aa 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/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/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp index 42dee92b3c..48c5b23207 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp +++ b/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