Skip to content

Commit

Permalink
Reenable some disabled warnings in CoreCLR (#34659)
Browse files Browse the repository at this point in the history
* First fixes to print hex without silencing warning 4477.

* After the previous commit, dasm.cpp started showing abnormalities.

* Warning 4302 reenable iteration 1

* Warning 4302 reenable iteration 2

* Warning 4312 reenable: Iteration 1

* Warning 4312 reenable: Iteration 2

* Updated configurecompiler.cmake comments with newly reenabled warnings.

* Fixed a comment.

* Fixed a 32-bit issue with printing formats as well as a scope issue on Linux.

* Warning 4302/4311/4477 reenable: Fixed Checked Builds.

* Warning 4302/4311/4477 iteration 3

* Warning 4477 reenable iteration 4: ToString of bits.

* Fixed an unsigned long long for x86.

* Fixed 4477 on x86 for real this time.

* Changed two bitness checks for size_t usage instead.
  • Loading branch information
ivdiazsa committed Apr 9, 2020
1 parent 26b6e4e commit 62d8baf
Show file tree
Hide file tree
Showing 23 changed files with 69 additions and 71 deletions.
6 changes: 1 addition & 5 deletions eng/native/configurecompiler.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -439,11 +439,7 @@ if (MSVC)

# Disable Warnings:
# 4291: Delete not defined for new, c++ exception may cause leak.
# 4302: Truncation from '%$S' to '%$S'.
# 4311: Pointer truncation from '%$S' to '%$S'.
# 4312: '<function-style-cast>' : conversion from '%$S' to '%$S' of greater size.
# 4477: Format string '%$S' requires an argument of type '%$S', but variadic argument %d has type '%$S'.
add_compile_options(/wd4291 /wd4302 /wd4311 /wd4312 /wd4477)
add_compile_options(/wd4291)

# Treat Warnings as Errors:
# 4007: 'main' : must be __cdecl.
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/src/debug/daccess/daccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7302,7 +7302,7 @@ ClrDataAccess::GetDacGlobals()
}

if (FAILED(status = GetResourceRvaFromResourceSectionRvaByName(m_pTarget, m_globalBase,
resourceSectionRVA, (DWORD)RT_RCDATA, _WIDE(DACCESS_TABLE_RESOURCE), 0,
resourceSectionRVA, (DWORD)(size_t)RT_RCDATA, _WIDE(DACCESS_TABLE_RESOURCE), 0,
&rsrcRVA, &rsrcSize)))
{
_ASSERTE_MSG(false, "DAC fatal error: can't locate DAC table resource in " TARGET_MAIN_CLR_DLL_NAME_A);
Expand Down Expand Up @@ -7351,9 +7351,9 @@ ClrDataAccess::GetDacGlobals()
#ifdef _DEBUG
char szMsgBuf[1024];
_snprintf_s(szMsgBuf, sizeof(szMsgBuf), _TRUNCATE,
"DAC fatal error: mismatch in number of globals in DAC table. Read from file: %d, expected: %d.",
"DAC fatal error: mismatch in number of globals in DAC table. Read from file: %d, expected: %zd.",
header.numGlobals,
offsetof(DacGlobals, EEJitManager__vtAddr) / sizeof(ULONG));
(size_t)offsetof(DacGlobals, EEJitManager__vtAddr) / sizeof(ULONG));
_ASSERTE_MSG(false, szMsgBuf);
#endif // _DEBUG

Expand All @@ -7366,9 +7366,9 @@ ClrDataAccess::GetDacGlobals()
#ifdef _DEBUG
char szMsgBuf[1024];
_snprintf_s(szMsgBuf, sizeof(szMsgBuf), _TRUNCATE,
"DAC fatal error: mismatch in number of vptrs in DAC table. Read from file: %d, expected: %d.",
"DAC fatal error: mismatch in number of vptrs in DAC table. Read from file: %d, expected: %zd.",
header.numVptrs,
(sizeof(DacGlobals) - offsetof(DacGlobals, EEJitManager__vtAddr)) / sizeof(ULONG));
(size_t)(sizeof(DacGlobals) - offsetof(DacGlobals, EEJitManager__vtAddr)) / sizeof(ULONG));
_ASSERTE_MSG(false, szMsgBuf);
#endif // _DEBUG

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/debug/di/process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12788,7 +12788,7 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven
PORTABILITY_ASSERT("NYI: Breakpoint size offset for this platform");
#endif
_ASSERTE(CORDbgGetIP(&tempDebugContext) == pEvent->u.Exception.ExceptionRecord.ExceptionAddress ||
(DWORD)CORDbgGetIP(&tempDebugContext) == ((DWORD)pEvent->u.Exception.ExceptionRecord.ExceptionAddress)+breakpointOpcodeSize);
(DWORD)(size_t)CORDbgGetIP(&tempDebugContext) == ((DWORD)(size_t)pEvent->u.Exception.ExceptionRecord.ExceptionAddress)+breakpointOpcodeSize);
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/debug/ee/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13947,7 +13947,7 @@ void GenericHijackFuncHelper()
if (pEEThread != NULL)
{
// We've got a Thread ptr, so get the continue type out of the thread's debugger word.
continueType = (DWORD)threadDebuggerWord;
continueType = (DWORD)(size_t) threadDebuggerWord;

_ASSERTE(pEEThread->GetInteropDebuggingHijacked());
pEEThread->SetInteropDebuggingHijacked(FALSE);
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/src/ildasm/dasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3824,7 +3824,7 @@ lDone: ;
}
else
{
sprintf_s(szString,SZSTRING_SIZE, "INVALID METHOD ADDRESS: 0x%8.8X (RVA: 0x%8.8X)",(size_t)newTarget,dwTargetRVA);
sprintf_s(szString,SZSTRING_SIZE, "INVALID METHOD ADDRESS: 0x%8.8zX (RVA: 0x%8.8X)",(size_t)newTarget,dwTargetRVA);
printError(GUICookie,szString);
}
}
Expand Down Expand Up @@ -4987,7 +4987,7 @@ void DumpVTables(IMAGE_COR20_HEADER *CORHeader, void* GUICookie)
}
else
{
sprintf_s(szString,SZSTRING_SIZE,"// [0x%04x] (0x%16x)", iSlot, VAL64(*(unsigned __int64 *) pSlot));
sprintf_s(szString,SZSTRING_SIZE,"// [0x%04x] (0x%16llx)", iSlot, VAL64(*(unsigned __int64 *) pSlot));
pSlot += sizeof(unsigned __int64);
}
printLine(GUICookie,szStr);
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/src/inc/holder.h
Original file line number Diff line number Diff line change
Expand Up @@ -608,9 +608,9 @@ class BaseWrapper : public BaseHolder<TYPE, BASE, DEFAULTVALUE, IS_NULL>
{
return !!(this->m_value != TYPE(value));
}
#ifdef __GNUC__
// This handles the NULL value that is an int and clang
// doesn't want to convert int to a pointer

// This handles the NULL value that is an int and the
// compiler doesn't want to convert int to a pointer.
FORCEINLINE bool operator==(int value) const
{
return !!(this->m_value == TYPE((void*)(SIZE_T)value));
Expand All @@ -619,7 +619,7 @@ class BaseWrapper : public BaseHolder<TYPE, BASE, DEFAULTVALUE, IS_NULL>
{
return !!(this->m_value != TYPE((void*)(SIZE_T)value));
}
#endif // __GNUC__

FORCEINLINE const TYPE &operator->() const
{
return this->m_value;
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/src/inc/stdmacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,13 @@
#define INVALID_POINTER_CD 0xcdcdcdcdcdcdcdcd
#define FMT_ADDR " %08x`%08x "
#define LFMT_ADDR W(" %08x`%08x ")
#define DBG_ADDR(ptr) (((UINT_PTR) (ptr)) >> 32), (((UINT_PTR) (ptr)) & 0xffffffff)
#define DBG_ADDR(ptr) (DWORD)(((UINT_PTR) (ptr)) >> 32), (DWORD)(((UINT_PTR) (ptr)) & 0xffffffff)
#else // HOST_64BIT
#define INVALID_POINTER_CC 0xcccccccc
#define INVALID_POINTER_CD 0xcdcdcdcd
#define FMT_ADDR " %08x "
#define LFMT_ADDR W(" %08x ")
#define DBG_ADDR(ptr) ((UINT_PTR)(ptr))
#define DBG_ADDR(ptr) (DWORD)((UINT_PTR)(ptr))
#endif // HOST_64BIT

#ifdef TARGET_ARM
Expand Down
44 changes: 22 additions & 22 deletions src/coreclr/src/inc/utilcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -4844,62 +4844,62 @@ inline T* InterlockedCompareExchangeT(
// to the appropriate pointer type.
template <typename T>
inline T* InterlockedExchangeT(
T* volatile * target,
int value) // When NULL is provided as argument.
T* volatile * target,
std::nullptr_t value) // When nullptr is provided as argument.
{
//STATIC_ASSERT(value == 0);
return InterlockedExchangeT(target, reinterpret_cast<T*>(value));
return InterlockedExchangeT(target, static_cast<T*>(value));
}

template <typename T>
inline T* InterlockedCompareExchangeT(
T* volatile * destination,
int exchange, // When NULL is provided as argument.
T* comparand)
T* volatile * destination,
std::nullptr_t exchange, // When nullptr is provided as argument.
T* comparand)
{
//STATIC_ASSERT(exchange == 0);
return InterlockedCompareExchangeT(destination, reinterpret_cast<T*>(exchange), comparand);
return InterlockedCompareExchangeT(destination, static_cast<T*>(exchange), comparand);
}

template <typename T>
inline T* InterlockedCompareExchangeT(
T* volatile * destination,
T* exchange,
int comparand) // When NULL is provided as argument.
T* volatile * destination,
T* exchange,
std::nullptr_t comparand) // When nullptr is provided as argument.
{
//STATIC_ASSERT(comparand == 0);
return InterlockedCompareExchangeT(destination, exchange, reinterpret_cast<T*>(comparand));
return InterlockedCompareExchangeT(destination, exchange, static_cast<T*>(comparand));
}

// NULL pointer variants of the above to avoid having to cast NULL
// to the appropriate pointer type.
template <typename T>
inline T* InterlockedExchangeT(
T* volatile * target,
std::nullptr_t value) // When nullptr is provided as argument.
T* volatile * target,
int value) // When NULL is provided as argument.
{
//STATIC_ASSERT(value == 0);
return InterlockedExchangeT(target, static_cast<T*>(value));
return InterlockedExchangeT(target, nullptr);
}

template <typename T>
inline T* InterlockedCompareExchangeT(
T* volatile * destination,
std::nullptr_t exchange, // When nullptr is provided as argument.
T* comparand)
T* volatile * destination,
int exchange, // When NULL is provided as argument.
T* comparand)
{
//STATIC_ASSERT(exchange == 0);
return InterlockedCompareExchangeT(destination, static_cast<T*>(exchange), comparand);
return InterlockedCompareExchangeT(destination, nullptr, comparand);
}

template <typename T>
inline T* InterlockedCompareExchangeT(
T* volatile * destination,
T* exchange,
std::nullptr_t comparand) // When nullptr is provided as argument.
T* volatile * destination,
T* exchange,
int comparand) // When NULL is provided as argument.
{
//STATIC_ASSERT(comparand == 0);
return InterlockedCompareExchangeT(destination, exchange, static_cast<T*>(comparand));
return InterlockedCompareExchangeT(destination, exchange, nullptr);
}

#undef InterlockedExchangePointer
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/src/jit/bitsetasshortlong.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,12 +412,12 @@ class BitSetOps</*BitSetType*/ BitSetShortLongRep,
char* ptr = res;
if (sizeof(size_t) == sizeof(int64_t))
{
sprintf_s(ptr, remaining, "%016llX", bits);
sprintf_s(ptr, remaining, "%016zX", bits);
}
else
{
assert(sizeof(size_t) == sizeof(int));
sprintf_s(ptr, remaining, "%08X", bits);
sprintf_s(ptr, remaining, "%08X", (DWORD)bits);
}
return res;
}
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/src/md/enc/stgtiggerstorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -993,15 +993,15 @@ ULONG TiggerStorage::PrintSizeInfo(bool verbose)
{
ULONG total = 0;

printf("Storage Header: %d\n", sizeof(STORAGEHEADER));
printf("Storage Header: %zu\n", sizeof(STORAGEHEADER));
if (m_pStreamList != NULL)
{
PSTORAGESTREAM storStream = m_pStreamList;
PSTORAGESTREAM pNext;
for (int i = 0; i < m_StgHdr.GetiStreams(); i++)
{
pNext = storStream->NextStream();
printf("Stream #%d (%s) Header: %d, Data: %d\n",i,storStream->GetName(), (BYTE*)pNext - (BYTE*)storStream, storStream->GetSize());
printf("Stream #%d (%s) Header: %zd, Data: %lu\n",i,storStream->GetName(), (size_t)((BYTE*)pNext - (BYTE*)storStream), storStream->GetSize());
total += storStream->GetSize();
storStream = pNext;
}
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/src/utilcode/loaderheap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,8 +594,8 @@ class LoaderHeapSniffer

}
printf(" ptr = 0x%-8p", pEvent->m_pMem);
printf(" rqsize = 0x%-8x", pEvent->m_dwRequestedSize);
printf(" actsize = 0x%-8x", pEvent->m_dwSize);
printf(" rqsize = 0x%-8x", (DWORD)pEvent->m_dwRequestedSize);
printf(" actsize = 0x%-8x", (DWORD)pEvent->m_dwSize);
printf(" (at %s@%d)", pEvent->m_szFile, pEvent->m_lineNum);
if (pEvent->m_allocationType == kFreedMem)
{
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/src/utilcode/stacktrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -793,8 +793,10 @@ CONTEXT * pContext // Context to use (or NULL to use current)

#ifdef HOST_64BIT
#define FMT_ADDR_BARE "%08x`%08x"
#define FMT_ADDR_OFFSET "%llX"
#else
#define FMT_ADDR_BARE "%08x"
#define FMT_ADDR_OFFSET "%lX"
#endif

void GetStringFromSymbolInfo
Expand All @@ -816,15 +818,14 @@ __out_ecount (cchMaxAssertStackLevelStringLen) CHAR *pszString // @parm Plac
{
sprintf_s(pszString,
cchMaxAssertStackLevelStringLen,
"%s! %s + 0x%X (0x" FMT_ADDR_BARE ")",
"%s! %s + 0x" FMT_ADDR_OFFSET " (0x" FMT_ADDR_BARE ")",
(psi->achModule[0]) ? psi->achModule : "<no module>",
(psi->achSymbol[0]) ? psi->achSymbol : "<no symbol>",
psi->dwOffset,
DBG_ADDR(dwAddr));
}
else
{

sprintf_s(pszString, cchMaxAssertStackLevelStringLen, "<symbols not available> (0x%p)", (void *)dwAddr);
}

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/vm/comcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ class CtxEntryCacheTraits : public DefaultSHashTraits<CtxEntry *>
static CtxEntry *Null() { LIMITED_METHOD_CONTRACT; return NULL; }
static bool IsNull(CtxEntry *e) { LIMITED_METHOD_CONTRACT; return (e == NULL); }
static const LPVOID GetKey(CtxEntry *e) { LIMITED_METHOD_CONTRACT; return e->GetCtxCookie(); }
static count_t Hash(LPVOID key_t) { LIMITED_METHOD_CONTRACT; return (count_t) key_t; }
static count_t Hash(LPVOID key_t) { LIMITED_METHOD_CONTRACT; return (count_t)(size_t) key_t; }
static BOOL Equals(LPVOID lhs, LPVOID rhs) { LIMITED_METHOD_CONTRACT; return (lhs == rhs); }
static CtxEntry *Deleted() { LIMITED_METHOD_CONTRACT; return (CtxEntry *)-1; }
static bool IsDeleted(CtxEntry *e) { LIMITED_METHOD_CONTRACT; return e == (CtxEntry *)-1; }
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/vm/compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3024,7 +3024,7 @@ HRESULT NGenModulePdbWriter::WritePDBData()
if (strcmp((const char *)&section[sectionIndex].Name[0], ".text") == 0) {
_ASSERTE((iCodeSection == 0) && (pCodeBase == NULL));
iCodeSection = (USHORT)(sectionIndex + 1);
pCodeBase = (BYTE *)section[sectionIndex].VirtualAddress;
pCodeBase = (BYTE *)(size_t)section[sectionIndex].VirtualAddress;
}

// In order to support the DIA RVA-to-lines API against the PDB we're
Expand Down
12 changes: 6 additions & 6 deletions src/coreclr/src/vm/debughelp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ WCHAR* formatMethodDesc(MethodDesc* pMD,
}
#endif

if(_snwprintf_s(&buff[wcslen(buff)], bufSize - wcslen(buff) - 1, _TRUNCATE, W("(%x)"), (size_t)pMD) < 0)
if(_snwprintf_s(&buff[wcslen(buff)], bufSize - wcslen(buff) - 1, _TRUNCATE, W("(%zx)"), (size_t)pMD) < 0)
{
return NULL;
}
Expand Down Expand Up @@ -477,7 +477,7 @@ int dumpStack(BYTE* topOfStack, unsigned len)

if (isRetAddr((TADDR)*ptr, &whereCalled))
{
if (_snwprintf_s(buffPtr, buffEnd - buffPtr, _TRUNCATE, W("STK[%08X] = %08X "), (size_t)ptr, *ptr) < 0)
if (_snwprintf_s(buffPtr, buffEnd - buffPtr, _TRUNCATE, W("STK[%08X] = %08X "), (DWORD)(size_t)ptr, (DWORD)*ptr) < 0)
{
return(0);
}
Expand Down Expand Up @@ -545,7 +545,7 @@ int dumpStack(BYTE* topOfStack, unsigned len)

if (whereCalled != 0)
{
if (_snwprintf_s(buffPtr, buffEnd - buffPtr, _TRUNCATE, W(" Caller called Entry %X"), whereCalled) < 0)
if (_snwprintf_s(buffPtr, buffEnd - buffPtr, _TRUNCATE, W(" Caller called Entry %zX"), (size_t)whereCalled) < 0)
{
return(0);
}
Expand All @@ -562,7 +562,7 @@ int dumpStack(BYTE* topOfStack, unsigned len)
if (pMT != 0)
{
buffPtr = buff;
if ( _snwprintf_s(buffPtr, buffEnd - buffPtr, _TRUNCATE, W("STK[%08X] = %08X MT PARAM "), (size_t)ptr, *ptr ) < 0)
if ( _snwprintf_s(buffPtr, buffEnd - buffPtr, _TRUNCATE, W("STK[%08X] = %08X MT PARAM "), (DWORD)(size_t)ptr, (DWORD)*ptr ) < 0)
{
return(0);
}
Expand Down Expand Up @@ -865,7 +865,7 @@ StackWalkAction PrintStackTraceCallback(CrawlFrame* pCF, VOID* pData)
if(_snwprintf_s(&buff[wcslen(buff)],
nLen - wcslen(buff) - 1,
_TRUNCATE,
W("JIT ESP:%X MethStart:%X EIP:%X(rel %X)"),
W("JIT ESP:%zX MethStart:%zX EIP:%zX(rel %X)"),
(size_t)GetRegdisplaySP(regs),
(size_t)start,
(size_t)GetControlPC(regs),
Expand Down Expand Up @@ -893,7 +893,7 @@ StackWalkAction PrintStackTraceCallback(CrawlFrame* pCF, VOID* pData)
nLen - wcslen(buff) - 1,
_TRUNCATE,
W("EE Frame is") LFMT_ADDR,
(size_t)DBG_ADDR(frame)) < 0)
DBG_ADDR(frame)) < 0)
{
return SWA_CONTINUE;
}
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/vm/frames.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ void Frame::LogFrame(
{
_ASSERTE(!"New Frame type needs to be added to FrameTypeName()");
// Pointer is up to 17chars + vtbl@ = 22 chars
sprintf_s(buf, COUNTOF(buf), "vtbl@%p", GetVTablePtr());
sprintf_s(buf, COUNTOF(buf), "vtbl@%p", (VOID *)GetVTablePtr());
pFrameType = buf;
}

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/vm/interoplibinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ namespace
public:
using key_t = void*;
static const key_t GetKey(_In_ element_t e) { LIMITED_METHOD_CONTRACT; return (key_t)e->Identity; }
static count_t Hash(_In_ key_t key) { LIMITED_METHOD_CONTRACT; return (count_t)key; }
static count_t Hash(_In_ key_t key) { LIMITED_METHOD_CONTRACT; return (count_t)(size_t)key; }
static bool Equals(_In_ key_t lhs, _In_ key_t rhs) { LIMITED_METHOD_CONTRACT; return (lhs == rhs); }
};

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/vm/invokeutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ OBJECTREF InvokeUtil::CreateObjectAfterInvoke(TypeHandle th, void * pValue) {
case ELEMENT_TYPE_FNPTR:
{
LPVOID capturedValue = *(LPVOID*)pValue;
INDEBUG(pValue = (LPVOID)0xcccccccc); // We're about to allocate a GC object - can no longer trust pValue
INDEBUG(pValue = (LPVOID)(size_t)0xcccccccc); // We're about to allocate a GC object - can no longer trust pValue
obj = AllocateObject(MscorlibBinder::GetElementType(ELEMENT_TYPE_I));
*(LPVOID*)(obj->UnBox()) = capturedValue;
}
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/src/vm/methodtable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1870,7 +1870,7 @@ MethodTable::DebugDumpVtable(LPCUTF8 szClassName, BOOL fDebug)
name,
pszName,
IsMdFinal(dwAttrs) ? " (final)" : "",
pMD->GetMethodEntryPoint(),
(VOID *)pMD->GetMethodEntryPoint(),
pMD->GetSlot()
);
WszOutputDebugString(buff);
Expand All @@ -1884,7 +1884,7 @@ MethodTable::DebugDumpVtable(LPCUTF8 szClassName, BOOL fDebug)
pMD->GetClass()->GetDebugClassName(),
pszName,
IsMdFinal(dwAttrs) ? " (final)" : "",
pMD->GetMethodEntryPoint(),
(VOID *)pMD->GetMethodEntryPoint(),
pMD->GetSlot()
));
}
Expand Down
Loading

0 comments on commit 62d8baf

Please sign in to comment.