[clang][bytecode] Diagnose PointerToIntegral casts (#137444)
Always emit the diagnostic, but permit the cast.
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index e2f2e73..63a1f3e 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2362,8 +2362,12 @@
bool CastPointerIntegral(InterpState &S, CodePtr OpPC) {
const Pointer &Ptr = S.Stk.pop<Pointer>();
+ S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_invalid_cast)
+ << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
+ << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
+
if (!CheckPointerToIntegralCast(S, OpPC, Ptr, T::bitWidth()))
- return false;
+ return Invalid(S, OpPC);
S.Stk.push<T>(T::from(Ptr.getIntegerRepresentation()));
return true;
diff --git a/clang/test/AST/ByteCode/cxx11.cpp b/clang/test/AST/ByteCode/cxx11.cpp
index 1880680..88e195c 100644
--- a/clang/test/AST/ByteCode/cxx11.cpp
+++ b/clang/test/AST/ByteCode/cxx11.cpp
@@ -221,3 +221,15 @@
static_assert(f() == 0, ""); // both-error {{constant expression}} \
// expected-note {{in call to}}
}
+
+namespace IntToPtrCast {
+ typedef __INTPTR_TYPE__ intptr_t;
+
+ constexpr intptr_t f(intptr_t x) {
+ return (((x) >> 21) * 8);
+ }
+
+ extern "C" int foo;
+ constexpr intptr_t i = f((intptr_t)&foo - 10); // both-error{{constexpr variable 'i' must be initialized by a constant expression}} \
+ // both-note{{reinterpret_cast}}
+}