Skip to content

[clang-tidy] Fix for cppcoreguidelines-pro-type-union-access if memLoc is invalid #104540

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

Merged
merged 10 commits into from
Oct 23, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ void ProTypeUnionAccessCheck::registerMatchers(MatchFinder *Finder) {

void ProTypeUnionAccessCheck::check(const MatchFinder::MatchResult &Result) {
const auto *Matched = Result.Nodes.getNodeAs<MemberExpr>("expr");
diag(Matched->getMemberLoc(),
"do not access members of unions; use (boost::)variant instead");
SourceLocation Loc = Matched->getMemberLoc();
if (Loc.isInvalid())
Loc = Matched->getBeginLoc();
diag(Loc, "do not access members of unions; consider using (boost::)variant "
"instead");
}

} // namespace clang::tidy::cppcoreguidelines
4 changes: 4 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ Changes in existing checks
avoid false positive when member initialization depends on a structured
binding variable.

- Fixed :doc:`cppcoreguidelines-pro-type-union-access
<clang-tidy/checks/cppcoreguidelines/pro-type-union-access>` check to
report a location even when the member location is not valid.

- Improved :doc:`misc-definitions-in-headers
<clang-tidy/checks/misc/definitions-in-headers>` check by rewording the
diagnostic note that suggests adding ``inline``.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ union U {
char union_member2;
} u;

union W {
template <class TP> operator TP *() const;
};

struct S {
int non_union_member;
union {
Expand All @@ -20,22 +24,25 @@ void f(char);
void f2(U);
void f3(U&);
void f4(U*);
W f5();

void check()
{
u.union_member1 = true;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not access members of unions; use (boost::)variant instead [cppcoreguidelines-pro-type-union-access]
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not access members of unions; consider using (boost::)variant instead [cppcoreguidelines-pro-type-union-access]
auto b = u.union_member2;
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not access members of unions; use (boost::)variant instead
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not access members of unions; consider using (boost::)variant instead
auto a = &s.union_member;
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not access members of unions; use (boost::)variant instead
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not access members of unions; consider using (boost::)variant instead
f(s.u.union_member2);
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not access members of unions; use (boost::)variant instead
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not access members of unions; consider using (boost::)variant instead

s.non_union_member = 2; // OK

U u2 = u; // OK
f2(u); // OK
f3(u); // OK
f4(&u); // OK
void *ret = f5();
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not access members of unions; consider using (boost::)variant instead
}