Skip to content

Commit e637a5c

Browse files
authored
[clang][bytecode] Only allow lossless ptr-to-int casts (#111669)
Only allow those casts if the bitwidth of the two types match.
1 parent 1731bb7 commit e637a5c

File tree

3 files changed

+51
-37
lines changed

3 files changed

+51
-37
lines changed

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "clang/AST/Expr.h"
2323
#include "clang/AST/ExprCXX.h"
2424
#include "clang/Basic/DiagnosticSema.h"
25+
#include "clang/Basic/TargetInfo.h"
2526
#include "llvm/ADT/APSInt.h"
2627
#include "llvm/ADT/StringExtras.h"
2728
#include <limits>
@@ -1415,6 +1416,46 @@ bool InvalidShuffleVectorIndex(InterpState &S, CodePtr OpPC, uint32_t Index) {
14151416
return false;
14161417
}
14171418

1419+
bool CheckPointerToIntegralCast(InterpState &S, CodePtr OpPC,
1420+
const Pointer &Ptr, unsigned BitWidth) {
1421+
if (Ptr.isDummy())
1422+
return false;
1423+
1424+
const SourceInfo &E = S.Current->getSource(OpPC);
1425+
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
1426+
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
1427+
1428+
if (Ptr.isBlockPointer() && !Ptr.isZero()) {
1429+
// Only allow based lvalue casts if they are lossless.
1430+
if (S.getASTContext().getTargetInfo().getPointerWidth(LangAS::Default) !=
1431+
BitWidth)
1432+
return Invalid(S, OpPC);
1433+
}
1434+
return true;
1435+
}
1436+
1437+
bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
1438+
const Pointer &Ptr = S.Stk.pop<Pointer>();
1439+
1440+
if (!CheckPointerToIntegralCast(S, OpPC, Ptr, BitWidth))
1441+
return false;
1442+
1443+
S.Stk.push<IntegralAP<false>>(
1444+
IntegralAP<false>::from(Ptr.getIntegerRepresentation(), BitWidth));
1445+
return true;
1446+
}
1447+
1448+
bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
1449+
const Pointer &Ptr = S.Stk.pop<Pointer>();
1450+
1451+
if (!CheckPointerToIntegralCast(S, OpPC, Ptr, BitWidth))
1452+
return false;
1453+
1454+
S.Stk.push<IntegralAP<true>>(
1455+
IntegralAP<true>::from(Ptr.getIntegerRepresentation(), BitWidth));
1456+
return true;
1457+
}
1458+
14181459
// https://github.com/llvm/llvm-project/issues/102513
14191460
#if defined(_WIN32) && !defined(__clang__) && !defined(NDEBUG)
14201461
#pragma optimize("", off)

clang/lib/AST/ByteCode/Interp.h

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,53 +2289,22 @@ static inline bool CastFloatingIntegralAPS(InterpState &S, CodePtr OpPC,
22892289
return CheckFloatResult(S, OpPC, F, Status, FPO);
22902290
}
22912291

2292+
bool CheckPointerToIntegralCast(InterpState &S, CodePtr OpPC,
2293+
const Pointer &Ptr, unsigned BitWidth);
2294+
bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth);
2295+
bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth);
2296+
22922297
template <PrimType Name, class T = typename PrimConv<Name>::T>
22932298
bool CastPointerIntegral(InterpState &S, CodePtr OpPC) {
22942299
const Pointer &Ptr = S.Stk.pop<Pointer>();
22952300

2296-
if (Ptr.isDummy())
2301+
if (!CheckPointerToIntegralCast(S, OpPC, Ptr, T::bitWidth()))
22972302
return false;
22982303

2299-
const SourceInfo &E = S.Current->getSource(OpPC);
2300-
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
2301-
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
2302-
23032304
S.Stk.push<T>(T::from(Ptr.getIntegerRepresentation()));
23042305
return true;
23052306
}
23062307

2307-
static inline bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC,
2308-
uint32_t BitWidth) {
2309-
const Pointer &Ptr = S.Stk.pop<Pointer>();
2310-
2311-
if (Ptr.isDummy())
2312-
return false;
2313-
2314-
const SourceInfo &E = S.Current->getSource(OpPC);
2315-
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
2316-
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
2317-
2318-
S.Stk.push<IntegralAP<false>>(
2319-
IntegralAP<false>::from(Ptr.getIntegerRepresentation(), BitWidth));
2320-
return true;
2321-
}
2322-
2323-
static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC,
2324-
uint32_t BitWidth) {
2325-
const Pointer &Ptr = S.Stk.pop<Pointer>();
2326-
2327-
if (Ptr.isDummy())
2328-
return false;
2329-
2330-
const SourceInfo &E = S.Current->getSource(OpPC);
2331-
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
2332-
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
2333-
2334-
S.Stk.push<IntegralAP<true>>(
2335-
IntegralAP<true>::from(Ptr.getIntegerRepresentation(), BitWidth));
2336-
return true;
2337-
}
2338-
23392308
template <PrimType Name, class T = typename PrimConv<Name>::T>
23402309
static inline bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC,
23412310
uint32_t FPS) {

clang/test/AST/ByteCode/codegen.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -o - %s | FileCheck %s
22
// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -o - %s -fexperimental-new-constant-interpreter | FileCheck %s
33

4+
#ifdef __SIZEOF_INT128__
5+
// CHECK: @PR11705 = global i128 0
6+
__int128_t PR11705 = (__int128_t)&PR11705;
7+
#endif
48

59
int arr[2];
610
// CHECK: @pastEnd = constant ptr getelementptr (i8, ptr @arr, i64 8)

0 commit comments

Comments
 (0)