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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to