[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