[clang-tools-extra] [clang-tidy] Avoid pointee-const fixes for arrays of pointer aliases (PR #234784)
Abdelrahman Salah via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 22 15:50:30 PDT 2026
https://github.com/Abusalah0 created https://github.com/llvm/llvm-project/pull/234784
Skip pointee-const diagnostics when an array element hides its pointer type behind a typedef or type alias, matching the handling of standalone pointer aliases. Adding const to such an alias qualifies the pointer itself and can make subsequent assignments ill-formed.
Add regression coverage for direct and chained typedefs, using aliases, valid pointers to aliases, and pointer-as-value transformations. All 19 const-correctness regression tests pass, and the original reproducer compiles after applying fixes.
Fixes #234356
>From c0a8771cb777deb2fb8411e6d1bdb6d7fff37775 Mon Sep 17 00:00:00 2001
From: abusalah0 <109g83 at gmail.com>
Date: Fri, 23 Oct 2026 01:47:22 +0300
Subject: [PATCH] [clang-tidy] Avoid pointee-const fixes for arrays of pointer
aliases
Skip pointee-const diagnostics when an array element hides its pointer type behind a typedef or type alias, matching the handling of standalone pointer aliases. Adding const to such an alias qualifies the pointer itself and can make subsequent assignments ill-formed.
Add regression coverage for direct and chained typedefs, using aliases, valid pointers to aliases, and pointer-as-value transformations. All 19 const-correctness regression tests pass, and the original reproducer compiles after applying fixes.
Fixes #234356
Assisted-by: OpenAI Codex
---
.../clang-tidy/misc/ConstCorrectnessCheck.cpp | 5 ++-
clang-tools-extra/docs/ReleaseNotes.md | 4 +++
.../const-correctness-pointer-as-pointers.cpp | 33 +++++++++++++++++++
.../const-correctness-pointer-as-values.cpp | 13 ++++++++
4 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
index 90919555d447e8..0dfb81a8f7f1e6 100644
--- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
@@ -351,7 +351,10 @@ void ConstCorrectnessCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *AT = dyn_cast<ArrayType>(VT)) {
assert(AT->getElementType()->isPointerType());
- if (!AT->getElementType()->getPointeeType().isConstQualified())
+ // A pointer hidden by an alias cannot have its pointee qualified by
+ // adding const to the variable declaration.
+ if (const auto *PT = dyn_cast<PointerType>(AT->getElementType());
+ PT && !PT->getPointeeType().isConstQualified())
CheckPointee();
}
}
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 361d14ec2242c2..92f102c0b35e86 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -265,6 +265,10 @@ infrastructure are described first, followed by tool-specific sections.
- No longer diagnoses parameters of `main`, whose signature is fixed by the
standard.
+ - Fixed incorrect pointee-const suggestions for arrays of pointer typedefs or
+ type aliases, where the fix would make the pointers themselves const.
+ ([#234356](https://github.com/llvm/llvm-project/issues/234356))
+
- Fixed an infinite loop in {doc}`misc-multiple-inheritance
<clang-tidy/checks/misc/multiple-inheritance>` when checking a class that
inherits from itself or has a circular inheritance graph.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp
index 9b6d8d320d4cf0..4294c067249095 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp
@@ -29,6 +29,39 @@ void array_of_pointer_to_const() {
p_local0[0] = &a[1];
}
+typedef void *PVOID;
+typedef PVOID HANDLE;
+using PointerAlias = void *;
+
+void array_of_pointer_alias(void *value) {
+ // Adding const to a pointer alias qualifies the pointer, not its pointee.
+ PVOID direct[3]{};
+ // CHECK-FIXES: PVOID direct[3]{};
+ direct[0] = value;
+
+ HANDLE chained[3]{};
+ // CHECK-FIXES: HANDLE chained[3]{};
+ chained[0] = value;
+
+ PointerAlias alias[3]{};
+ // CHECK-FIXES: PointerAlias alias[3]{};
+ alias[0] = value;
+}
+
+using ScalarAlias = int;
+
+void array_of_pointer_to_alias(ScalarAlias *value, PVOID *pointer) {
+ ScalarAlias *scalar[3]{};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: pointee of variable 'scalar' of type 'ScalarAlias *[3]' (aka 'int *[3]') can be declared 'const'
+ // CHECK-FIXES: ScalarAlias const*scalar[3]{};
+ scalar[0] = value;
+
+ PVOID *outer[3]{};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: pointee of variable 'outer' of type 'PVOID *[3]' (aka 'void **[3]') can be declared 'const'
+ // CHECK-FIXES: PVOID const*outer[3]{};
+ outer[0] = pointer;
+}
+
template<class T>
void template_fn() {
T a[] = {1, 2};
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp
index b498c0b6d8d5a8..7f3d03e8af879c 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp
@@ -20,6 +20,19 @@ void potential_const_pointer() {
// CHECK-FIXES: doublePtr const p_local1 = &np_local1[0];
}
+typedef void *PVOID;
+using PointerAlias = void *;
+
+void array_of_pointer_alias() {
+ PVOID direct[3]{};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'direct' of type 'PVOID[3]' (aka 'void *[3]') can be declared 'const'
+ // CHECK-FIXES: PVOID const direct[3]{};
+
+ PointerAlias alias[3]{};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'alias' of type 'PointerAlias[3]' (aka 'void *[3]') can be declared 'const'
+ // CHECK-FIXES: PointerAlias const alias[3]{};
+}
+
void range_for() {
int np_local0[2] = {1, 2};
int *p_local0[2] = {&np_local0[0], &np_local0[1]};
More information about the cfe-commits
mailing list