[clang-tools-extra] [clang-tidy] Fix false positive in readability-make-member-function-c… (PR #174286)
Arthur Courteaud via cfe-commits
cfe-commits at lists.llvm.org
Sat Jan 3 10:51:23 PST 2026
https://github.com/arthur3336 updated https://github.com/llvm/llvm-project/pull/174286
>From 0405716b07316c776316188c89f050a740038920 Mon Sep 17 00:00:00 2001
From: Arthur Courteaud <arthurcourteaud at gmail.com>
Date: Sat, 3 Jan 2026 19:18:54 +0100
Subject: [PATCH] [clang-tidy] Fix false positive in
readability-make-member-function-const for unions with pointer/reference
members
Fixes #174269
The check incorrectly suggested adding const to member functions that
return non-const references from dereferencing pointer members within
unions. Union members share memory, making such cases inherently
non-const-safe.
Added special handling to detect pointer/reference members within unions
and correctly mark them as non-const usage.
---
.../MakeMemberFunctionConstCheck.cpp | 11 ++++
.../make-member-function-const.cpp | 50 +++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
index 2e6edd706b131..7b9ecb99a3c60 100644
--- a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
@@ -154,6 +154,17 @@ class FindUsageOfThis : public RecursiveASTVisitor<FindUsageOfThis> {
// 1) has builtin type (a 'const int' cannot be modified),
// 2) or it's a public member (the pointee of a public 'int * const' can
// can be modified by any user of the class).
+
+ // Union members are never safe for pointer/reference types
+ // (all union members share memory).
+ if (const auto *Field = dyn_cast<FieldDecl>(Member->getMemberDecl())) {
+ if (Field->getParent()->isUnion()) {
+ QualType MemberType = Field->getType();
+ if (MemberType->isPointerType() || MemberType->isReferenceType())
+ return false;
+ }
+ }
+
if (Member->getFoundDecl().getAccess() != AS_public &&
!Cast->getType()->isBuiltinType())
return false;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/make-member-function-const.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/make-member-function-const.cpp
index 72a8e362b9c8a..7cdd9bfd7819a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/make-member-function-const.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/make-member-function-const.cpp
@@ -336,3 +336,53 @@ struct MemberFunctionPointer {
};
} // namespace Keep
+
+namespace UnionMemberAccess {
+ // Test case from GitHub issue #174269
+ // Union with pointer member returning non-const reference
+ struct UnionWithPointer {
+ union { int* resource; };
+ int& get() { return *resource; } // Should NOT trigger warning
+ const int& get() const { return *resource; }
+ };
+
+ // Union with pointer - single method variant
+ struct UnionWithPointerSingle {
+ union { int* resource; };
+ int& get() { return *resource; } // Should NOT trigger warning
+ };
+
+ // Union with value type - should still suggest const where appropriate
+ struct UnionWithValue {
+ union { int value; };
+ int get() { return value; }
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: method 'get' can be made const
+ // CHECK-FIXES: int get() const { return value; }
+ };
+
+ // Union with multiple pointer members
+ struct UnionMultiplePointers {
+ union {
+ int* int_ptr;
+ double* double_ptr;
+ };
+ int& getInt() { return *int_ptr; } // Should NOT trigger warning
+ double& getDouble() { return *double_ptr; } // Should NOT trigger warning
+ };
+
+ // Named union member access
+ struct NamedUnion {
+ union Inner {
+ int* resource;
+ } inner;
+ int& get() { return *inner.resource; } // Should NOT trigger warning
+ };
+
+ // Regular struct for comparison - this SHOULD work as before
+ struct RegularStruct {
+ private:
+ int* ptr;
+ public:
+ int& get() { return *ptr; } // Should NOT trigger warning (private non-const access)
+ };
+} // namespace UnionMemberAccess
More information about the cfe-commits
mailing list