Repository: llvm/llvm-project
File: clang/lib/AST/ByteCode/InterpBuiltin.cpp (C++)

Code before:
    return std::nullopt;

  // According to the GCC documentation, we want the size of the subobject
  // denoted by the pointer. But that's not quite right -- what we actually
  // want is the size of the immediately-enclosing array, if there is one.
  if (Ptr.isArrayElement())
    Ptr = Ptr.expand();

  bool DetermineForCompleteObject = Ptr.getFieldDesc() == Ptr.getDeclDesc();
  const Descriptor *DeclDesc = Ptr.getDeclDesc();
  assert(DeclDesc);

  bool UseFieldDesc = (Kind & 1u);
  bool ReportMinimum = (Kind & 2u);
  if (!UseFieldDesc || DetermineForCompleteObject) {
    // Lower bound, so we can't fall back to this.
    if (ReportMinimum && !DetermineForCompleteObject)
      return std::nullopt;

    // Can't read beyond the pointer decl desc.
    if (!UseFieldDesc && !ReportMinimum && DeclDesc->getType()->isPointerType())
      return std::nullopt;
  } else {
    if (isUserWritingOffTheEnd(ASTCtx, Ptr)) {
      // If we cannot determine the size of the initial allocation, then we
      // can't given an accurate upper-bound. However, we are still able to give
      // conservative lower-bounds for Type=3.
      if (Kind == 1)
        return std::nullopt;
    }
  }

  // The "closest surrounding subobject" is NOT a base class,
  // so strip the base class casts.
  if (UseFieldDesc && Ptr.isBaseClass())
    Ptr = Ptr.stripBaseCasts();

  const Descriptor *Desc = UseFieldDesc ? Ptr.getFieldDesc() : DeclDesc;
  assert(Desc);

  std::optional<unsigned> FullSize = computeFullDescSize(ASTCtx, Desc);
  if (!FullSize)
    return std::nullopt;

  unsigned ByteOffset;
  if (UseFieldDesc) {
    if (Ptr.isBaseClass()) {
      assert(computePointerOffset(ASTCtx, Ptr.getBase()) <=
             computePointerOffset(ASTCtx, Ptr));
      ByteOffset = computePointerOffset(ASTCtx, Ptr.getBase()) -
                   computePointerOffset(ASTCtx, Ptr);

Review comment (suggestion):
Static analysis flagged this line. Im order to pass the outer `if` statement either `UseFieldDesc` has to be `false` or `DetermineForCompleteObject` has to be `true` but then they can't both be `true` here. Maybe I am missing something but then please point out the test that covers this case.

Code after:
  if (Ptr.isDummy() && Ptr.getType()->isPointerType())
    return std::nullopt;

  bool InvalidBase = false;

  if (Ptr.isDummy()) {
    if (const VarDecl *VD = Ptr.getDeclDesc()->asVarDecl();
        VD && VD->getType()->isPointerType())
      InvalidBase = true;
  }

  // According to the GCC documentation, we want the size of the subobject
  // denoted by the pointer. But that's not quite right -- what we actually
  // want is the size of the immediately-enclosing array, if there is one.
  if (Ptr.isArrayElement())
    Ptr = Ptr.expand();

  bool DetermineForCompleteObject = Ptr.getFieldDesc() == Ptr.getDeclDesc();
  const Descriptor *DeclDesc = Ptr.getDeclDesc();
  assert(DeclDesc);

  bool UseFieldDesc = (Kind & 1u);
  bool ReportMinimum = (Kind & 2u);
  if (!UseFieldDesc || DetermineForCompleteObject) {
    // Lower bound, so we can't fall back to this.
    if (ReportMinimum && UseFieldDesc && !DetermineForCompleteObject)
      return std::nullopt;

    // Can't read beyond the pointer decl desc.
    if (!UseFieldDesc && !ReportMinimum && DeclDesc->getType()->isPointerType())
      return std::nullopt;

    if (InvalidBase)
      return std::nullopt;
  } else {
    if (isUserWritingOffTheEnd(ASTCtx, Ptr, InvalidBase)) {
      // If we cannot determine the size of the initial allocation, then we
      // can't given an accurate upper-bound. However, we are still able to give
      // conservative lower-bounds for Type=3.
      if (Kind == 1)
        return std::nullopt;
    }
  }

  // The "closest surrounding subobject" is NOT a base class,
  // so strip the base class casts.
  if (UseFieldDesc && Ptr.isBaseClass())
    Ptr = Ptr.stripBaseCasts();

  const Descriptor *Desc = UseFieldDesc ? Ptr.getFieldDesc() : DeclDesc;
  assert(Desc);