tbaeder updated this revision to Diff 474930.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D137706/new/
https://reviews.llvm.org/D137706
Files:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/Opcodes.td
clang/lib/AST/Interp/Pointer.cpp
clang/lib/AST/Interp/Pointer.h
clang/test/Sema/const-eval-64.c
Index: clang/test/Sema/const-eval-64.c
===================================================================
--- clang/test/Sema/const-eval-64.c
+++ clang/test/Sema/const-eval-64.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux -fexperimental-new-constant-interpreter %s
#define EVAL_EXPR(testno, expr) int test##testno = sizeof(struct{char qq[expr];});
Index: clang/lib/AST/Interp/Pointer.h
===================================================================
--- clang/lib/AST/Interp/Pointer.h
+++ clang/lib/AST/Interp/Pointer.h
@@ -67,6 +67,7 @@
Pointer() {}
Pointer(Block *B);
Pointer(Block *B, unsigned BaseAndOffset);
+ Pointer(unsigned Offset);
Pointer(const Pointer &P);
Pointer(Pointer &&P);
~Pointer();
@@ -79,6 +80,8 @@
/// Offsets a pointer inside an array.
Pointer atIndex(unsigned Idx) const {
+ if (!Pointee)
+ return Pointer(nullptr, 0, Offset + Idx);
if (Base == RootPtrMark)
return Pointer(Pointee, RootPtrMark, getDeclDesc()->getSize());
unsigned Off = Idx * elemSize();
@@ -160,14 +163,17 @@
}
/// Checks if the pointer is null.
- bool isZero() const { return Pointee == nullptr; }
+ bool isZero() const { return Pointee == nullptr && Offset == 0; }
/// Checks if the pointer is live.
bool isLive() const { return Pointee && !Pointee->IsDead; }
/// Checks if the item is a field in an object.
bool isField() const { return Base != 0 && Base != RootPtrMark; }
/// Accessor for information about the declaration site.
- Descriptor *getDeclDesc() const { return Pointee->Desc; }
+ Descriptor *getDeclDesc() const {
+ assert(Pointee);
+ return Pointee->Desc;
+ }
SourceLocation getDeclLoc() const { return getDeclDesc()->getLocation(); }
/// Returns a pointer to the object of which this pointer is a field.
@@ -232,12 +238,12 @@
}
/// Checks if the innermost field is an array.
- bool inArray() const { return getFieldDesc()->IsArray; }
+ bool inArray() const { return Pointee ? getFieldDesc()->IsArray : false; }
/// Checks if the structure is a primitive array.
bool inPrimitiveArray() const { return getFieldDesc()->isPrimitiveArray(); }
/// Checks if the structure is an array of unknown size.
bool isUnknownSizeArray() const {
- return getFieldDesc()->isUnknownSizeArray();
+ return Pointee ? getFieldDesc()->isUnknownSizeArray() : false;
}
/// Checks if the pointer points to an array.
bool isArrayElement() const { return Base != Offset; }
@@ -288,12 +294,20 @@
}
/// Returns the number of elements.
- unsigned getNumElems() const { return getSize() / elemSize(); }
+ unsigned getNumElems() const {
+ if (Pointee)
+ return getSize() / elemSize();
+
+ return std::numeric_limits<unsigned>::max();
+ }
Block *block() const { return Pointee; }
/// Returns the index into an array.
int64_t getIndex() const {
+ if (!Pointee)
+ return 0;
+
if (isElementPastEnd())
return 1;
if (auto ElemSize = elemSize())
@@ -307,7 +321,7 @@
}
/// Checks if the pointer is an out-of-bounds element pointer.
- bool isElementPastEnd() const { return Offset == PastEndMark; }
+ bool isElementPastEnd() const { return Pointee && Offset == PastEndMark; }
/// Dereferences the pointer, if it's live.
template <typename T> T &deref() const {
Index: clang/lib/AST/Interp/Pointer.cpp
===================================================================
--- clang/lib/AST/Interp/Pointer.cpp
+++ clang/lib/AST/Interp/Pointer.cpp
@@ -19,6 +19,8 @@
Pointer::Pointer(Block *Pointee, unsigned BaseAndOffset)
: Pointer(Pointee, BaseAndOffset, BaseAndOffset) {}
+Pointer::Pointer(unsigned Offset) : Pointer(nullptr, 0, Offset) {}
+
Pointer::Pointer(const Pointer &P) : Pointer(P.Pointee, P.Base, P.Offset) {}
Pointer::Pointer(Pointer &&P)
Index: clang/lib/AST/Interp/Opcodes.td
===================================================================
--- clang/lib/AST/Interp/Opcodes.td
+++ clang/lib/AST/Interp/Opcodes.td
@@ -522,6 +522,11 @@
let HasGroup = 1;
}
+def CastIntegralPointer : Opcode {
+ let Types = [AluTypeClass];
+ let HasGroup = 1;
+}
+
//===----------------------------------------------------------------------===//
// Comparison opcodes.
//===----------------------------------------------------------------------===//
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -1250,6 +1250,13 @@
return CheckFloatResult(S, OpPC, Status);
}
+template <PrimType Name, class T = typename PrimConv<Name>::T>
+bool CastIntegralPointer(InterpState &S, CodePtr OpPC) {
+ const T &Src = S.Stk.pop<T>();
+ S.Stk.push<Pointer>(Pointer(static_cast<unsigned>(Src)));
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// Zero, Nullptr
//===----------------------------------------------------------------------===//
Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -165,6 +165,17 @@
return this->emitCastFloatingIntegral(*ToT, RM, CE);
}
+ case CK_NullToPointer:
+ case CK_IntegralToPointer: {
+ if (isa<CXXNullPtrLiteralExpr>(SubExpr))
+ return this->visit(SubExpr);
+
+ if (!this->visit(SubExpr))
+ return false;
+
+ return this->emitCastIntegralPointer(classifyPrim(SubExpr->getType()), CE);
+ }
+
case CK_ArrayToPointerDecay:
case CK_AtomicToNonAtomic:
case CK_ConstructorConversion:
@@ -172,10 +183,14 @@
case CK_NonAtomicToAtomic:
case CK_NoOp:
case CK_UserDefinedConversion:
- case CK_NullToPointer:
return this->visit(SubExpr);
case CK_IntegralToBoolean:
+ // == in C
+ if (const auto *BOP = dyn_cast<BinaryOperator>(SubExpr);
+ BOP && BOP->isEqualityOp())
+ return this->visit(SubExpr);
+ [[fallthrough]];
case CK_IntegralCast: {
Optional<PrimType> FromT = classify(SubExpr->getType());
Optional<PrimType> ToT = classify(CE->getType());
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits