<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/105458>105458</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
             clang-tidy issue:WRAPPER_ESCAPE problem.  about INNERPOINTERCHECKER.cpp
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang-tidy
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          zxyzxy1111
      </td>
    </tr>
</table>

<pre>
    Question: clang-tidy issue: It is known that the following code snippet will cause a WRAPPER_ESCAPE problem.

```cpp
const char *single_quote(const char *input) {
    std::string s = std::string("");
    return s.append("'").append(input).append("'").c_str();
}
```
1. Found that the checkPostCall function can detect append and call the markPtrSymbolsReleased function, but after entering markPtrSymbolsReleased, std::cout<<"Marking symbol as released: " << Symbol << "\n"; does not output when the program is running, this line has not been executed, indicating that the problem may be in if (const PtrSet *PS = State->get<RawPtrMap>(MR)) {
    const Expr *Origin = Call.getOriginExpr();

So: The problem may be that the PtrSet returned by State->get<RawPtrMap>(MR) is empty, or that MR is not correctly mapped to RawPtrMap. Further check the state of RawPtrMap and the value of MR.

2. Check the contents of RawPtrMap:
Add debugging information in markPtrSymbolsReleased to print the contents of RawPtrMap and ensure that MR is correctly mapped.
Check the value of MR:
Print the value of MR in checkPostCall and markPtrSymbolsReleased to ensure that they are consistent.
1. Add debugging information in markPtrSymbolsReleased:
Print the contents of RawPtrMap and the value of MR.
void InnerPointerChecker::markPtrSymbolsReleased(const CallEvent &Call,
                                                 ProgramStateRef State,
                                                 const MemRegion *MR,
                                                 CheckerContext &C) const {
  std::cout << "markPtrSymbolsReleased called with MR: " << MR << "\n";
  const RawPtrMapTy &RPM = State->get<RawPtrMap>();
  for (const auto &Entry : RPM) {
    std::cout << "RawPtrMap entry: " << Entry.first << "\n";
  }

  if (const PtrSet *PS = State->get<RawPtrMap>(MR)) {
    const Expr *Origin = Call.getOriginExpr();
    for (const auto Symbol : *PS) {
      std::cout << "Marking symbol as released: " << Symbol << "\n";
      State = allocation_state::markReleased(State, Symbol, Origin);
    }
    State = State->remove<RawPtrMap>(MR);
    C.addTransition(State);
    return;
  } else {
    std::cout << "No PtrSet found for MR: " << MR << "\n";
  }
}

2. Add debugging information in checkPostCall:
Print the value of ObjRegion.
void InnerPointerChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const {
  ProgramStateRef State = C.getState();

  const TypedValueRegion *ObjRegion = nullptr;

  if (const auto *ICall = dyn_cast<CXXInstanceCall>(&Call)) {
    ObjRegion = dyn_cast_or_null<TypedValueRegion>(
        ICall->getCXXThisVal().getAsRegion());

    if (isInvalidatingMemberFunction(Call)) {
      std::cout << "call markPtrSymbolsReleased with ObjRegion: " << ObjRegion << "\n";
      markPtrSymbolsReleased(Call, State, ObjRegion, C);
      return;
    }
  }

  if (isInnerPointerAccessFunction(Call)) {
    if (isa<SimpleFunctionCall>(Call)) {
      ObjRegion =
          dyn_cast_or_null<TypedValueRegion>(Call.getArgSVal(0).getAsRegion());
    }

    if (!ObjRegion)
      return;

    SVal RawPtr = Call.getReturnValue();
    if (SymbolRef Sym = RawPtr.getAsSymbol(/*IncludeBaseRegions=*/true)) {
      PtrSet::Factory &F = State->getStateManager().get_context<PtrSet>();
      const PtrSet *SetPtr = State->get<RawPtrMap>(ObjRegion);
      PtrSet Set = SetPtr ? *SetPtr : F.getEmptySet();
      assert(C.wasInlined || !Set.contains(Sym));
      Set = F.add(Set, Sym);

      State = State->set<RawPtrMap>(ObjRegion, Set);
      C.addTransition(State);
    }

    return;
  }

  checkFunctionArguments(Call, State, C);
}

Output
call markPtrSymbolsReleased with ObjRegion: 0x7631a60
call markPtrSymbolsReleased
markPtrSymbolsReleased called with MR: 0x7631a60
No PtrSet found for MR: 0x7631a60
call markPtrSymbolsReleased with ObjRegion: 0x7630cb8
call markPtrSymbolsReleased
markPtrSymbolsReleased called with MR: 0x7630cb8
No PtrSet found for MR: 0x7630cb8
call markPtrSymbolsReleased with ObjRegion: 0
call markPtrSymbolsReleased
markPtrSymbolsReleased called with MR: 0
No PtrSet found for MR: 0
call markPtrSymbolsReleased with ObjRegion: 0
call mark markPtrSymbolsReleased

markPtrSymbolsReleased function was correctly called, but the PtrSet returned by State->get<RawPtrMap>(MR) is always empty. This indicates that MR has not been correctly added to RawPtrMap.

3. Further debugging found that in the checkPostCall function, ObjRegion was not correctly added to RawPtrMap. In SymbolRef Sym = RawPtr.getAsSymbol(/*IncludeBaseRegions=*/true) returns false, which means that RawPtr is not a symbol. Further check the type and source of RawPtr to determine why it is not a symbol.

4. The problem may be in if (isInnerPointerAccessFunction(Call)) {
    std::cout << "isInnerPointerAccessFunction(Call) = true" << "\n"; // It has been determined that this is running
    if (isa<SimpleFunctionCall>(Call)) {
      std::cout << "isa<SimpleFunctionCall>(Call) = true" << "\n"; // It has been determined that this is not running
      ObjRegion =
          dyn_cast_or_null<TypedValueRegion>(Call.getArgSVal(0).getAsRegion());
    } where if (isa<SimpleFunctionCall>(Call))=false

isa<SimpleFunctionCall>(Call) returns false, need to further check the type of Call to determine why it is not a SimpleFunctionCall type.

5. Check the specific type of Call: Use llvm::isa and llvm::dyn_cast to check the specific type of Call and print relevant information.

`Output
release-install/bin/wecheck test2.cpp -- -g
markPtrSymbolsReleased called with MR: 0x7df7710
No PtrSet found for MR: 0x7df7710
markPtrSymbolsReleased called with MR: 0x7df6968
No PtrSet found for MR: 0x7df6968
markPtrSymbolsReleased called with MR: 0
No PtrSet found for MR: 0
markPtrSymbolsReleased called with MR: 0
No PtrSet found for MR: 0
isInnerPointerAccessFunction(Call) = true
isa<CXXMemberCall>(Call) = true`

Conclusion
Call object does not have a getCXXThisVal method. The value of this pointer needs to be obtained from the CXXMemberCall object.
`// Check the specific type of Call
    if (llvm::isa<SimpleFunctionCall>(Call)) {
      std::cout << "isa<SimpleFunctionCall>(Call) = true" << "\n"; // It has been determined that this is not running
      ObjRegion =
          dyn_cast_or_null<TypedValueRegion>(Call.getArgSVal(0).getAsRegion());
    } else if (const auto *MemberCall = llvm::dyn_cast<CXXMemberCall>(&Call)) {
      std::cout << "isa<CXXMemberCall>(Call) = true" << "\n";
      ObjRegion = dyn_cast_or_null<TypedValueRegion>(MemberCall->getCXXThisVal().getAsRegion()); // It has been determined that this is a CXXMemberCall, not a SimpleFunctionCall
    } else if (llvm::isa<CXXConstructorCall>(Call)) {
      std::cout << "isa<CXXConstructorCall>(Call) = true" << "\n";
    } else if (llvm::isa<CXXDestructorCall>(Call)) {
      std::cout << "isa<CXXDestructorCall>(Call) = true" << "\n";
    } else {
      std::cout << "Call is of unknown type" << "\n";
    }
    if (!ObjRegion)
      return;`

Output
`isInnerPointerAccessFunction(Call) = true
isa<CXXMemberCall>(Call) = true
MemberCall->getCXXThisVal() = &SymRegion{conj_$13{basic_string<char> &, LC2, S1185017, #1}}ThisVal.getAsRegion() = 0x7e96d48`

MemberCall->getCXXThisVal() returned a SymRegion, and ThisVal.getAsRegion() returned a valid memory region address 0x7e96d48. This indicates that the value returned by getCXXThisVal() is valid.
However, dyn_cast_or_null<TypedValueRegion>(ThisRegion) may have failed because ThisRegion is not of TypedValueRegion type. Further check the actual type of ThisRegion and ensure that it can be correctly converted.

isInnerPointerAccessFunction(Call) = true
isa<CXXMemberCall>(Call) = true
MemberCall->getCXXThisVal() = &SymRegion{conj_$13{basic_string<char> &, LC2, S1185017, #1}}ThisVal.getAsRegion() = 0x80fe488
ThisRegion is a SymbolicRegion
ObjRegion is null

This Region is a SymbolicRegion, not a TypedValueRegion. This indicates that further processing of SymbolicRegion is needed to obtain the required TypedValueRegion.

In the checkPostCall method, when ThisRegion is a SymbolicRegion, obtain its BaseRegion and try to convert it to TypedValueRegion.
After experimentation: error propagation - it has been determined that this is a SymbolicRegion, not a TypedValueRegion, and it is not possible to obtain TypedValueRegion from it.
@NagyDonat

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWl1T4zrS_jXmRkUqkQMJF1wEk9Sh3peZbJg9yx0l251EZ2zJR5IJOb9-qyV_JnYILGdrLnaKYohjdT_9qL_UNtOabwTArXd1513dX7DcbKW6_ett_9fbfjQajS5CGe9v_5GDNlwKz5-RKGFic2l4vCdc6xzw2oMhXJOfQu4EMVtmiNkCWcskkTsuNiSSMRAteJaBITueJCRiuQbCyL9Ws-VyvnqZPwWz5ZxkSoYJpANveO8NZ8Xv66H7ibLMXYmk0IZEW6aIR2eai00CL3_m0oBHp-0vuchy49Eb4k3u3GJCCNEm9vyZ58-0UYhPE8-_P7zq0alHqf258fzGagUmV4LoAcsyEHF538TdWl8tdffcF71oo-zFWrw3uT8w2n0cDchC5iKuyY22EP1cSm0CliRknYsI94dETJAYDESGOK2EiZhEeA-uSpn6uTTqaZ-GMtErSIBpiKvlHg1ImBvC1gYUAWHA0tO9Cm-uKItkbjw_wB9KH5n6aWm1CwjTRJVr_BnxKCXuVuIklp-Ql6tA4H_-HYklaCKkITI3WW7IbgvC2pApuVEsRYdTuRB2pwJitlyThAsgW-bWhQCCwBtEuXFguYh5xAwiq2gsHI6kbE9CIFwQviaVF6HRYNCPlk_WRZ4MM3Dp-fMNoLkrtlsa9cgyz597dPq4wr08dDYnav6WWYf8rviGCysMd26wAeMu4Q2H3mB_P0lk7ccx2MqIAqbzS4hJuD8HKBIIaWb2yI1UTtzjCi8jfZFUCiKT7EmKnhQTI0klZkAWuTJbUM4PLQqNKolc13dZ38OvXlmS268eV63QpgMSVOsjKQwIo1si0LvsrbM4JjGE-WaD-8fFWqqUWZfnos-tjSSZ4sL0i7cIQehcQdP-Q9sL0DXWhkEVwmWlqvEtomuHKmrsx9vEYrawJ0xZ6JprRD-o0sEn-OhA2k9K97a9Sh6TByFALSXH9GApAeWSQF-eKKIJzZ-_gsCAusYPHg3qMPnQv6XLAdbLV7B27v55cQ7fI6Qr2CCFHp1hiHxWXEFKgOS-OWsx3pyWRm5oZc9GFuxxD8ziEJMdN1vnd81U-rjqTKOlKqe72uIfe0S1Wj6ekdXa5W8tVZ0fWW4kCpoLo_YEEa2Wj_3V9sDM2uEA1x8YZGUO1lxpc9KyumQWF36hBI6rjwmrqt7MATtS2E_ZV1TWph5Lh7WFJYmMbAJ5sYm8juhGHJdhVojHv5zth0ZXm9JWUrGvIJWv0LcBTUnBgMXxD8WE5q5DKUF09WRttyCQaDjPFb_J0lXWts3CTftoiNWO2PZI-k6ybpWHU9Xke_iHy09nJeO22FM5-Ox81Zl1XSRgGBQb09HClDH0Y59B_DvaUyfayiorSORJkhl1tL4Z1EXWmT3Yeoqr4r14iZjGiA6enx-ENkxE4Ph0Kayw9Ti42-pLQS9SvSAUzw8OMRcSW5XBIimySvD8_GPL9e8scVQgMzNdrHXkdPBTWsj1g3hlCY9tn_oIaQhqUXXn0z4r-j3btv49BcVWkoqAA29vEnM6ifSW_dK_qrRR60KvO4zhjihuZZKeTI-U1TEwiyLQ-gzKysXM84MnnmYJlItqv-mnu-U2h23C2V5UFpCZ2jw5hxm-6zEtUg7N8eiowfHNCW4b6fl3lhSdQauqrewCi7mjrDl9bs9tLtindrUT5Ewoq8TUowuMVxEleQx3TBckaOSOzjy6MCqHbqJdWnauvWCRkcq2Loujam7_fmSCbUDVkfcSuaTm-UEp6binqYt83S88gSkJOd0ztPj2O7ATKxHllCIXLQUzskCkczyKIcAudExrUPhVMNgx_SDwoBsTbxJ4EwzM0ROYAVrKuNBuWzq8hlRIFlhU8T5UZ6t5d07qrN36HRYCYsUe6j6zkHe4dldtP6guWMDK8J2pTZ7ioaYrAwXd0xb7-7sdNBQjpg-lzeHb5NofsXJac2Kxu-HsBv9AcH-bcj6CPvjDKJz-LfBrwe_APwtBF_wvh_0u3K-AeRLrScTVtG_HmrMKZ0g5w_vPBkMs2bF9MR8aEGxoyvEZ6GpS0pq01ThYHB-Oi5pG-fXwqO6J1_V0k4sTA85WF2Htb8-qOnSTB0G-uE4VjGqyZom2eWW35dGWpMBEQU9RUIthGitObF1zM7PPwI5ctMxV1JigoRkxGFApF0B22z3h5khgk9nxoGtMWM00P9ko9XWW54mzZDvaaPeg15K-IA_G-pP1pcrqauCN_lfPe7-oieu37Ax5X2oYbumRcb9Al0l2W1DwQZo9_97FRcM1z6P0KKwEuGhed0eNXNtu9XSgHCu1i1uRc9UcROsMIr7mUUsHZvB_aiBJ8po6p-Ga2bCtr5Q7gnii0-LsSjecVpDAKxOmORc4fADWbE2Kic8lx2Mu8rYIufDoYgeFTtCGDqIsI5eX5HLz8ZIdryeT0TkdR_PGjym4vrk-pydo3vjl1fvLBX40ITYCI3h-dmf9E2mm7O2KZxESq5RG0e4zOpUM_4DI1I_OtuwVCCOtqQRJwWxl7EpFNVuyiShzyG3UaXTiEIgM8VCBTYeSqfXnFtZC5aB-aumS3nvRdJDBW1H1v1z-9-RyOw7tGqQ1thOJOE5o3R56Yqr23n6c4-89W9HL6fkk1qo_OLP7iBuwdqDYatZTj3q36TAsgufnAHdO5ZGRx9x9ZhtOyfvAXrwP_B6-FPcJcZ-BfaZ6GyPcPi7NRfG6yz47T9GnZnXtpN9sA7zr4d9ccOzt78aKvd-j10_74umpN7mLpPjjxaPjke9N7kKmuX3XBROiH0Rbpjx_jkswJv4_oHZAMxpNr4ajCf7tUX-EfE3uC0XH4WiVDt8mcHMdj6cHLL0PuToQM1LDpoFtyvp1NlbZET1JIZVqT5RLQSyOFWhdw-o-N9ePdJrH8i6UXDs9RXH9Te7gFRTiPDvTocDKw-yB0LYEa8axxwnBvYZV31XWL7k-flZjm-aO8yuLTM6Sqrw3hB2-XMGNfT8phObQQopXUKZ6x-K_0kr9-p49Ha5hPC1a3_b-sGKawaNinUsNVSnELczLolILICckVLXpcNO7Xbg8jWVK4sZwscGNb8u0MACKaYzrIq27KPgz5wriY11NxA9dQyDXubpxCwjyDi00KNVyo0k9zXGvt6i9PaU570PPNLIP0cy9DfeWgeIpCMPKNyFBKWlZyNjGPc69RElntAbn8l8mpfo8m0mteZhAg9WjSLWtOq-a8vHwG9vs76VgRem4iG_9-Ma_YRdwO5rQMR3SEaUX21t_eHM9HPtssqYQT-g4Hl-PmB-FPoPpML5mF_yWDul4OKWj4WhIh3QQwpU_vWbsJprQcDQaeeMhpIwnA-wABlJtLuw7orej4dX4anqRsBASbV82pbR-kdQWzfsLdYurLsN8o73xMOHa6FqO4SaB2-O3T-cL7y7wbmY9b5ISwkKs4Q_fvs1Xy-8P337MV8Fv8-D_5is8I1_kKrndGpNprPe2u9tws83DQSRTjy5sI-P-u8yUxLOORxdWs_boojDr9Zb-OwAA__-_e1yd">