Skip to content

Conversation

mptre
Copy link
Contributor

@mptre mptre commented Oct 4, 2025

This has bitten me before and is definitely a foot gun. GCC 15[1] changed their semantics related to zero initialization of unions; from initializing the complete union (sizeof union) to only zero initializing the first member. If the same first member is not the largest one, the state of the remaining storage is considered undefined and in practice most likely stack garbage.

The unionzeroinit checker can detect such scenarios and emit a warning. It does not cover the designated initializers as I would interpret those as being intentional.

Example output from one of my projects:

x86-decoder.c:294:7: warning: Zero initializing union Evex does not guarantee its complete storage to be zero initialized as its largest member is not declared as the first member. Consider making u32 the first member or favor memset(). [unionzeroinit-unionzeroinit]
 Evex evex = {0};
      ^

[1] https://trofi.github.io/posts/328-c-union-init-and-gcc-15.html

@mptre
Copy link
Contributor Author

mptre commented Oct 4, 2025

Second attempt of #7843 which accidently got merged.

Copy link
Owner

@danmar danmar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this. I think it looks good overall but have some nits.

Please write a little description in the CheckOther::classInfo() method.

please add a line in the releasenotes.txt

@mptre
Copy link
Contributor Author

mptre commented Oct 9, 2025

I hope all feedback have been addressed at this point.

This has bitten me before and is definitely a foot gun. GCC 15[1] changed their
semantics related to zero initialization of unions; from initializing the
complete union (sizeof union) to only zero initializing the first member. If the
same first member is not the largest one, the state of the remaining storage is
considered undefined and in practice most likely stack garbage.

The unionzeroinit checker can detect such scenarios and emit a warning. It does
not cover the designated initializers as I would interpret those as being
intentional.

Example output from one of my projects:

```
x86-decoder.c:294:7: warning: Zero initializing union Evex does not guarantee its complete storage to be zero initialized as its largest member is not declared as the first member. Consider making u32 the first member or favor memset(). [unionzeroinit-unionzeroinit]
 Evex evex = {0};
      ^
```

[1] https://trofi.github.io/posts/328-c-union-init-and-gcc-15.html
Copy link

sonarqubecloud bot commented Oct 9, 2025

@danmar danmar merged commit cded51e into danmar:main Oct 12, 2025
53 checks passed
@danmar
Copy link
Owner

danmar commented Oct 12, 2025

@mptre thanks.. now I merged it by intention :-)

please close the ticket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants