Index: clang/lib/AST/Interp/Boolean.h =================================================================== --- clang/lib/AST/Interp/Boolean.h +++ clang/lib/AST/Interp/Boolean.h @@ -50,6 +50,7 @@ explicit operator int64_t() const { return V; } explicit operator uint64_t() const { return V; } explicit operator int() const { return V; } + explicit operator bool() const { return V; } APSInt toAPSInt() const { return APSInt(APInt(1, static_cast(V), false), true); @@ -85,9 +86,10 @@ static Boolean min(unsigned NumBits) { return Boolean(false); } static Boolean max(unsigned NumBits) { return Boolean(true); } - template - static std::enable_if_t::value, Boolean> from(T Value) { - return Boolean(Value != 0); + template static Boolean from(T Value) { + if constexpr (std::is_integral::value) + return Boolean(Value != 0); + return Boolean(static_cast(Value) != 0); } template Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -117,6 +117,7 @@ case CK_NullToPointer: return this->Visit(SubExpr); + case CK_IntegralToBoolean: case CK_IntegralCast: { Optional FromT = classify(SubExpr->getType()); Optional ToT = classify(CE->getType()); @@ -132,19 +133,6 @@ case CK_ToVoid: return discard(SubExpr); - case CK_IntegralToBoolean: - // Compare integral from Subexpr with 0 - if (Optional T = classify(SubExpr->getType())) { - if (!this->Visit(SubExpr)) - return false; - - if (!this->emitConst(SubExpr, 0)) - return false; - - return this->emitNE(*T, SubExpr); - } - return false; - default: assert(false && "Cast not implemented"); } Index: clang/lib/AST/Interp/Opcodes.td =================================================================== --- clang/lib/AST/Interp/Opcodes.td +++ clang/lib/AST/Interp/Opcodes.td @@ -425,12 +425,16 @@ //===----------------------------------------------------------------------===// // TODO: Expand this to handle casts between more types. -def Sint32TypeClass : TypeClass { - let Types = [Sint32]; +def FromCastTypeClass : TypeClass { + let Types = [Sint32, Bool]; +} + +def ToCastTypeClass : TypeClass { + let Types = [Sint32, Bool]; } def Cast: Opcode { - let Types = [BoolTypeClass, Sint32TypeClass]; + let Types = [FromCastTypeClass, ToCastTypeClass]; let HasGroup = 1; } Index: clang/test/AST/Interp/literals.cpp =================================================================== --- clang/test/AST/Interp/literals.cpp +++ clang/test/AST/Interp/literals.cpp @@ -14,6 +14,11 @@ // expected-note{{evaluates to}} \ // ref-note{{evaluates to}} +constexpr bool b = number; +static_assert(b, ""); +constexpr int one = true; +static_assert(one == 1, ""); + constexpr bool getTrue() { return true; } constexpr bool getFalse() { return false; } constexpr void* getNull() { return nullptr; }