Skip to content

Commit b8f5e3c

Browse files
authored
[clang][bytecode] Diagnose PointerToIntegral casts (llvm#137444)
Always emit the diagnostic, but permit the cast.
1 parent 3bc1254 commit b8f5e3c

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

clang/lib/AST/ByteCode/Interp.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2362,8 +2362,12 @@ template <PrimType Name, class T = typename PrimConv<Name>::T>
23622362
bool CastPointerIntegral(InterpState &S, CodePtr OpPC) {
23632363
const Pointer &Ptr = S.Stk.pop<Pointer>();
23642364

2365+
S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_invalid_cast)
2366+
<< diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
2367+
<< S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
2368+
23652369
if (!CheckPointerToIntegralCast(S, OpPC, Ptr, T::bitWidth()))
2366-
return false;
2370+
return Invalid(S, OpPC);
23672371

23682372
S.Stk.push<T>(T::from(Ptr.getIntegerRepresentation()));
23692373
return true;

clang/test/AST/ByteCode/cxx11.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,15 @@ namespace PseudoDtor {
221221
static_assert(f() == 0, ""); // both-error {{constant expression}} \
222222
// expected-note {{in call to}}
223223
}
224+
225+
namespace IntToPtrCast {
226+
typedef __INTPTR_TYPE__ intptr_t;
227+
228+
constexpr intptr_t f(intptr_t x) {
229+
return (((x) >> 21) * 8);
230+
}
231+
232+
extern "C" int foo;
233+
constexpr intptr_t i = f((intptr_t)&foo - 10); // both-error{{constexpr variable 'i' must be initialized by a constant expression}} \
234+
// both-note{{reinterpret_cast}}
235+
}

0 commit comments

Comments
 (0)