Index: clang/lib/AST/Interp/Boolean.h =================================================================== --- clang/lib/AST/Interp/Boolean.h +++ clang/lib/AST/Interp/Boolean.h @@ -48,6 +48,10 @@ Boolean operator~() const { return Boolean(true); } explicit operator unsigned() const { return V; } + explicit operator int8_t() const { return V; } + explicit operator uint8_t() const { return V; } + explicit operator int16_t() const { return V; } + explicit operator uint16_t() const { return V; } explicit operator int64_t() const { return V; } explicit operator uint64_t() const { return V; } explicit operator int() const { return V; } Index: clang/lib/AST/Interp/ByteCodeExprGen.h =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.h +++ clang/lib/AST/Interp/ByteCodeExprGen.h @@ -80,6 +80,7 @@ bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E); bool VisitInitListExpr(const InitListExpr *E); bool VisitConstantExpr(const ConstantExpr *E); + bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E); protected: bool visitExpr(const Expr *E) override; Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -281,7 +281,19 @@ } template -bool ByteCodeExprGen::discard(const Expr *E) { +bool ByteCodeExprGen::VisitUnaryExprOrTypeTraitExpr( + const UnaryExprOrTypeTraitExpr *E) { + + if (E->getKind() == UETT_SizeOf) { + QualType ArgType = E->getTypeOfArgument(); + return this->emitConst( + E, Ctx.getASTContext().getTypeSizeInChars(ArgType).getQuantity()); + } + + return false; +} + +template bool ByteCodeExprGen::discard(const Expr *E) { OptionScope Scope(this, /*NewDiscardResult=*/true); return this->Visit(E); } Index: clang/lib/AST/Interp/Opcodes.td =================================================================== --- clang/lib/AST/Interp/Opcodes.td +++ clang/lib/AST/Interp/Opcodes.td @@ -427,11 +427,11 @@ // TODO: Expand this to handle casts between more types. def FromCastTypeClass : TypeClass { - let Types = [Uint32, Sint32, Bool]; + let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool]; } def ToCastTypeClass : TypeClass { - let Types = [Uint32, Sint32, Bool]; + let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool]; } def Cast: Opcode { Index: clang/test/AST/Interp/literals.cpp =================================================================== --- clang/test/AST/Interp/literals.cpp +++ clang/test/AST/Interp/literals.cpp @@ -72,10 +72,33 @@ constexpr const int* getIntPointer() { return &m; } -//static_assert(getIntPointer() == &m, ""); TODO -//static_assert(*getIntPointer() == 10, ""); TODO +static_assert(getIntPointer() == &m, ""); +static_assert(*getIntPointer() == 10, ""); constexpr int gimme(int k) { return k; } -// static_assert(gimme(5) == 5, ""); TODO +static_assert(gimme(5) == 5, ""); + +namespace SizeOf { + constexpr int soint = sizeof(int); + constexpr int souint = sizeof(unsigned int); + static_assert(soint == souint, ""); + + static_assert(sizeof(&soint) == sizeof(void*), ""); + static_assert(sizeof(&soint) == sizeof(nullptr), ""); + + static_assert(sizeof(long) == sizeof(unsigned long), ""); + static_assert(sizeof(char) == sizeof(unsigned char), ""); + + constexpr int N = 4; + constexpr int arr[N] = {1,2,3,4}; + static_assert(sizeof(arr) == N * sizeof(int), ""); + static_assert(sizeof(arr) == N * sizeof(arr[0]), ""); + + constexpr bool arrB[N] = {true, true, true, true}; + static_assert(sizeof(arrB) == N * sizeof(bool), ""); + + static_assert(sizeof(bool) == 1, ""); + static_assert(sizeof(char) == 1, ""); +};