mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 09:26:07 +00:00
[clang][bytecode] Only allow lossless ptr-to-int casts (#111669)
Only allow those casts if the bitwidth of the two types match.
This commit is contained in:
parent
1731bb79a9
commit
e637a5c9fe
@ -22,6 +22,7 @@
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/Basic/DiagnosticSema.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include <limits>
|
||||
@ -1415,6 +1416,46 @@ bool InvalidShuffleVectorIndex(InterpState &S, CodePtr OpPC, uint32_t Index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckPointerToIntegralCast(InterpState &S, CodePtr OpPC,
|
||||
const Pointer &Ptr, unsigned BitWidth) {
|
||||
if (Ptr.isDummy())
|
||||
return false;
|
||||
|
||||
const SourceInfo &E = S.Current->getSource(OpPC);
|
||||
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
|
||||
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
|
||||
|
||||
if (Ptr.isBlockPointer() && !Ptr.isZero()) {
|
||||
// Only allow based lvalue casts if they are lossless.
|
||||
if (S.getASTContext().getTargetInfo().getPointerWidth(LangAS::Default) !=
|
||||
BitWidth)
|
||||
return Invalid(S, OpPC);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
|
||||
const Pointer &Ptr = S.Stk.pop<Pointer>();
|
||||
|
||||
if (!CheckPointerToIntegralCast(S, OpPC, Ptr, BitWidth))
|
||||
return false;
|
||||
|
||||
S.Stk.push<IntegralAP<false>>(
|
||||
IntegralAP<false>::from(Ptr.getIntegerRepresentation(), BitWidth));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
|
||||
const Pointer &Ptr = S.Stk.pop<Pointer>();
|
||||
|
||||
if (!CheckPointerToIntegralCast(S, OpPC, Ptr, BitWidth))
|
||||
return false;
|
||||
|
||||
S.Stk.push<IntegralAP<true>>(
|
||||
IntegralAP<true>::from(Ptr.getIntegerRepresentation(), BitWidth));
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://github.com/llvm/llvm-project/issues/102513
|
||||
#if defined(_WIN32) && !defined(__clang__) && !defined(NDEBUG)
|
||||
#pragma optimize("", off)
|
||||
|
@ -2289,53 +2289,22 @@ static inline bool CastFloatingIntegralAPS(InterpState &S, CodePtr OpPC,
|
||||
return CheckFloatResult(S, OpPC, F, Status, FPO);
|
||||
}
|
||||
|
||||
bool CheckPointerToIntegralCast(InterpState &S, CodePtr OpPC,
|
||||
const Pointer &Ptr, unsigned BitWidth);
|
||||
bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth);
|
||||
bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth);
|
||||
|
||||
template <PrimType Name, class T = typename PrimConv<Name>::T>
|
||||
bool CastPointerIntegral(InterpState &S, CodePtr OpPC) {
|
||||
const Pointer &Ptr = S.Stk.pop<Pointer>();
|
||||
|
||||
if (Ptr.isDummy())
|
||||
if (!CheckPointerToIntegralCast(S, OpPC, Ptr, T::bitWidth()))
|
||||
return false;
|
||||
|
||||
const SourceInfo &E = S.Current->getSource(OpPC);
|
||||
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
|
||||
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
|
||||
|
||||
S.Stk.push<T>(T::from(Ptr.getIntegerRepresentation()));
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC,
|
||||
uint32_t BitWidth) {
|
||||
const Pointer &Ptr = S.Stk.pop<Pointer>();
|
||||
|
||||
if (Ptr.isDummy())
|
||||
return false;
|
||||
|
||||
const SourceInfo &E = S.Current->getSource(OpPC);
|
||||
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
|
||||
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
|
||||
|
||||
S.Stk.push<IntegralAP<false>>(
|
||||
IntegralAP<false>::from(Ptr.getIntegerRepresentation(), BitWidth));
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC,
|
||||
uint32_t BitWidth) {
|
||||
const Pointer &Ptr = S.Stk.pop<Pointer>();
|
||||
|
||||
if (Ptr.isDummy())
|
||||
return false;
|
||||
|
||||
const SourceInfo &E = S.Current->getSource(OpPC);
|
||||
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
|
||||
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
|
||||
|
||||
S.Stk.push<IntegralAP<true>>(
|
||||
IntegralAP<true>::from(Ptr.getIntegerRepresentation(), BitWidth));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <PrimType Name, class T = typename PrimConv<Name>::T>
|
||||
static inline bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC,
|
||||
uint32_t FPS) {
|
||||
|
@ -1,6 +1,10 @@
|
||||
// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -o - %s -fexperimental-new-constant-interpreter | FileCheck %s
|
||||
|
||||
#ifdef __SIZEOF_INT128__
|
||||
// CHECK: @PR11705 = global i128 0
|
||||
__int128_t PR11705 = (__int128_t)&PR11705;
|
||||
#endif
|
||||
|
||||
int arr[2];
|
||||
// CHECK: @pastEnd = constant ptr getelementptr (i8, ptr @arr, i64 8)
|
||||
|
Loading…
x
Reference in New Issue
Block a user