namespace { template T source(); template T* indirect_source(); void sink(...); } typedef unsigned int UINT; typedef long LONG; typedef void* LPVOID; typedef void* PVOID; typedef bool BOOL; typedef char* PSTR, *LPSTR; typedef const char* LPCTSTR; typedef const wchar_t* LPCWSTR; typedef unsigned short WORD; typedef unsigned long DWORD; typedef void* HANDLE; typedef LONG HRESULT; typedef unsigned long ULONG; typedef const char* LPCSTR; typedef wchar_t OLECHAR; typedef OLECHAR* LPOLESTR; typedef const LPOLESTR LPCOLESTR; typedef OLECHAR* BSTR; typedef wchar_t* LPWSTR, *PWSTR; typedef BSTR* LPBSTR; typedef unsigned short USHORT; typedef char *LPTSTR; struct __POSITION { int unused; }; typedef __POSITION* POSITION; typedef WORD ATL_URL_PORT; using HINSTANCE = void*; using size_t = decltype(sizeof(int)); using SIZE_T = size_t; #define NULL nullptr namespace ATL { enum ATL_URL_SCHEME{ ATL_URL_SCHEME_UNKNOWN = -1, ATL_URL_SCHEME_FTP = 0, ATL_URL_SCHEME_GOPHER = 1, ATL_URL_SCHEME_HTTP = 2, ATL_URL_SCHEME_HTTPS = 3, ATL_URL_SCHEME_FILE = 4, ATL_URL_SCHEME_NEWS = 5, ATL_URL_SCHEME_MAILTO = 6, ATL_URL_SCHEME_SOCKS = 7 }; typedef struct tagSAFEARRAYBOUND { ULONG cElements; LONG lLbound; } SAFEARRAYBOUND, *LPSAFEARRAYBOUND; typedef struct tagVARIANT { /* ... */ } VARIANT; typedef struct tagSAFEARRAY { USHORT cDims; USHORT fFeatures; ULONG cbElements; ULONG cLocks; PVOID pvData; SAFEARRAYBOUND rgsabound[1]; } SAFEARRAY, *LPSAFEARRAY; struct _U_STRINGorID { _U_STRINGorID(UINT nID); _U_STRINGorID(LPCTSTR lpString); LPCTSTR m_lpstr; }; void test__U_STRINGorID() { { UINT x = source(); _U_STRINGorID u(x); sink(u.m_lpstr); // $ ir } { LPCTSTR y = indirect_source(); _U_STRINGorID u(y); sink(u.m_lpstr); // $ ir } } template struct CA2AEX { LPSTR m_psz; char m_szBuffer[t_nBufferLength]; CA2AEX(LPCSTR psz, UINT nCodePage); CA2AEX(LPCSTR psz); ~CA2AEX(); operator LPSTR() const throw(); }; void test_CA2AEX() { { LPSTR x = indirect_source(); CA2AEX<128> a(x); sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_szBuffer); // $ ir } { LPSTR x = indirect_source(); CA2AEX<128> a(x, 0); sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_szBuffer); // $ ir } } template struct CA2CAEX { CA2CAEX(LPCSTR psz, UINT nCodePage) ; CA2CAEX(LPCSTR psz) ; ~CA2CAEX() throw(); operator LPCSTR() const throw(); LPCSTR m_psz; }; void test_CA2CAEX() { LPCSTR x = indirect_source(); { CA2CAEX<128> a(x); sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_psz); // $ ir } { CA2CAEX<128> a(x, 0); sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_psz); // $ ir } } template struct CA2WEX { CA2WEX(LPCSTR psz, UINT nCodePage) ; CA2WEX(LPCSTR psz) ; ~CA2WEX() throw(); operator LPWSTR() const throw(); LPWSTR m_psz; wchar_t m_szBuffer[t_nBufferLength]; }; void test_CA2WEX() { LPCSTR x = indirect_source(); { CA2WEX<128> a(x); sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_psz); // $ ir } { CA2WEX<128> a(x, 0); sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_psz); // $ ir } } template struct CElementTraitsBase { typedef const T& INARGTYPE; typedef T& OUTARGTYPE; static void CopyElements(T* pDest, const T* pSrc, size_t nElements); static void RelocateElements(T* pDest, T* pSrc, size_t nElements); }; template struct CDefaultElementTraits : public CElementTraitsBase {}; template struct CElementTraits : public CDefaultElementTraits {}; template> struct CAtlArray { using INARGTYPE = typename ETraits::INARGTYPE; using OUTARGTYPE = typename ETraits::OUTARGTYPE; CAtlArray() throw(); ~CAtlArray() throw(); size_t Add(INARGTYPE element); size_t Add(); size_t Append(const CAtlArray& aSrc); void Copy(const CAtlArray& aSrc); const E& GetAt(size_t iElement) const throw(); E& GetAt(size_t iElement) throw(); size_t GetCount() const throw(); E* GetData() throw(); const E* GetData() const throw(); void InsertArrayAt(size_t iStart, const CAtlArray* paNew); void InsertAt(size_t iElement, INARGTYPE element, size_t nCount); bool IsEmpty() const throw(); void RemoveAll() throw(); void RemoveAt(size_t iElement, size_t nCount); void SetAt(size_t iElement, INARGTYPE element); void SetAtGrow(size_t iElement, INARGTYPE element); bool SetCount(size_t nNewSize, int nGrowBy); E& operator[](size_t ielement) throw(); const E& operator[](size_t ielement) const throw(); }; void test_CAtlArray() { int x = source(); { CAtlArray a; a.Add(x); sink(a[0]); // $ ir a.Add(0); sink(a[0]); // $ ir CAtlArray a2; sink(a2[0]); a2.Append(a); sink(a2[0]); // $ ir CAtlArray a3; sink(a3[0]); a3.Copy(a2); sink(a3[0]); // $ ir sink(a3.GetAt(0)); // $ ir sink(*a3.GetData()); // $ ir CAtlArray a4; sink(a4.GetAt(0)); a4.InsertArrayAt(0, &a3); sink(a4.GetAt(0)); // $ ir } { CAtlArray a5; a5.InsertAt(0, source(), 1); sink(a5[0]); // $ ir CAtlArray a6; a6.SetAtGrow(0, source()); sink(a6[0]); // $ ir } } template> struct CAtlList { using INARGTYPE = typename ETraits::INARGTYPE; CAtlList(UINT nBlockSize) throw(); ~CAtlList() throw(); POSITION AddHead(); POSITION AddHead(INARGTYPE element); void AddHeadList(const CAtlList* plNew); POSITION AddTail(); POSITION AddTail(INARGTYPE element); void AddTailList(const CAtlList* plNew); POSITION Find(INARGTYPE element, POSITION posStartAfter) const throw(); POSITION FindIndex(size_t iElement) const throw(); E& GetAt(POSITION pos) throw(); const E& GetAt(POSITION pos) const throw(); size_t GetCount() const throw(); E& GetHead() throw(); const E& GetHead() const throw(); POSITION GetHeadPosition() const throw(); E& GetNext(POSITION& pos) throw(); const E& GetNext(POSITION& pos) const throw(); E& GetPrev(POSITION& pos) throw(); const E& GetPrev(POSITION& pos) const throw(); E& GetTail() throw(); const E& GetTail() const throw(); POSITION GetTailPosition() const throw(); POSITION InsertAfter(POSITION pos, INARGTYPE element); POSITION InsertBefore(POSITION pos, INARGTYPE element); bool IsEmpty() const throw(); void MoveToHead(POSITION pos) throw(); void MoveToTail(POSITION pos) throw(); void RemoveAll() throw(); void RemoveAt(POSITION pos) throw(); E RemoveHead(); void RemoveHeadNoReturn() throw(); E RemoveTail(); void RemoveTailNoReturn() throw(); void SetAt(POSITION pos, INARGTYPE element); void SwapElements(POSITION pos1, POSITION pos2) throw(); }; void test_CAtlList() { int x = source(); { CAtlList list(10); sink(list.GetHead()); list.AddHead(x); sink(list.GetHead()); // $ ir CAtlList list2(10); list2.AddHeadList(&list); sink(list2.GetHead()); // $ ir CAtlList list3(10); list3.AddTail(x); sink(list3.GetHead()); // $ ir CAtlList list4(10); list4.AddTailList(&list3); sink(list4.GetHead()); // $ ir { CAtlList list5(10); auto pos = list5.Find(x, list5.GetHeadPosition()); sink(list5.GetAt(pos)); // $ MISSING: ir } { CAtlList list6(10); list6.AddHead(x); auto pos = list6.FindIndex(0); sink(list6.GetAt(pos)); // $ ir } { CAtlList list7(10); auto pos = list7.GetTailPosition(); list7.InsertAfter(pos, x); sink(list7.GetHead()); // $ ir } { CAtlList list8(10); auto pos = list8.GetTailPosition(); list8.InsertBefore(pos, x); sink(list8.GetHead()); // $ ir } { CAtlList list9(10); list9.SetAt(list9.GetHeadPosition(), x); sink(list9.GetHead()); // $ ir } } int* p = indirect_source(); { CAtlList list(10); sink(list.GetHead()); list.AddHead(p); sink(list.GetHead()); // $ ir CAtlList list2(10); list2.AddHeadList(&list); sink(list2.GetHead()); // $ ir CAtlList list3(10); list3.AddTail(p); sink(list3.GetHead()); // $ ir CAtlList list4(10); list4.AddTailList(&list3); sink(list4.GetHead()); // $ ir { CAtlList list5(10); auto pos = list5.Find(p, list5.GetHeadPosition()); sink(list5.GetAt(pos)); // $ MISSING: ir } { CAtlList list6(10); list6.AddHead(p); auto pos = list6.FindIndex(0); sink(list6.GetAt(pos)); // $ ir } { CAtlList list7(10); auto pos = list7.GetTailPosition(); list7.InsertAfter(pos, p); sink(list7.GetHead()); // $ ir } { CAtlList list8(10); auto pos = list8.GetTailPosition(); list8.InsertBefore(pos, p); sink(list8.GetHead()); // $ ir } { CAtlList list9(10); list9.SetAt(list9.GetHeadPosition(), p); sink(list9.GetHead()); // $ ir } } } struct IUnknown { }; struct ISequentialStream : public IUnknown { }; struct IStream : public ISequentialStream { }; struct CComBSTR { CComBSTR() throw(); CComBSTR(const CComBSTR& src); CComBSTR(int nSize); CComBSTR(int nSize, LPCOLESTR sz); CComBSTR(int nSize, LPCSTR sz); CComBSTR(LPCOLESTR pSrc); CComBSTR(LPCSTR pSrc); CComBSTR(CComBSTR&& src) throw(); ~CComBSTR(); HRESULT Append(const CComBSTR& bstrSrc) throw(); HRESULT Append(wchar_t ch) throw(); HRESULT Append(char ch) throw(); HRESULT Append(LPCOLESTR lpsz) throw(); HRESULT Append(LPCSTR lpsz) throw(); HRESULT Append(LPCOLESTR lpsz, int nLen) throw(); HRESULT AppendBSTR(BSTR p) throw(); HRESULT AppendBytes(const char* lpsz, int nLen) throw(); HRESULT ArrayToBSTR(const SAFEARRAY* pSrc) throw(); HRESULT AssignBSTR(const BSTR bstrSrc) throw(); void Attach(BSTR src) throw(); HRESULT BSTRToArray(LPSAFEARRAY* ppArray) throw(); unsigned int ByteLength() const throw(); BSTR Copy() const throw(); HRESULT CopyTo(BSTR* pbstr) throw(); HRESULT CopyTo(VARIANT* pvarDest) throw(); BSTR Detach() throw(); void Empty() throw(); unsigned int Length() const throw(); bool LoadString(HINSTANCE hInst, UINT nID) throw(); bool LoadString(UINT nID) throw(); HRESULT ReadFromStream(IStream* pStream) throw(); HRESULT ToUpper() throw(); HRESULT WriteToStream(IStream* pStream) throw(); operator BSTR() const throw(); BSTR* operator&() throw(); CComBSTR& operator+= (const CComBSTR& bstrSrc); CComBSTR& operator+= (const LPCOLESTR pszSrc); BSTR m_str; }; LPSAFEARRAY getSafeArray() { SAFEARRAY* safe = new SAFEARRAY; safe->pvData = indirect_source(); return safe; } void test_CComBSTR() { char* x = indirect_source(); { CComBSTR b(x); sink(b.m_str); // $ ir CComBSTR b2(b); sink(b2.m_str); // $ ir } { CComBSTR b(10, x); sink(b.m_str); // $ ir } { CComBSTR b(x); CComBSTR b2; sink(b2.m_str); b2 += b; sink(b2.m_str); // $ ir CComBSTR b3; b3 += x; sink(b3.m_str); // $ ir sink(static_cast(b3)); // $ ir sink(**&b3); // $ ir CComBSTR b4; b4.Append(source()); sink(b4.m_str); // $ ir CComBSTR b5; b5.AppendBSTR(b4.m_str); sink(b5.m_str); // $ ir CComBSTR b6; b6.AppendBytes(x, 10); sink(b6.m_str); // $ ir CComBSTR b7; b7.ArrayToBSTR(getSafeArray()); sink(b7.m_str); // $ ir CComBSTR b8; b8.AssignBSTR(b7.m_str); sink(b8.m_str); // $ ir CComBSTR b9; LPSAFEARRAY safe; b9.Append(source()); b9.BSTRToArray(&safe); sink(safe->pvData); // $ ir sink(b9.Copy()); // $ ir } wchar_t* w = indirect_source(); { CComBSTR b(w); sink(b.m_str); // $ ir CComBSTR b2; b2.Attach(w); sink(b2.m_str); // $ ir } { CComBSTR b(10, w); sink(b.m_str); // $ ir } } template struct CComSafeArray { CComSafeArray(); CComSafeArray(const SAFEARRAYBOUND& bound); CComSafeArray(ULONG ulCount, LONG lLBound); CComSafeArray(const SAFEARRAYBOUND* pBound, UINT uDims); CComSafeArray(const CComSafeArray& saSrc); CComSafeArray(const SAFEARRAY& saSrc); CComSafeArray(const SAFEARRAY* psaSrc); ~CComSafeArray() throw(); HRESULT Add(const SAFEARRAY* psaSrc); HRESULT Add(ULONG ulCount, const T* pT, BOOL bCopy); HRESULT Add(const T& t, BOOL bCopy); HRESULT Attach(const SAFEARRAY* psaSrc); HRESULT CopyFrom(LPSAFEARRAY* ppArray); HRESULT CopyTo(LPSAFEARRAY* ppArray); HRESULT Create(const SAFEARRAYBOUND* pBound, UINT uDims); HRESULT Create(ULONG ulCount, LONG lLBound); HRESULT Destroy(); LPSAFEARRAY Detach(); T& GetAt(LONG lIndex) const; ULONG GetCount(UINT uDim) const; UINT GetDimensions() const; LONG GetLowerBound(UINT uDim) const; LPSAFEARRAY GetSafeArrayPtr() throw(); LONG GetUpperBound(UINT uDim) const; bool IsSizable() const; HRESULT MultiDimGetAt(const LONG* alIndex, T& t); HRESULT MultiDimSetAt(const LONG* alIndex, const T& t); HRESULT Resize(const SAFEARRAYBOUND* pBound); HRESULT Resize(ULONG ulCount, LONG lLBound); HRESULT SetAt(LONG lIndex, const T& t, BOOL bCopy); operator LPSAFEARRAY() const; T& operator[](long lindex) const; T& operator[](int nindex) const; LPSAFEARRAY m_psa; }; void test_CComSafeArray() { LPSAFEARRAY safe = getSafeArray(); sink(safe->pvData); // $ ir { CComSafeArray c(safe); sink(c[0]); // $ ir sink(c.GetAt(0)); // $ ir sink(c.GetSafeArrayPtr()->pvData); // $ ir sink(c.m_psa->pvData); // $ ir } { CComSafeArray c; sink(c[0]); sink(c.GetAt(0)); sink(c.GetSafeArrayPtr()->pvData); c.Add(safe); sink(c[0]); // $ ir sink(c.GetAt(0)); // $ ir sink(c.GetSafeArrayPtr()->pvData); // $ ir sink(static_cast(c)->pvData); // $ ir } { CComSafeArray c; c.Add(source(), true); sink(c[0]); // $ ir sink(c.GetAt(0)); // $ ir sink(c.GetSafeArrayPtr()->pvData); // $ ir } { CComSafeArray c; c.SetAt(0, source(), true); sink(c[0]); // $ ir sink(c[0L]); // $ ir } } template struct CPathT { typedef StringType PCXSTR; // simplified CPathT(PCXSTR pszPath); CPathT(const CPathT& path); CPathT() throw(); void AddBackslash(); BOOL AddExtension(PCXSTR pszExtension); BOOL Append(PCXSTR pszMore); void BuildRoot(int iDrive); void Canonicalize(); void Combine(PCXSTR pszDir, PCXSTR pszFile); CPathT CommonPrefix(PCXSTR pszOther); BOOL CompactPathEx(UINT nMaxChars, DWORD dwFlags); BOOL FileExists() const; int FindExtension() const; int FindFileName() const; int GetDriveNumber() const; StringType GetExtension() const; BOOL IsDirectory() const; BOOL IsFileSpec() const; BOOL IsPrefix(PCXSTR pszPrefix) const; BOOL IsRelative() const; BOOL IsRoot() const; BOOL IsSameRoot(PCXSTR pszOther) const; BOOL IsUNC() const; BOOL IsUNCServer() const; BOOL IsUNCServerShare() const; BOOL MakePretty(); BOOL MatchSpec(PCXSTR pszSpec) const; void QuoteSpaces(); BOOL RelativePathTo( PCXSTR pszFrom, DWORD dwAttrFrom, PCXSTR pszTo, DWORD dwAttrTo); void RemoveArgs(); void RemoveBackslash(); void RemoveBlanks(); void RemoveExtension(); BOOL RemoveFileSpec(); BOOL RenameExtension(PCXSTR pszExtension); int SkipRoot() const; void StripPath(); BOOL StripToRoot(); void UnquoteSpaces(); operator const StringType&() const throw(); operator PCXSTR() const throw(); operator StringType&() throw(); CPathT& operator+=(PCXSTR pszMore); StringType m_strPath; }; using CPath = CPathT; void test_CPathT() { char* x = indirect_source(); CPath p(x); sink(static_cast(p)); // $ MISSING: ir sink(p.m_strPath); // $ ir CPath p2(p); sink(p2.m_strPath); // $ ir { CPath p; p.AddExtension(x); sink(p.m_strPath); // $ ir } { CPath p; p.Append(x); sink(p.m_strPath); // $ ir CPath p2; p2 += p; sink(p2.m_strPath); // $ MISSING: ir // this requires flow through `operator StringType&()` which we can't yet model in MaD CPath p3; p3 += x; sink(p3.m_strPath); // $ ir } { CPath p; p.Combine(x, nullptr); sink(p.m_strPath); // $ ir } { CPath p; p.Combine(nullptr, x); sink(p.m_strPath); // $ ir } { CPath p; auto p2 = p.CommonPrefix(x); sink(p2.m_strPath); // $ ir sink(p2.GetExtension()); // $ ir } } template struct CSimpleArray { CSimpleArray(const CSimpleArray& src); CSimpleArray(); ~CSimpleArray(); BOOL Add(const T& t); int Find(const T& t) const; T* GetData() const; int GetSize() const; BOOL Remove(const T& t); void RemoveAll(); BOOL RemoveAt(int nIndex); BOOL SetAtIndex( int nIndex, const T& t); T& operator[](int nindex); CSimpleArray & operator=(const CSimpleArray& src); }; void test_CSimpleArray() { int x = source(); { CSimpleArray a; a.Add(x); sink(a[0]); // $ ir a.Add(0); sink(a[0]); // $ ir CSimpleArray a2; sink(a2[0]); a2 = a; sink(a2[0]); // $ ir } { CSimpleArray a; a.Add(x); sink(a.GetData()); // $ ir CSimpleArray a2; int pos = a2.Find(x); sink(a2[pos]); // $ MISSING: ir } } template struct CSimpleMap { CSimpleMap(); ~CSimpleMap(); BOOL Add(const TKey& key, const TVal& val); int FindKey(const TKey& key) const; int FindVal(const TVal& val) const; TKey& GetKeyAt(int nIndex) const; int GetSize() const; TVal& GetValueAt(int nIndex) const; TVal Lookup(const TKey& key) const; BOOL Remove(const TKey& key); void RemoveAll(); BOOL RemoveAt(int nIndex); TKey ReverseLookup(const TVal& val) const; BOOL SetAt(const TKey& key, const TVal& val); BOOL SetAtIndex(int nIndex, const TKey& key, const TVal& val); }; void test_CSimpleMap() { wchar_t* x = source(); { CSimpleMap a; a.Add("hello", x); sink(a.Lookup("hello")); // $ ir } { CSimpleMap a; auto pos = a.FindKey("hello"); sink(a.GetValueAt(pos)); // clean } { CSimpleMap a; auto pos = a.FindVal(x); sink(a.GetValueAt(pos)); // $ MISSING: ir } { CSimpleMap a; auto key = a.ReverseLookup(x); sink(key); sink(a.Lookup(key)); // $ MISSING: ir } { CSimpleMap a; a.SetAt("hello", x); sink(a.Lookup("hello")); // $ ir } { CSimpleMap a; a.SetAtIndex(0, "hello", x); sink(a.Lookup("hello")); // $ ir } } struct CUrl { CUrl& operator= (const CUrl& urlThat) throw(); CUrl() throw(); CUrl(const CUrl& urlThat) throw(); ~CUrl() throw(); inline BOOL Canonicalize(DWORD dwFlags) throw(); inline void Clear() throw(); BOOL CrackUrl(LPCTSTR lpszUrl, DWORD dwFlags) throw(); inline BOOL CreateUrl(LPTSTR lpszUrl, DWORD* pdwMaxLength, DWORD dwFlags) const throw(); inline LPCTSTR GetExtraInfo() const throw(); inline DWORD GetExtraInfoLength() const throw(); inline LPCTSTR GetHostName() const throw(); inline DWORD GetHostNameLength() const throw(); inline LPCTSTR GetPassword() const throw(); inline DWORD GetPasswordLength() const throw(); inline ATL_URL_PORT GetPortNumber() const throw(); inline ATL_URL_SCHEME GetScheme() const throw(); inline LPCTSTR GetSchemeName() const throw(); inline DWORD GetSchemeNameLength() const throw(); inline DWORD GetUrlLength() const throw(); inline LPCTSTR GetUrlPath() const throw(); inline DWORD GetUrlPathLength() const throw(); inline LPCTSTR GetUserName() const throw(); inline DWORD GetUserNameLength() const throw(); inline BOOL SetExtraInfo(LPCTSTR lpszInfo) throw(); inline BOOL SetHostName(LPCTSTR lpszHost) throw(); inline BOOL SetPassword(LPCTSTR lpszPass) throw(); inline BOOL SetPortNumber(ATL_URL_PORT nPrt) throw(); inline BOOL SetScheme(ATL_URL_SCHEME nScheme) throw(); inline BOOL SetSchemeName(LPCTSTR lpszSchm) throw(); inline BOOL SetUrlPath(LPCTSTR lpszPath) throw(); inline BOOL SetUserName(LPCTSTR lpszUser) throw(); }; void test_CUrl() { char* x = indirect_source(); CUrl url; url.CrackUrl(x, 0); sink(url); // $ ir sink(url.GetExtraInfo()); // $ ir sink(url.GetHostName()); // $ ir sink(url.GetPassword()); // $ ir sink(url.GetSchemeName()); // $ ir sink(url.GetUrlPath()); // $ ir sink(url.GetUserName()); // $ ir { CUrl url2; DWORD len; char buffer[1024]; url2.CrackUrl(x, 0); url2.CreateUrl(buffer, &len, 0); sink(buffer); // $ ast ir } { CUrl url2; url2.SetExtraInfo(x); sink(url2); // $ ir } { CUrl url2; url2.SetHostName(x); sink(url2); // $ ir } { CUrl url2; url2.SetPassword(x); sink(url2); // $ ir } { CUrl url2; url2.SetSchemeName(x); sink(url2); // $ ir } { CUrl url2; url2.SetUrlPath(x); sink(url2); // $ ir } { CUrl url2; url2.SetUserName(x); sink(url2); // $ ir } } struct IAtlStringMgr {}; // simplified using XCHAR = char; using YCHAR = wchar_t; template struct CSimpleStringT { using PCXSTR = const BaseType*; // simplified using PXSTR = BaseType*; // simplified CSimpleStringT() throw(); CSimpleStringT(const XCHAR* pchSrc, int nLength, IAtlStringMgr* pStringMgr); CSimpleStringT(PCXSTR pszSrc, IAtlStringMgr* pStringMgr); CSimpleStringT(const CSimpleStringT& strSrc); ~CSimpleStringT() throw(); void Append(const CSimpleStringT& strSrc); void Append(PCXSTR pszSrc, int nLength); void Append(PCXSTR pszSrc); void AppendChar(XCHAR ch); static void CopyChars(XCHAR* pchDest, const XCHAR* pchSrc, int nChars) throw(); static void CopyChars(XCHAR* pchDest, size_t nDestLen, const XCHAR* pchSrc, int nChars) throw(); static void CopyCharsOverlapped(XCHAR* pchDest, const XCHAR* pchSrc, int nChars) throw(); XCHAR GetAt(int iChar) const; PXSTR GetBuffer(int nMinBufferLength); PXSTR GetBuffer(); PXSTR GetBufferSetLength(int nLength); PCXSTR GetString() const throw(); PXSTR LockBuffer(); void SetAt(int iChar, XCHAR ch); void SetString(PCXSTR pszSrc, int nLength); void SetString(PCXSTR pszSrc); operator PCXSTR() const throw(); XCHAR operator[](int iChar) const; CSimpleStringT& operator+=(PCXSTR pszSrc); CSimpleStringT& operator+=(const CSimpleStringT& strSrc); CSimpleStringT& operator+=(char ch); CSimpleStringT& operator+=(unsigned char ch); CSimpleStringT& operator+=(wchar_t ch); CSimpleStringT& operator=(PCXSTR pszSrc); CSimpleStringT& operator=(const CSimpleStringT& strSrc); }; void test_CSimpleStringT() { char* x = indirect_source(); CSimpleStringT s1(x, 10, nullptr); sink(s1.GetString()); // $ ir CSimpleStringT s2(x, nullptr); sink(s2.GetString()); // $ ir CSimpleStringT s3(s2); sink(s3.GetString()); // $ ir CSimpleStringT s4; s4.Append(indirect_source()); sink(s4.GetString()); // $ ir CSimpleStringT s5; s5.Append(s4); sink(s5.GetString()); // $ ir CSimpleStringT s6; s6.Append(indirect_source(), 42); sink(s6.GetString()); // $ ir char buffer1[128]; CSimpleStringT::CopyChars(buffer1, x, 10); sink(buffer1); // $ ast ir char buffer2[128]; CSimpleStringT::CopyChars(buffer2, 128, x, 10); sink(buffer2); // $ ast ir char buffer3[128]; CSimpleStringT::CopyCharsOverlapped(buffer3, x, 10); sink(buffer3); // $ ast ir sink(s4.GetAt(0)); // $ ir sink(s4.GetBuffer(10)); // $ ir sink(s4.GetBuffer()); // $ ir sink(s4.GetBufferSetLength(10)); // $ ir sink(s4.LockBuffer()); // $ ir CSimpleStringT s7; s7.SetAt(0, source()); sink(s7.GetAt(0)); // $ ir CSimpleStringT s8; s8.SetString(indirect_source()); sink(s8.GetAt(0)); // $ ir CSimpleStringT s9; s9.SetString(indirect_source(), 1024); sink(s9.GetAt(0)); // $ ir sink(static_cast::PCXSTR>(s1)); // $ ir sink(s1[0]); // $ ir } template struct MakeOther {}; template<> struct MakeOther { using other_t = wchar_t; }; template<> struct MakeOther { using other_t = char; }; template struct CStringT : public CSimpleStringT { using XCHAR = BaseType; // simplified using YCHAR = typename MakeOther::other_t; // simplified using PCXSTR = typename CSimpleStringT::PCXSTR; using PXSTR = typename CSimpleStringT::PXSTR; CStringT() throw(); CStringT(IAtlStringMgr* pStringMgr) throw(); CStringT(const VARIANT& varSrc); CStringT(const VARIANT& varSrc, IAtlStringMgr* pStringMgr); CStringT(const CStringT& strSrc); CStringT(const CSimpleStringT& strSrc); CStringT(const XCHAR* pszSrc); CStringT(const YCHAR* pszSrc); CStringT(LPCSTR pszSrc, IAtlStringMgr* pStringMgr); CStringT(LPCWSTR pszSrc, IAtlStringMgr* pStringMgr); CStringT(const unsigned char* pszSrc); CStringT(char* pszSrc); CStringT(unsigned char* pszSrc); CStringT(wchar_t* pszSrc); CStringT(const unsigned char* pszSrc, IAtlStringMgr* pStringMgr); CStringT(char ch, int nLength = 1); CStringT(wchar_t ch, int nLength = 1); CStringT(const XCHAR* pch, int nLength); CStringT(const YCHAR* pch, int nLength); CStringT(const XCHAR* pch, int nLength, IAtlStringMgr* pStringMgr); CStringT(const YCHAR* pch, int nLength, IAtlStringMgr* pStringMgr); operator CSimpleStringT &(); ~CStringT() throw(); BSTR AllocSysString() const; void AppendFormat(PCXSTR pszFormat, ...); void AppendFormat(UINT nFormatID, ...); int Delete(int iIndex, int nCount = 1); int Find(PCXSTR pszSub, int iStart=0) const throw(); int Find(XCHAR ch, int iStart=0) const throw(); int FindOneOf(PCXSTR pszCharSet) const throw(); void Format(UINT nFormatID, ...); void Format(PCXSTR pszFormat, ...); BOOL GetEnvironmentVariable(PCXSTR pszVar); int Insert(int iIndex, PCXSTR psz); int Insert(int iIndex, XCHAR ch); CStringT Left(int nCount) const; BOOL LoadString(HINSTANCE hInstance, UINT nID, WORD wLanguageID); BOOL LoadString(HINSTANCE hInstance, UINT nID); BOOL LoadString(UINT nID); CStringT& MakeLower(); CStringT& MakeReverse(); CStringT& MakeUpper(); CStringT Mid(int iFirst, int nCount) const; CStringT Mid(int iFirst) const; int Replace(PCXSTR pszOld, PCXSTR pszNew); int Replace(XCHAR chOld, XCHAR chNew); CStringT Right(int nCount) const; BSTR SetSysString(BSTR* pbstr) const; CStringT SpanExcluding(PCXSTR pszCharSet) const; CStringT SpanIncluding(PCXSTR pszCharSet) const; CStringT Tokenize(PCXSTR pszTokens, int& iStart) const; CStringT& Trim(XCHAR chTarget); CStringT& Trim(PCXSTR pszTargets); CStringT& Trim(); CStringT& TrimLeft(XCHAR chTarget); CStringT& TrimLeft(PCXSTR pszTargets); CStringT& TrimLeft(); CStringT& TrimRight(XCHAR chTarget); CStringT& TrimRight(PCXSTR pszTargets); CStringT& TrimRight(); }; void test_CStringT() { VARIANT v = source(); CStringT s1(v); sink(s1.GetString()); // $ ir CStringT s2(v, nullptr); sink(s2.GetString()); // $ ir CStringT s3(s2); sink(s3.GetString()); // $ ir char* x = indirect_source(); CStringT s4(x); sink(s4.GetString()); // $ ir wchar_t* y = indirect_source(); CStringT s5(y); sink(s5.GetString()); // $ ir CStringT s6(x, nullptr); sink(s6.GetString()); // $ ir CStringT s7(y, nullptr); sink(s7.GetString()); // $ ir unsigned char* ucs = indirect_source(); CStringT s8(ucs); sink(s8.GetString()); // $ ir char c = source(); CStringT s9(c); sink(s9.GetString()); // $ ir wchar_t wc = source(); CStringT s10(wc); sink(s10.GetString()); // $ ir sink(static_cast&>(s1)); // $ ast ir auto bstr = s1.AllocSysString(); sink(bstr); // $ ir CStringT s11; s11.AppendFormat("%d", source()); sink(s11.GetString()); // $ ir CStringT s12; s12.AppendFormat(indirect_source()); sink(s12.GetString()); // $ ir CStringT s13; s13.AppendFormat(source()); sink(s13.GetString()); // $ ir CStringT s14; s14.AppendFormat(42, source()); sink(s14.GetString()); // $ ir CStringT s15; s15.AppendFormat(42, indirect_source()); sink(s15.GetString()); // $ ir CStringT s16; s16.AppendFormat("%s", indirect_source()); CStringT s17; s17.Insert(0, x); sink(s17.GetString()); // $ ir CStringT s18; s18.Insert(0, source()); sink(s18.GetString()); // $ ir sink(s1.Left(42).GetString()); // $ ir CStringT s20; s20.LoadString(source()); sink(s20.GetString()); // $ ir sink(s1.MakeLower().GetString()); // $ ir sink(s1.MakeReverse().GetString()); // $ ir sink(s1.MakeUpper().GetString()); // $ ir sink(s1.Mid(0, 42).GetString()); // $ ir CStringT s21; s21.Replace("abc", x); sink(s21.GetString()); // $ ir CStringT s22; s22.Replace('\n', source()); sink(s22.GetString()); // $ ir sink(s2.Right(42).GetString()); // $ ir BSTR bstr2; s1.SetSysString(&bstr2); sink(bstr2); // $ ast ir sink(s1.SpanExcluding("abc").GetString()); // $ ir sink(s1.SpanIncluding("abc").GetString()); // $ ir int start = 0; sink(s1.Tokenize("abc", start).GetString()); // $ ir sink(s1.Trim('a').GetString()); // $ ir sink(s1.Trim("abc").GetString()); // $ ir sink(s1.Trim().GetString()); // $ ir sink(s1.TrimLeft('a').GetString()); // $ ir sink(s1.TrimLeft("abc").GetString()); // $ ir sink(s1.TrimLeft().GetString()); // $ ir sink(s1.TrimRight('a').GetString()); // $ ir sink(s1.TrimRight("abc").GetString()); // $ ir sink(s1.TrimRight().GetString()); // $ ir } struct CStringData { void* data() throw(); }; void test_CStringData() { CStringData d = source(); sink(d.data()); // $ ir } template struct CStrBufT { typedef CSimpleStringT StringType; using PCXSTR = typename StringType::PCXSTR; using PXSTR = typename StringType::PXSTR; CStrBufT(StringType& str, int nMinLength, DWORD dwFlags); CStrBufT(StringType& str); operator PCXSTR() const throw(); operator PXSTR() throw(); }; void test_CStrBufT() { CStringT s = source>(); CStrBufT b(s, 42, 0); sink(static_cast::PCXSTR>(b)); // $ ir sink(static_cast::PXSTR>(b)); // $ ir } } namespace Microsoft { namespace WRL { template class ComPtr; struct GUID; typedef GUID IID; typedef IID *REFIID; class IUnknown; class WeakRef; namespace Details { template class ComPtrRef { public: using InterfaceType = T; ComPtrRef(T*); InterfaceType* const * GetAddressOf() const; InterfaceType** ReleaseAndGetAddressOf(); operator InterfaceType**(); operator T*(); operator void**() const; InterfaceType* operator *(); }; } template class ComPtr { public: using InterfaceType = T; ComPtr(); ComPtr(const ComPtr &); ComPtr(ComPtr &&); template ComPtr(U *); ~ComPtr(); template HRESULT As(ComPtr *p) const; HRESULT AsWeak(WeakRef *); void Attach(InterfaceType *); HRESULT CopyTo(InterfaceType **); HRESULT CopyTo(REFIID, void **) const; template HRESULT CopyTo(U **) const; T *Detach(); T *Get() const; T *const *GetAddressOf() const; T **GetAddressOf(); T **ReleaseAndGetAddressOf(); unsigned long Reset(); void Swap(ComPtr &&r); void Swap(ComPtr &r); Details::ComPtrRef> operator&(); const Details::ComPtrRef> operator&() const; InterfaceType* operator->() const; // return type simplified from Microsoft::WRL::Details::RemoveIUnknown* ComPtr& operator=(T *); template ComPtr& operator=(U *); ComPtr& operator=(const ComPtr &); template ComPtr& operator=(const ComPtr&); ComPtr& operator=(ComPtr &&); template ComPtr& operator=(ComPtr&&); }; } } namespace std { template T&& move(T& t) noexcept; // simplified signature } void test_constructor() { Microsoft::WRL::ComPtr p0; sink(*p0.Get()); // clean int x = source(); Microsoft::WRL::ComPtr p1(new int(x)); sink(*p1.Get()); // $ ir MISSING: ast sink(*p1.Detach()); // $ ir MISSING: ast Microsoft::WRL::ComPtr p2(p1); sink(*p2.Get()); // $ ir MISSING: ast Microsoft::WRL::ComPtr p3(std::move(p1)); sink(*p3.Get()); // $ ir MISSING: ast } void test_As() { int x = source(); Microsoft::WRL::ComPtr p1(new int(x)); Microsoft::WRL::ComPtr* p2; p1.As(p2); sink(*p2->Get()); // $ ir MISSING: ast } void test_CopyTo() { int x = source(); Microsoft::WRL::ComPtr p1(new int(x)); int *raw = nullptr; p1.CopyTo(&raw); sink(*raw); // $ ir MISSING: ast Microsoft::WRL::ComPtr p2; p1.CopyTo(nullptr, (void**)&raw); sink(*raw); // $ ir MISSING: ast Microsoft::WRL::ComPtr p3(new int(x)); int* raw2 = nullptr; p3.CopyTo(&raw2); sink(*raw2); // $ ir MISSING: ast } void test_Swap() { int x = source(); Microsoft::WRL::ComPtr p1(new int(x)); Microsoft::WRL::ComPtr p2; p1.Swap(p2); sink(*p2.Get()); // $ ir MISSING: ast sink(*p1.Get()); // $ SPURIOUS: ir } void test_GetAddressOf() { int x = source(); Microsoft::WRL::ComPtr p1(new int(x)); sink(**p1.GetAddressOf()); // $ ir MISSING: ast const Microsoft::WRL::ComPtr p2(new int(x)); sink(**p2.GetAddressOf()); // $ ir MISSING: ast Microsoft::WRL::ComPtr p3(new int(x)); int **pp = p3.ReleaseAndGetAddressOf(); sink(**pp); // $ ir MISSING: ast } struct S { int x; }; void test_address_of_deref_operators() { int x = source(); Microsoft::WRL::ComPtr p1(new int(x)); Microsoft::WRL::Details::ComPtrRef> pp = &p1; Microsoft::WRL::ComPtr* qq = *pp; sink(*qq->Get()); // $ MISSING: ast,ir const Microsoft::WRL::ComPtr p2(new int(x)); Microsoft::WRL::Details::ComPtrRef> pp2 = &p2; const Microsoft::WRL::ComPtr* qq2 = *pp2; sink(*qq2->Get()); // $ MISSING: ast,ir S s; s.x = source(); Microsoft::WRL::ComPtr p3(&s); sink(p3->x); // $ MISSING: ast,ir } void test_assignments() { Microsoft::WRL::ComPtr p1; p1 = new int(source()); sink(*p1.Get()); // $ MISSING: ast,ir Microsoft::WRL::ComPtr p2; p2 = new long(source()); sink(*p2.Get()); // $ MISSING: ast,ir Microsoft::WRL::ComPtr p3; p3 = p1; sink(*p3.Get()); // $ MISSING: ast,ir Microsoft::WRL::ComPtr p4; p4 = p1; sink(*p4.Get()); // $ MISSING: ast,ir Microsoft::WRL::ComPtr p5; p5 = std::move(p1); sink(*p5.Get()); // $ MISSING: ast,ir Microsoft::WRL::ComPtr p6; p6 = std::move(p1); sink(*p6.Get()); // $ MISSING: ast,ir }