llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

This adds an `IntegralKind` to `clang::interp::Integral` (not `IntegralAP` yet).

As a result, the size of such an integral is now different (larger) than that 
of its underlying representation type. 
If the type is now `IntegralKind::Number`, the value of the underlying type is 
used as an internal value for a pointer or an address label difference (similar 
to the existing "native pointer" mechanism in `Program`).

One existing problem is that the IDs we create for address label differences 
can overflow the underlying integral type, e.g. in
```c
int c(void) {
  static char ar1 = &amp;&amp;l2 - &amp;&amp;l1;
l1:
  return 10;
l2:
  return 11;
}
```
we can only save roughly 128 (depending on other saved pointers, etc.) 
variables like `ar1` here, since otherwise the ID we create will overflow the 
8bit size of the underling integral type.

Another unfortunate side-effect is that we need to pass around the `Program` 
instance more often.

---

Patch is 68.23 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/169769.diff


33 Files Affected:

- (modified) clang/lib/AST/ByteCode/Boolean.h (+6-2) 
- (modified) clang/lib/AST/ByteCode/Context.cpp (+8-3) 
- (modified) clang/lib/AST/ByteCode/Descriptor.cpp (+7) 
- (modified) clang/lib/AST/ByteCode/Descriptor.h (+5) 
- (modified) clang/lib/AST/ByteCode/EvalEmitter.cpp (+10-9) 
- (modified) clang/lib/AST/ByteCode/FixedPoint.h (+7-2) 
- (modified) clang/lib/AST/ByteCode/Floating.h (+5-2) 
- (modified) clang/lib/AST/ByteCode/Integral.h (+60-9) 
- (modified) clang/lib/AST/ByteCode/IntegralAP.h (+6-2) 
- (modified) clang/lib/AST/ByteCode/Interp.cpp (+27-15) 
- (modified) clang/lib/AST/ByteCode/Interp.h (+126-24) 
- (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+30-38) 
- (modified) clang/lib/AST/ByteCode/InterpFrame.cpp (+8-6) 
- (modified) clang/lib/AST/ByteCode/InterpHelpers.h (+2-2) 
- (modified) clang/lib/AST/ByteCode/InterpStack.h (+8-16) 
- (modified) clang/lib/AST/ByteCode/MemberPointer.cpp (+3-2) 
- (modified) clang/lib/AST/ByteCode/MemberPointer.h (+4-3) 
- (modified) clang/lib/AST/ByteCode/Pointer.cpp (+24-13) 
- (modified) clang/lib/AST/ByteCode/Pointer.h (+6-5) 
- (modified) clang/lib/AST/ByteCode/PrimType.h (+16) 
- (modified) clang/lib/AST/ByteCode/Primitives.h (+8) 
- (modified) clang/lib/AST/ByteCode/Program.cpp (+18-10) 
- (modified) clang/lib/AST/ByteCode/Program.h (+39) 
- (added) clang/test/AST/ByteCode/addr-label-diff.c (+22) 
- (modified) clang/test/AST/ByteCode/const-eval.c (+3) 
- (modified) clang/test/CodeGen/const-label-addr.c (+1) 
- (modified) clang/test/CodeGen/statements.c (+1) 
- (modified) clang/test/CodeGen/staticinit.c (+1) 
- (modified) clang/test/CodeGenCXX/2008-05-07-CrazyOffsetOf.cpp (+1) 
- (modified) clang/test/CodeGenCXX/const-init-cxx11.cpp (+3) 
- (modified) clang/test/Sema/compound-literal.c (+1) 
- (modified) clang/test/SemaCXX/constexpr-string.cpp (+1) 
- (modified) clang/unittests/AST/ByteCode/toAPValue.cpp (+8-8) 


``````````diff
diff --git a/clang/lib/AST/ByteCode/Boolean.h b/clang/lib/AST/ByteCode/Boolean.h
index fd8d546656881..f04bcd3ba337c 100644
--- a/clang/lib/AST/ByteCode/Boolean.h
+++ b/clang/lib/AST/ByteCode/Boolean.h
@@ -52,10 +52,14 @@ class Boolean final {
   APSInt toAPSInt(unsigned NumBits) const {
     return APSInt(toAPSInt().zextOrTrunc(NumBits), true);
   }
-  APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); }
+  APValue toAPValue(const ASTContext &, const Program &) const {
+    return APValue(toAPSInt());
+  }
 
   Boolean toUnsigned() const { return *this; }
 
+  static IntegralKind getKind() { return IntegralKind::Number; }
+
   constexpr static unsigned bitWidth() { return 1; }
   bool isZero() const { return !V; }
   bool isMin() const { return isZero(); }
@@ -84,7 +88,7 @@ class Boolean final {
   void bitcastToMemory(std::byte *Buff) { std::memcpy(Buff, &V, sizeof(V)); }
 
   void print(llvm::raw_ostream &OS) const { OS << (V ? "true" : "false"); }
-  std::string toDiagnosticString(const ASTContext &Ctx) const {
+  std::string toDiagnosticString(const ASTContext &Ctx, const Program &) const 
{
     std::string NameStr;
     llvm::raw_string_ostream OS(NameStr);
     print(OS);
diff --git a/clang/lib/AST/ByteCode/Context.cpp 
b/clang/lib/AST/ByteCode/Context.cpp
index 208fcb2a2732e..2a777025035b8 100644
--- a/clang/lib/AST/ByteCode/Context.cpp
+++ b/clang/lib/AST/ByteCode/Context.cpp
@@ -186,7 +186,7 @@ bool Context::evaluateStringRepr(State &Parent, const Expr 
*SizeExpr,
       return false;
 
     // Must be char.
-    if (Ptr.getFieldDesc()->getElemSize() != 1 /*bytes*/)
+    if (Ptr.getFieldDesc()->getElemDataSize() != 1 /*bytes*/)
       return false;
 
     if (Size > Ptr.getNumElems()) {
@@ -199,7 +199,7 @@ bool Context::evaluateStringRepr(State &Parent, const Expr 
*SizeExpr,
       Result = APValue(APValue::UninitArray{}, Size, Size);
       for (uint64_t I = 0; I != Size; ++I) {
         if (std::optional<APValue> ElemVal =
-                Ptr.atIndex(I).toRValue(*this, CharTy))
+                Ptr.atIndex(I).toRValue(*this, CharTy, *P))
           Result.getArrayInitializedElt(I) = *ElemVal;
         else
           return false;
@@ -208,7 +208,12 @@ bool Context::evaluateStringRepr(State &Parent, const Expr 
*SizeExpr,
       assert((std::is_same_v<ResultT, std::string>));
       if (Size < Result.max_size())
         Result.resize(Size);
-      Result.assign(reinterpret_cast<const char *>(Ptr.getRawAddress()), Size);
+      unsigned StartIndex = Ptr.getIndex();
+      for (uint64_t I = 0; I != Size; ++I) {
+        FIXED_SIZE_INT_TYPE_SWITCH(Ptr.getFieldDesc()->getPrimType(), {
+          Result[I] = static_cast<char>(Ptr.elem<T>(StartIndex + I));
+        });
+      }
     }
 
     return true;
diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp 
b/clang/lib/AST/ByteCode/Descriptor.cpp
index a3cee034191d2..57bd9e8f0646c 100644
--- a/clang/lib/AST/ByteCode/Descriptor.cpp
+++ b/clang/lib/AST/ByteCode/Descriptor.cpp
@@ -481,3 +481,10 @@ bool Descriptor::hasTrivialDtor() const {
 }
 
 bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); 
}
+
+unsigned Descriptor::getElemDataSize() const {
+  if ((isPrimitive() || isPrimitiveArray()) && isIntegralType(getPrimType())) {
+    FIXED_SIZE_INT_TYPE_SWITCH(getPrimType(), { return T::bitWidth() / 8; });
+  }
+  return ElemSize;
+}
diff --git a/clang/lib/AST/ByteCode/Descriptor.h 
b/clang/lib/AST/ByteCode/Descriptor.h
index 5bf550ffe1172..88fc490d69ac9 100644
--- a/clang/lib/AST/ByteCode/Descriptor.h
+++ b/clang/lib/AST/ByteCode/Descriptor.h
@@ -242,6 +242,11 @@ struct Descriptor final {
   unsigned getAllocSize() const { return AllocSize; }
   /// returns the size of an element when the structure is viewed as an array.
   unsigned getElemSize() const { return ElemSize; }
+  /// Returns the element data size, i.e. not what the size of
+  /// our primitive data type is, but what the data size of that is.
+  /// E.g., for PT_SInt32, that's 4 bytes.
+  unsigned getElemDataSize() const;
+
   /// Returns the size of the metadata.
   unsigned getMetadataSize() const { return MDSize; }
 
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp 
b/clang/lib/AST/ByteCode/EvalEmitter.cpp
index cf3cc1b17133c..afda7e2047c09 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.cpp
+++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp
@@ -184,7 +184,7 @@ template <PrimType OpType> bool 
EvalEmitter::emitRet(SourceInfo Info) {
     return true;
 
   using T = typename PrimConv<OpType>::T;
-  EvalResult.takeValue(S.Stk.pop<T>().toAPValue(Ctx.getASTContext()));
+  EvalResult.takeValue(S.Stk.pop<T>().toAPValue(Ctx.getASTContext(), S.P));
   return true;
 }
 
@@ -195,7 +195,7 @@ template <> bool EvalEmitter::emitRet<PT_Ptr>(SourceInfo 
Info) {
   const Pointer &Ptr = S.Stk.pop<Pointer>();
 
   if (Ptr.isFunctionPointer()) {
-    EvalResult.takeValue(Ptr.toAPValue(Ctx.getASTContext()));
+    EvalResult.takeValue(Ptr.toAPValue(Ctx.getASTContext(), S.P));
     return true;
   }
 
@@ -226,7 +226,7 @@ template <> bool EvalEmitter::emitRet<PT_Ptr>(SourceInfo 
Info) {
       return false;
 
     if (std::optional<APValue> V =
-            Ptr.toRValue(Ctx, EvalResult.getSourceType())) {
+            Ptr.toRValue(Ctx, EvalResult.getSourceType(), P)) {
       EvalResult.takeValue(std::move(*V));
     } else {
       return false;
@@ -236,14 +236,14 @@ template <> bool EvalEmitter::emitRet<PT_Ptr>(SourceInfo 
Info) {
     // the result, even if the pointer is dead.
     // This will later be diagnosed by CheckLValueConstantExpression.
     if (Ptr.isBlockPointer() && !Ptr.block()->isStatic()) {
-      EvalResult.takeValue(Ptr.toAPValue(Ctx.getASTContext()));
+      EvalResult.takeValue(Ptr.toAPValue(Ctx.getASTContext(), S.P));
       return true;
     }
 
     if (!Ptr.isLive() && !Ptr.isTemporary())
       return false;
 
-    EvalResult.takeValue(Ptr.toAPValue(Ctx.getASTContext()));
+    EvalResult.takeValue(Ptr.toAPValue(Ctx.getASTContext(), S.P));
   }
 
   return true;
@@ -263,7 +263,7 @@ bool EvalEmitter::emitRetValue(SourceInfo Info) {
     return false;
 
   if (std::optional<APValue> APV =
-          Ptr.toRValue(S.getASTContext(), EvalResult.getSourceType())) {
+          Ptr.toRValue(S.getASTContext(), EvalResult.getSourceType(), P)) {
     EvalResult.takeValue(std::move(*APV));
     return true;
   }
@@ -362,11 +362,12 @@ void EvalEmitter::updateGlobalTemporaries() {
     const Pointer &Ptr = P.getPtrGlobal(*GlobalIndex);
     APValue *Cached = Temp->getOrCreateValue(true);
     if (OptPrimType T = Ctx.classify(E->getType())) {
-      TYPE_SWITCH(*T,
-                  { *Cached = Ptr.deref<T>().toAPValue(Ctx.getASTContext()); 
});
+      TYPE_SWITCH(*T, {
+        *Cached = Ptr.deref<T>().toAPValue(Ctx.getASTContext(), S.P);
+      });
     } else {
       if (std::optional<APValue> APV =
-              Ptr.toRValue(Ctx, Temp->getTemporaryExpr()->getType()))
+              Ptr.toRValue(Ctx, Temp->getTemporaryExpr()->getType(), P))
         *Cached = *APV;
     }
   }
diff --git a/clang/lib/AST/ByteCode/FixedPoint.h 
b/clang/lib/AST/ByteCode/FixedPoint.h
index fcb3c79cc1097..694b541c14cb5 100644
--- a/clang/lib/AST/ByteCode/FixedPoint.h
+++ b/clang/lib/AST/ByteCode/FixedPoint.h
@@ -13,6 +13,8 @@
 #include "clang/AST/ComparisonCategories.h"
 #include "llvm/ADT/APFixedPoint.h"
 
+#include "Program.h"
+
 namespace clang {
 namespace interp {
 
@@ -49,7 +51,9 @@ class FixedPoint final {
   operator bool() const { return V.getBoolValue(); }
   void print(llvm::raw_ostream &OS) const { OS << V; }
 
-  APValue toAPValue(const ASTContext &) const { return APValue(V); }
+  APValue toAPValue(const ASTContext &, const Program &) const {
+    return APValue(V);
+  }
   APSInt toAPSInt(unsigned BitWidth = 0) const { return V.getValue(); }
 
   unsigned bitWidth() const { return V.getWidth(); }
@@ -78,9 +82,10 @@ class FixedPoint final {
     return V.convertToInt(BitWidth, Signed, Overflow);
   }
 
-  std::string toDiagnosticString(const ASTContext &Ctx) const {
+  std::string toDiagnosticString(const ASTContext &Ctx, const Program &) const 
{
     return V.toString();
   }
+  static IntegralKind getKind() { return IntegralKind::Number; }
 
   ComparisonCategoryResult compare(const FixedPoint &Other) const {
     int c = V.compare(Other.V);
diff --git a/clang/lib/AST/ByteCode/Floating.h 
b/clang/lib/AST/ByteCode/Floating.h
index cc918dc12deb6..149133a535953 100644
--- a/clang/lib/AST/ByteCode/Floating.h
+++ b/clang/lib/AST/ByteCode/Floating.h
@@ -14,6 +14,7 @@
 #define LLVM_CLANG_AST_INTERP_FLOATING_H
 
 #include "Primitives.h"
+#include "Program.h"
 #include "clang/AST/APValue.h"
 #include "llvm/ADT/APFloat.h"
 
@@ -86,14 +87,16 @@ class Floating final {
   APSInt toAPSInt(unsigned NumBits = 0) const {
     return APSInt(getValue().bitcastToAPInt());
   }
-  APValue toAPValue(const ASTContext &) const { return APValue(getValue()); }
+  APValue toAPValue(const ASTContext &, const Program &) const {
+    return APValue(getValue());
+  }
   void print(llvm::raw_ostream &OS) const {
     // Can't use APFloat::print() since it appends a newline.
     SmallVector<char, 16> Buffer;
     getValue().toString(Buffer);
     OS << Buffer;
   }
-  std::string toDiagnosticString(const ASTContext &Ctx) const {
+  std::string toDiagnosticString(const ASTContext &Ctx, const Program &) const 
{
     std::string NameStr;
     llvm::raw_string_ostream OS(NameStr);
     print(OS);
diff --git a/clang/lib/AST/ByteCode/Integral.h 
b/clang/lib/AST/ByteCode/Integral.h
index e90f1a9a74e1c..d86f04c3afa8e 100644
--- a/clang/lib/AST/ByteCode/Integral.h
+++ b/clang/lib/AST/ByteCode/Integral.h
@@ -14,6 +14,7 @@
 #define LLVM_CLANG_AST_INTERP_INTEGRAL_H
 
 #include "clang/AST/APValue.h"
+#include "clang/AST/CharUnits.h"
 #include "clang/AST/ComparisonCategories.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/Support/MathExtras.h"
@@ -22,6 +23,7 @@
 #include <cstdint>
 
 #include "Primitives.h"
+#include "Program.h"
 
 namespace clang {
 namespace interp {
@@ -69,8 +71,9 @@ template <unsigned Bits, bool Signed> class Integral final {
 
   // The primitive representing the integral.
   using ReprT = typename Repr<Bits, Signed>::Type;
-  ReprT V;
   static_assert(std::is_trivially_copyable_v<ReprT>);
+  ReprT V;
+  IntegralKind Kind = IntegralKind::Number;
 
   /// Primitive representing limits.
   static const auto Min = std::numeric_limits<ReprT>::min();
@@ -78,6 +81,8 @@ template <unsigned Bits, bool Signed> class Integral final {
 
   /// Construct an integral from anything that is convertible to storage.
   template <typename T> explicit Integral(T V) : V(V) {}
+  template <typename T>
+  explicit Integral(IntegralKind Kind, T V) : V(V), Kind(Kind) {}
 
 public:
   using AsUnsigned = Integral<Bits, false>;
@@ -87,7 +92,9 @@ template <unsigned Bits, bool Signed> class Integral final {
 
   /// Constructs an integral from another integral.
   template <unsigned SrcBits, bool SrcSign>
-  explicit Integral(Integral<SrcBits, SrcSign> V) : V(V.V) {}
+  explicit Integral(Integral<SrcBits, SrcSign> V) : V(V.V), Kind(V.Kind) {}
+
+  IntegralKind getKind() const { return Kind; }
 
   /// Construct an integral from a value based on signedness.
   explicit Integral(const APSInt &V)
@@ -115,7 +122,7 @@ template <unsigned Bits, bool Signed> class Integral final {
 
   template <unsigned DstBits, bool DstSign>
   explicit operator Integral<DstBits, DstSign>() const {
-    return Integral<DstBits, DstSign>(V);
+    return Integral<DstBits, DstSign>(Kind, V);
   }
 
   template <typename Ty, typename = std::enable_if_t<std::is_integral_v<Ty>>>
@@ -137,7 +144,35 @@ template <unsigned Bits, bool Signed> class Integral final 
{
       return APInt(Bits, static_cast<uint64_t>(V), Signed)
           .zextOrTrunc(BitWidth);
   }
-  APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); }
+  APValue toAPValue(const ASTContext &, const Program &P) const {
+    switch (Kind) {
+    case IntegralKind::Address: {
+      const ValueDecl *VD =
+          reinterpret_cast<const ValueDecl *>(P.getNativePointer(V));
+      return APValue(VD, CharUnits::Zero(), APValue::NoLValuePath{});
+    }
+    case IntegralKind::LabelAddress: {
+      const Expr *VD = reinterpret_cast<const Expr *>(P.getNativePointer(V));
+      return APValue(VD, CharUnits::Zero(), APValue::NoLValuePath{});
+    }
+    case IntegralKind::BlockAddress: {
+      const Block *B = reinterpret_cast<const Block *>(P.getNativePointer(V));
+      const Descriptor *D = B->getDescriptor();
+      if (const Expr *E = D->asExpr())
+        return APValue(E, CharUnits::Zero(), APValue::NoLValuePath{});
+
+      return APValue(D->asValueDecl(), CharUnits::Zero(),
+                     APValue::NoLValuePath{});
+    }
+    case IntegralKind::AddrLabelDiff: {
+      AddrLabelDiff ALD = P.getLabelDiff(V);
+      return APValue(ALD.LHS, ALD.RHS);
+    }
+    case IntegralKind::Number:
+      return APValue(toAPSInt());
+    }
+    llvm_unreachable("Unhandled IntegralKind");
+  }
 
   Integral<Bits, false> toUnsigned() const {
     return Integral<Bits, false>(*this);
@@ -172,7 +207,7 @@ template <unsigned Bits, bool Signed> class Integral final {
     return Integral(V);
   }
 
-  std::string toDiagnosticString(const ASTContext &Ctx) const {
+  std::string toDiagnosticString(const ASTContext &Ctx, const Program &) const 
{
     std::string NameStr;
     llvm::raw_string_ostream OS(NameStr);
     OS << V;
@@ -198,14 +233,25 @@ template <unsigned Bits, bool Signed> class Integral 
final {
     return Integral((V & BitMask) | (Signed && (V & SignBit) ? ExtMask : 0));
   }
 
-  void print(llvm::raw_ostream &OS) const { OS << V; }
+  void print(llvm::raw_ostream &OS) const {
+    OS << V;
+    if (Kind == IntegralKind::Address)
+      OS << " (Address)";
+    else if (Kind == IntegralKind::BlockAddress)
+      OS << " (BlockAddress)";
+    else if (Kind == IntegralKind::LabelAddress)
+      OS << " (LabelAddress)";
+    else if (Kind == IntegralKind::AddrLabelDiff)
+      OS << " (LabelAddrDiff)";
+  }
 
   static Integral min(unsigned NumBits) { return Integral(Min); }
   static Integral max(unsigned NumBits) { return Integral(Max); }
   static Integral zero(unsigned BitWidth = 0) { return from(0); }
 
   template <typename ValT>
-  static Integral from(ValT Value, unsigned NumBits = 0) {
+  static std::enable_if_t<!std::is_same_v<ValT, IntegralKind>, Integral>
+  from(ValT Value, unsigned NumBits = 0) {
     if constexpr (std::is_integral_v<ValT>)
       return Integral(Value);
     else
@@ -213,8 +259,13 @@ template <unsigned Bits, bool Signed> class Integral final 
{
   }
 
   template <unsigned SrcBits, bool SrcSign>
-  static Integral from(Integral<SrcBits, SrcSign> Value) {
-    return Integral(Value.V);
+  static std::enable_if_t<SrcBits != 0, Integral>
+  from(Integral<SrcBits, SrcSign> Value) {
+    return Integral(Value.Kind, Value.V);
+  }
+
+  template <typename T> static Integral from(IntegralKind Kind, T Value) {
+    return Integral(Kind, Value);
   }
 
   static bool increment(Integral A, Integral *R) {
diff --git a/clang/lib/AST/ByteCode/IntegralAP.h 
b/clang/lib/AST/ByteCode/IntegralAP.h
index b11e6eea28e3f..b14951559fd2a 100644
--- a/clang/lib/AST/ByteCode/IntegralAP.h
+++ b/clang/lib/AST/ByteCode/IntegralAP.h
@@ -22,6 +22,7 @@
 #include <cstdint>
 
 #include "Primitives.h"
+#include "Program.h"
 
 namespace clang {
 namespace interp {
@@ -150,7 +151,9 @@ template <bool Signed> class IntegralAP final {
     else
       return APSInt(getValue().zext(Bits), !Signed);
   }
-  APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); }
+  APValue toAPValue(const ASTContext &, const Program &) const {
+    return APValue(toAPSInt());
+  }
 
   bool isZero() const { return getValue().isZero(); }
   bool isPositive() const {
@@ -179,12 +182,13 @@ template <bool Signed> class IntegralAP final {
   unsigned countLeadingZeros() const { return getValue().countl_zero(); }
 
   void print(llvm::raw_ostream &OS) const { getValue().print(OS, Signed); }
-  std::string toDiagnosticString(const ASTContext &Ctx) const {
+  std::string toDiagnosticString(const ASTContext &Ctx, const Program &) const 
{
     std::string NameStr;
     llvm::raw_string_ostream OS(NameStr);
     print(OS);
     return NameStr;
   }
+  static IntegralKind getKind() { return IntegralKind::Number; }
 
   IntegralAP truncate(unsigned BitWidth) const {
     if constexpr (Signed)
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index 0205d840fd71e..b26485a937da6 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1180,7 +1180,7 @@ bool CheckDeleteSource(InterpState &S, CodePtr OpPC, 
const Expr *Source,
   // Whatever this is, we didn't heap allocate it.
   const SourceInfo &Loc = S.Current->getSource(OpPC);
   S.FFDiag(Loc, diag::note_constexpr_delete_not_heap_alloc)
-      << Ptr.toDiagnosticString(S.getASTContext());
+      << Ptr.toDiagnosticString(S.getASTContext(), S.P);
 
   if (Ptr.isTemporary())
     S.Note(Ptr.getDeclLoc(), diag::note_constexpr_temporary_here);
@@ -1352,7 +1352,8 @@ bool Free(InterpState &S, CodePtr OpPC, bool 
DeleteIsArrayForm,
         (Ptr.isArrayElement() && Ptr.getIndex() != 0)) {
       const SourceInfo &Loc = S.Current->getSource(OpPC);
       S.FFDiag(Loc, diag::note_constexpr_delete_subobject)
-          << Ptr.toDiagnosticString(S.getASTContext()) << Ptr.isOnePastEnd();
+          << Ptr.toDiagnosticString(S.getASTContext(), S.P)
+          << Ptr.isOnePastEnd();
       return false;
     }
 
@@ -1480,7 +1481,7 @@ static bool getField(InterpState &S, CodePtr OpPC, const 
Pointer &Ptr,
     // `typeid(int).name`, but we currently diagnose `&typeid(int)`.
     S.FFDiag(S.Current->getSource(OpPC),
              diag::note_constexpr_access_unreadable_object)
-        << AK_Read << Ptr.toDiagnosticString(S.getASTContext());
+        << AK_Read << Ptr.toDiagnosticString(S.getASTContext(), S.P);
     return false;
   }
 
@@ -1717,7 +1718,7 @@ static bool GetDynamicDecl(InterpState &S, CodePtr OpPC, 
Pointer TypePtr,
     if (const VarDecl *VD = TypePtr.getDeclDesc()->asVarDecl();
         VD && !VD->isConstexpr()) {
       const Expr *E = S.Current->getExpr(OpPC);
-      APValue V = TypePtr.toAPValue(S.getASTContext());
+      APValue V = TypePtr.toAPValue(S.getASTContext(), S.P);
       QualType TT = S.getASTContext().getLValueReferenceType(DynamicType);
       S.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
           << AccessKinds::AK_MemberCall << V.getAsString(S.getASTContext(), 
TT);
@@ -2113,10 +2114,10 @@ bool handleFixedPointOverflow(InterpState &S, CodePtr 
OpPC,
   if (S.checkingForUndefinedBehavior()) {
     S.getASTContext().getDiagnostics().Report(
         E->getExprLoc(), diag::warn_fixedpoint_constant_overflow)
-        << FP.toDiagnosticString(S.getASTContext()) << E->getType();
+        << FP.toDiagnosticString(S.getASTContext(), S.P) << E->getType();
   }
   S.CCEDiag(E, diag::note_constexpr_overflow)
-      << FP.toDiagnosticString(S.getASTContext()) << E->getType();
+      << FP.toDiagnosticString(S.getASTContext(), S.P) << E->getType();
   return S.noteUndefinedBehavior();
 }
 
@@ -2134,12 +2135,12 @@ bool CheckPointerToIntegralCast(InterpState &S, CodePtr 
OpPC,
   S.CCEDiag(E, diag::note_constexpr_invalid_cast)
       << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
 
-  if (Ptr.isDummy())
+  if (Ptr.isDummy() && !Ptr.pointsToLabel())
     return false;
-  if (Ptr.isFunctionPointer())
+  if (Ptr.isIntegralPointer())
     return true;
 
-  if (Ptr.isBlockPointer() && !Ptr.isZero()) {
+  if (!Ptr.isZero()) {
     // Only allow based lvalue casts if they are lossless.
     if (S.getASTContext().getTargetInfo().getPointerWidth(LangAS::Default) !=
         BitWidth)
@@ -2148,6 +2149,11 @@ bool CheckPointerToIntegralCast(InterpState &S, CodePtr 
OpPC,
   return true;
 }
 
+bool CheckIntegralAddressCast(InterpState &S, CodePtr OpPC, unsigned BitWidth) 
{
+  return (S.getASTContext().getTargetInfo().getPointerWidth(LangAS::Default) ==
+          BitWidth);
+}
+
 bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
   const Pointer &Ptr = S.Stk.pop<Pointer>();
 
@@ -2233,13 +2239,19 @@ bool DiagTypeid(InterpState &S, CodePtr OpPC) {
 
 bool arePotentiallyOverlappingStringLiterals(const Poin...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/169769
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to