From: Abramo Bagnara Date: Thu, 7 Apr 2011 09:26:19 +0000 (+0000) Subject: In C++ the argument of logical not should always be bool. Added missing implicit... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=737d5447b5d20633992ee5388eca5270c28c8ae7;p=clang In C++ the argument of logical not should always be bool. Added missing implicit cast for scalars. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129066 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 6adf844c97..356ffed694 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -4749,6 +4749,10 @@ public: ExprValueKind VK = VK_RValue, const CXXCastPath *BasePath = 0); + /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding + /// to the conversion from scalar type ScalarTy to the Boolean type. + static CastKind ScalarTypeToBooleanCastKind(QualType ScalarTy); + /// IgnoredValueConversions - Given that an expression's result is /// syntactically ignored, perform any conversions that are /// required. diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 0846845e26..0e783018ec 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -235,6 +235,21 @@ void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty, Expr = ImplicitCastExpr::Create(Context, Ty, Kind, Expr, BasePath, VK); } +/// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding +/// to the conversion from scalar type ScalarTy to the Boolean type. +CastKind Sema::ScalarTypeToBooleanCastKind(QualType ScalarTy) { + switch (ScalarTy->getScalarTypeKind()) { + case Type::STK_Bool: return CK_NoOp; + case Type::STK_Pointer: return CK_PointerToBoolean; + case Type::STK_MemberPointer: return CK_MemberPointerToBoolean; + case Type::STK_Integral: return CK_IntegralToBoolean; + case Type::STK_Floating: return CK_FloatingToBoolean; + case Type::STK_IntegralComplex: return CK_IntegralComplexToBoolean; + case Type::STK_FloatingComplex: return CK_FloatingComplexToBoolean; + } + return CK_Invalid; +} + ExprValueKind Sema::CastCategory(Expr *E) { Expr::Classification Classification = E->Classify(Context); return Classification.isRValue() ? VK_RValue : diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index b62b2eeff1..a822c45b90 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -8633,8 +8633,14 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, resultType = Input->getType(); if (resultType->isDependentType()) break; - if (resultType->isScalarType()) { // C99 6.5.3.3p1 - // ok, fallthrough + if (resultType->isScalarType()) { + // C99 6.5.3.3p1: ok, fallthrough; + if (Context.getLangOptions().CPlusPlus) { + // C++03 [expr.unary.op]p8, C++0x [expr.unary.op]p9: + // operand contextually converted to bool. + ImpCastExprToType(Input, Context.BoolTy, + ScalarTypeToBooleanCastKind(resultType)); + } } else if (resultType->isPlaceholderType()) { ExprResult PR = CheckPlaceholderExpr(Input, OpLoc); if (PR.isInvalid()) return ExprError(); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 8c81acc9d1..3d38b511ec 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2183,21 +2183,11 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath); break; } - case ICK_Boolean_Conversion: { - CastKind Kind = CK_Invalid; - switch (FromType->getScalarTypeKind()) { - case Type::STK_Pointer: Kind = CK_PointerToBoolean; break; - case Type::STK_MemberPointer: Kind = CK_MemberPointerToBoolean; break; - case Type::STK_Bool: llvm_unreachable("bool -> bool conversion?"); - case Type::STK_Integral: Kind = CK_IntegralToBoolean; break; - case Type::STK_Floating: Kind = CK_FloatingToBoolean; break; - case Type::STK_IntegralComplex: Kind = CK_IntegralComplexToBoolean; break; - case Type::STK_FloatingComplex: Kind = CK_FloatingComplexToBoolean; break; - } - ImpCastExprToType(From, Context.BoolTy, Kind); + case ICK_Boolean_Conversion: + ImpCastExprToType(From, Context.BoolTy, + ScalarTypeToBooleanCastKind(FromType)); break; - } case ICK_Derived_To_Base: { CXXCastPath BasePath;