Skip to content

Commit

Permalink
make reinterpret_cast between integer types of same size works + memc…
Browse files Browse the repository at this point in the history
…mp builtin + span as_bytes/as_writable_bytes works
  • Loading branch information
hanickadot committed Aug 19, 2024
1 parent 417fad9 commit c76cb33
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
18 changes: 12 additions & 6 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4666,7 +4666,7 @@ struct CompoundAssignSubobjectHandler {
if (!checkConst(SubobjType))
return false;

if (!SubobjType->isIntegerType()) {
if (!SubobjType->isIntegerType() && !SubobjType->isEnumeralType()) {
// We don't support compound assignment on integer-cast-to-pointer
// values.
Info.FFDiag(E);
Expand Down Expand Up @@ -7984,7 +7984,8 @@ class ExprEvaluatorBase
}

bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E) {
CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
if (!Info.Ctx.getLangOpts().CPlusPlus26)
CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
return static_cast<Derived*>(this)->VisitCastExpr(E);
}
bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) {
Expand Down Expand Up @@ -9508,6 +9509,9 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
(HasValidResult &&
Info.Ctx.hasSimilarType(Result.Designator.getType(Info.Ctx),
E->getType()->getPointeeType()));

bool BothAreIntsOrEnums = (E->getType()->getPointeeType()->isIntegerType() || E->getType()->getPointeeType()->isEnumeralType()) && (Result.Designator.getType(Info.Ctx)->isIntegerType() || Result.Designator.getType(Info.Ctx)->isEnumeralType());

// 1. We'll allow it in std::allocator::allocate, and anything which that
// calls.
// 2. HACK 2022-03-28: Work around an issue with libstdc++'s
Expand All @@ -9520,6 +9524,8 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
IsDeclSourceLocationCurrent(Info.CurrentCall->Callee) ||
Info.getLangOpts().CPlusPlus26)) {
// Permitted.
} else if (BothAreIntsOrEnums && Info.Ctx.getIntWidth(E->getType()->getPointeeType()) == Info.Ctx.getIntWidth(Result.Designator.getType(Info.Ctx))) {
// Permitted now :)
} else {
if (SubExpr->getType()->isVoidPointerType() &&
Info.getLangOpts().CPlusPlus) {
Expand All @@ -9531,9 +9537,10 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
else
CCEDiag(E, diag::note_constexpr_invalid_cast)
<< 3 << SubExpr->getType();
} else
} else {
CCEDiag(E, diag::note_constexpr_invalid_cast)
<< 2 << Info.Ctx.getLangOpts().CPlusPlus;
}
Result.Designator.setInvalid();
}
}
Expand Down Expand Up @@ -9747,7 +9754,7 @@ bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) {
// Determine if T is a character type for which we guarantee that
// sizeof(T) == 1.
static bool isOneByteCharacterType(QualType T) {
return T->isCharType() || T->isChar8Type();
return T->isCharType() || T->isChar8Type() || T->isStdByteType();
}

bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
Expand Down Expand Up @@ -11774,11 +11781,10 @@ class IntExprEvaluator
bool Success(const llvm::APSInt &SI, const Expr *E, APValue &Result) {
assert(E->getType()->isIntegralOrEnumerationType() &&
"Invalid evaluation result.");
assert(SI.isSigned() == E->getType()->isSignedIntegerOrEnumerationType() &&
"Invalid evaluation result.");
assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
"Invalid evaluation result.");
Result = APValue(SI);
Result.getInt().setIsUnsigned(E->getType()->isUnsignedIntegerOrEnumerationType());
return true;
}
bool Success(const llvm::APSInt &SI, const Expr *E) {
Expand Down
12 changes: 6 additions & 6 deletions libcxx/include/span
Original file line number Diff line number Diff line change
Expand Up @@ -393,11 +393,11 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
_LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }

_LIBCPP_HIDE_FROM_ABI span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept {
_LIBCPP_HIDE_FROM_ABI constexpr span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept {
return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte*>(data()), size_bytes()};
}

_LIBCPP_HIDE_FROM_ABI span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept {
_LIBCPP_HIDE_FROM_ABI constexpr span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept {
return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte*>(data()), size_bytes()};
}

Expand Down Expand Up @@ -555,11 +555,11 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
_LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }

_LIBCPP_HIDE_FROM_ABI span<const byte, dynamic_extent> __as_bytes() const noexcept {
_LIBCPP_HIDE_FROM_ABI constexpr span<const byte, dynamic_extent> __as_bytes() const noexcept {
return {reinterpret_cast<const byte*>(data()), size_bytes()};
}

_LIBCPP_HIDE_FROM_ABI span<byte, dynamic_extent> __as_writable_bytes() const noexcept {
_LIBCPP_HIDE_FROM_ABI constexpr span<byte, dynamic_extent> __as_writable_bytes() const noexcept {
return {reinterpret_cast<byte*>(data()), size_bytes()};
}

Expand All @@ -576,13 +576,13 @@ inline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true;

// as_bytes & as_writable_bytes
template <class _Tp, size_t _Extent>
_LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept {
_LIBCPP_HIDE_FROM_ABI constexpr auto as_bytes(span<_Tp, _Extent> __s) noexcept {
return __s.__as_bytes();
}

template <class _Tp, size_t _Extent>
requires(!is_const_v<_Tp>)
_LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept {
_LIBCPP_HIDE_FROM_ABI constexpr auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept {
return __s.__as_writable_bytes();
}

Expand Down

0 comments on commit c76cb33

Please sign in to comment.