Skip to content
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

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

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 @@ -141,6 +141,10 @@ New check aliases
Changes in existing checks
^^^^^^^^^^^^^^^^^^^^^^^^^^

- 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.
nicovank marked this conversation as resolved.
Show resolved Hide resolved

- Improved :doc:`bugprone-casting-through-void
<clang-tidy/checks/bugprone/casting-through-void>` check to suggest replacing
the offending code with ``reinterpret_cast``, to more clearly express intent.
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
}
Loading