[clang] [clang][bytecode] Only allow lossless ptr-to-int casts (PR #111669)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 9 05:28:50 PDT 2024
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?= <tbaeder at 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)
More information about the cfe-commits
mailing list