-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Usage of memset with non-trivial types that results in -Wclass-memaccess #12684
Comments
That would be ideal but I'm afraid that at least in the JIT code you'll find some cases that might be difficult to fix like that. So 2. will probably be needed as well, if it doesn't cause other problems. |
How many places do hit this warning - could you please share the list (as gist if it is too long)? |
cd coreclr
./build.sh -skiprestore -skipmanaged -gcc &> build-output.txt
# count unique lines
cat build-output.txt | grep class-memaccess | uniq -uc | wc -l
# => 1646
# filter output file with afterLines=2 and replace newline with literal '\n'
CONTENTS=`cat build-output.txt | grep -A 2 class-memaccess | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g'`
# write gist API request body to a temp file
echo "{\"public\":false,\"files\":{\"class-memaccess.txt\":{\"content\":\"$CONTENTS\"}}}" > class-memaccess-gist.txt
# send to github server using access token
curl -X POST -d @class-memaccess-gist.txt -u <personal-access-token-with-'gist'-scope>:x-oauth-basic https://api.github.com/gists |
@jkotas, I have found few places while fixing some of these warnings in runtime/src/coreclr/src/vm/class.h Line 2157 in e7ce09d
|
It is easy to notice that it is a uninitialized value when debugging. It is why it is done only under |
The specific one you have linked is getting major refactoring in dotnet/coreclr#1828. |
By type casting the pointer to an AllocatorTableEntry to be 'void*', this will circumvent the typecheck being done by gcc 8 or higher to determine whether the object is a POD or not. (see: dotnet/runtime#12684) Prior to this change, this warning would be triggered in GCC 10.2.1: error: 'void* memset(void*, int, size_t)' clearing an object of non-trivial type` It is unclear why gcc is considering this POD to be non-trivial.
By type casting the pointer to an AllocatorTableEntry to be 'void*', this will circumvent the typecheck being done by gcc 8 or higher to determine whether the object is a POD or not. (see: dotnet/runtime#12684) Prior to this change, this warning would be triggered in GCC 10.2.1: error: 'void* memset(void*, int, size_t)' clearing an object of non-trivial type` It is unclear why gcc is considering this POD to be non-trivial.
There are numerous places gcc-12 complains about memset being called to zero the entire object when the object is not Plain Old Data (POD). (The C++ standard haas a more encompassing definition than POD.) Consider runtime/src/coreclr/vm/syncblk.h Line 631 in 3e0a5ad
InteropSyncBlockInfo has a lot of non-trivial data, some of which will (likely?) have constructors fired on them, and the memset is a blunt hammer to zero out everything, perhaps leaving embedded objects in an inconsistent and buggy state. |
I went through and added gcc diagnostic suppressions throughout the code base as needed to get to compile with gcc12. There were 41 files changed with ~50 changes. See attached file It is conceivable that the CONTRACT semantics of some of the callers to memset tell some compiler that memset is safe, but gcc certainly doesn't know about that. |
Starting with gcc 8, compiler is warning about several usages of
memset
in case of types that arenon-trivially copyable. This includes
struct
s inheritingstruct ZeroInit
, usage ofFillMemory
andZeroMemory
macros (defined inpal.h
) and other places which are directly calling the function (although some of those places can make use of the defined macro as it stands).From release notes (https://www.gnu.org/software/gcc/gcc-8/changes.html):
LLVM has included
-Wnontrivial-memaccess
for C structs and there are also considerations to add-Wclass-memaccess
in future: https://reviews.llvm.org/D45310Reading the community discussions about practices pertaining to usage of
memset
with non-POD types and how others have responded to the gcc warning, I think there are three ways to fix this (in descending order of preference):std:fill
and friends for non-trivial data structures.void*
to circumvent the type check.-Wno-class-memaccess
.The text was updated successfully, but these errors were encountered: