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 = &&l2 - &&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