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

    <tr>
        <th>Summary</th>
        <td>
            False-Positive clang-tidy clang-analyzer-cplusplus.NewDelete with message "Use of memory after it is freed" on deleting pointer with MACRO and MFC
        </td>
    </tr>

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

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

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

<pre>
    If considering the following code

```
#define DELETE_POINTER(p)                                       \
        do {                                                                    \
                delete p;                                                       \
                p= nullptr;                              \
        } while(0)
```

This will raise a false positive error iff the delete operator is customized. This issue is solved if not using a loop construct.

```
#define DELETE_POINTER(p)                                       \
        {                                                                       \
                delete p;                                                       \
                p= nullptr;                              \
        }
```

If p is from this class type it will raise the issue:

```
class cPointerClass : CObject // MFC Base class
{

};

```

The corresponding class definition:

```

// CObject
_AFX_INLINE CObject::CObject()
        { }
_AFX_INLINE CObject::~CObject()
        { }
_AFX_INLINE void CObject::Serialize(CArchive&)
        { /* CObject does not serialize anything by default */ }
_AFX_INLINE void* PASCAL CObject::operator new(size_t, void* p)
        { return p; }
#ifndef _DEBUG
// _DEBUG versions in afxmem.cpp
_AFX_INLINE void PASCAL CObject::operator delete(void* p)
        { ::operator delete(p); }
_AFX_INLINE void PASCAL CObject::operator delete(void* p, void*)
        { ::operator delete(p); }
_AFX_INLINE void* PASCAL CObject::operator new(size_t nSize)
        { return ::operator new(nSize); }
// _DEBUG versions in objcore.cpp
#ifdef _AFXDLL
_AFX_INLINE void CObject::AssertValid() const
        { /* no asserts in release builds */ }
_AFX_INLINE void CObject::Dump(CDumpContext&) const
        { /* no dumping in release builds */ }
#endif //_AFXDLL
#endif //!_DEBUG
```

I'm considering using a release build so the operator delete will be overriden but will the use the standard delete operation.

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMVltvo7gX_zTOy1EjMLmQBx5oLn9V6rTVtPPXvFUOPiQeGRvZJp30YT_7yoYkQ7bJbKVdaSsKMZybf79zMbNWbBRiRsa3ZLwYsMZttckqJjnbDNaa77O7EgqtrOBohNqA2yKUWkr95leF5kiiBYny7j6Juqtd0oRjKRTCYnm_fFm-Pj3ePbwsvxKa1oTOSNS_xvODrRnXQKa35wIXhL08SnQINUl6SnDh70y7JskCVCNl7cy5hZ7odAFvWyGR0DQKG_ho0-H-shUW3oSUYJiwCAxKJi1Cra1wYoeAxmgDoiwDpF38ukbDnH9voWis05V4Rz6EYE1Y26D_YrXcIQdRgtIOGuuZYCC1rgNVzjSFG_4rtPw3OblCw10JtYesNLoC51EsJLMW3L5GEO5XhjwNAWKS5FfAa_WLJy2UQzMPK5LkMH9c_8DCAaErQlfwZTWHW2ax9ddZ8uj9Yni6CBu7zFOXSQiFNgZtrRUPVRecBgqFE1pdD_jAeQiri7J995qvvr_ePdzfPSyPH5KcJPlhQdNTkgfy4Yj2Rd0_Pqm804L3LTyjEUyKd19l89wUW7FDQid_seZ3dMKda7ShHuxBHZjau60HbL33aLFGeno8FJdD8Saf8ud5ft8P6liZCt8ITa14x1dH6PyoVJ_HZ9A1RoX0P7kjNBGl4ljC62J5--1_PXLaV7BDY4VWFoQCVv6ssBoWdX0BuauxthVIaHoxyEsKQTC5RtmnHR-h-sdi-BRXoJ5DSn1I0od6R4U-gZeo0usfhTZ44ipwHajOV98X9_d_J_dza9G4_zPpd-cLqO3oHyW-0sCCdPBuUKJvN-tGSG5_m-Z9r4umqn2x-edcK4c_XVtwV73zpqp9df3eO6EJKi7Krjn28Dj7Rmjcq4wPmzqh06p3KjnMwF4cYHVo6meZ1fb8NYLeoTGCo4J1000CL950s8A6pjgzvD-bhVbdaB3wLOGzZMYGmMXTKIrjyTSKB9ssns4m05SOkzSNGZYxH5XlbJzGo2hS0NmMDURGI5rEcTyJJklK42GRRAyTlI3KcjyKy5iMIqyYkEMpd9VQm80gDKZsSkcpHUi2RmnDkY3SQjK1uXGC7wml_ghnMq90s242lowiKayzJzNOOInZyp9Ebp4OJ5GTie4nU0zu39HcFLVsrP8fPuDb4oCe20KF1rINAqH0m0XQJVRYabMHVjo0frCGmYvICaWgVYuh56hu52Zr5ks-__oITHE_LgeNkdnWudr6pAzJsBFu26yHha4IXflNdI-b2uh2xqwCMJbQVcDmzwAAAP__-Zoc2A">