https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/111669
Only allow those casts if the bitwidth of the two types match. >From 6d68260682f723fa7a010e2fd381da32316ed5e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Wed, 9 Oct 2024 14:03:39 +0200 Subject: [PATCH] [clang][bytecode] Only allow lossless ptr-to-int casts Only allow those casts if the bitwidth of the two types match. --- clang/lib/AST/ByteCode/Interp.cpp | 41 +++++++++++++++++++++++++++ clang/lib/AST/ByteCode/Interp.h | 43 ++++------------------------- clang/test/AST/ByteCode/codegen.cpp | 4 +++ 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 050de67c2e77dd..82e11743cc5296 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -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) diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 2c5538d221bf0b..41708910024476 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -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) { diff --git a/clang/test/AST/ByteCode/codegen.cpp b/clang/test/AST/ByteCode/codegen.cpp index 12d8b5a5c548e1..ea2c812f30f6f0 100644 --- a/clang/test/AST/ByteCode/codegen.cpp +++ b/clang/test/AST/ByteCode/codegen.cpp @@ -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) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits