[clang] [clang] Warn on signed char array constant conversion (PR #203792)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 23 18:48:23 PDT 2026
https://github.com/filaka771 updated https://github.com/llvm/llvm-project/pull/203792
>From f8eb7ae6127aa00c441f4f9e6242be9290449edb Mon Sep 17 00:00:00 2001
From: Alex Filak <filaka771 at gmail.com>
Date: Sun, 14 Jun 2026 00:40:00 +0300
Subject: [PATCH 1/4] [clang] Fix char-array constant-conversion suppression
---
clang/lib/Sema/SemaChecking.cpp | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index ef07e8c6133ed..24914c0057c7b 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -13251,7 +13251,8 @@ static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T,
}
// Helper function to filter out cases for constant width constant conversion.
-// Don't warn on char array initialization or for non-decimal values.
+// Don't warn on char / unsigned char array initialization or for non-decimal
+// values.
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T,
SourceLocation CC) {
// If initializing from a constant, and the constant starts with '0',
@@ -13264,12 +13265,16 @@ static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T,
return false;
}
- // If the CC location points to a '{', and the type is char, then assume
- // assume it is an array initialization.
+ // If the CC location points to a '{', and the destination type is char or
+ // unsigned char, then assume this is an array initialization. Keep warning
+ // for signed char arrays, where values such as 255 change sign.
if (CC.isValid() && T->isCharType()) {
+ const auto *BT =
+ dyn_cast<BuiltinType>(S.Context.getCanonicalType(T).getTypePtr());
const char FirstContextCharacter =
S.getSourceManager().getCharacterData(CC)[0];
- if (FirstContextCharacter == '{')
+ if (BT && BT->getKind() != BuiltinType::SChar &&
+ FirstContextCharacter == '{')
return false;
}
>From ab55b35b3edabca58ae31cd2b2a93b4cf31da3fc Mon Sep 17 00:00:00 2001
From: Alex Filak <filaka771 at gmail.com>
Date: Sun, 14 Jun 2026 00:40:12 +0300
Subject: [PATCH 2/4] [clang] Add char-array constant-conversion tests
---
clang/test/Sema/constant-conversion.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/clang/test/Sema/constant-conversion.c b/clang/test/Sema/constant-conversion.c
index ffc25b9cc4978..b40379e2180ce 100644
--- a/clang/test/Sema/constant-conversion.c
+++ b/clang/test/Sema/constant-conversion.c
@@ -125,6 +125,16 @@ void test9(void) {
char macro_char_dec = CHAR_MACRO_DEC; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 255 to -1}}
char array_init[] = { 255, 127, 128, 129, 0 };
+ unsigned char unsigned_array_init[] = { 255 };
+ unsigned char unsigned_array_init_multi[] = { 255, 127, 128, 129, 0 };
+ signed char signed_array_init[] = { 255 }; // expected-warning {{implicit conversion from 'int' to 'signed char' changes value from 255 to -1}}
+ signed char signed_array_init_multi[] = {
+ 255, // expected-warning {{implicit conversion from 'int' to 'signed char' changes value from 255 to -1}}
+ 127,
+ 128, // expected-warning {{implicit conversion from 'int' to 'signed char' changes value from 128 to -128}}
+ 129, // expected-warning {{implicit conversion from 'int' to 'signed char' changes value from 129 to -127}}
+ 0
+ };
}
#define A 1
>From 1e6ec0df823dccd6a9eed9fe4697833bfb9d962f Mon Sep 17 00:00:00 2001
From: Alex Filak <filaka771 at gmail.com>
Date: Wed, 17 Jun 2026 21:53:22 +0300
Subject: [PATCH 3/4] [clang] Add release note for signed-char array warning
---
clang/docs/ReleaseNotes.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 3dd17d8c523bc..3b2dce7a2fa2e 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -325,6 +325,9 @@ features cannot lower the translation-unit ABI level;
- Clang now attempts to print enumerator names rather than C-style cast expressions
in more diagnostics.
+- Fixed a missing `-Wconstant-conversion` diagnostic for `signed char` array
+ initialization.
+
### Improvements to Clang's time-trace
>From e5c5b146eecdf8af9f7649b45e69e6d3628bf0b8 Mon Sep 17 00:00:00 2001
From: Alex Filak <filaka771 at gmail.com>
Date: Fri, 26 Jun 2026 07:02:08 +0300
Subject: [PATCH 4/4] [clang] Handle plain char signedness in array conversion
warnings
---
clang/docs/ReleaseNotes.md | 3 +--
clang/lib/Sema/SemaChecking.cpp | 14 +++++---------
clang/test/Sema/constant-conversion.c | 11 ++++++-----
3 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 3b2dce7a2fa2e..dc7b9f7b17143 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -326,8 +326,7 @@ features cannot lower the translation-unit ABI level;
in more diagnostics.
- Fixed a missing `-Wconstant-conversion` diagnostic for `signed char` array
- initialization.
-
+ initialization. (#GH181730)
### Improvements to Clang's time-trace
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 24914c0057c7b..debf1a8198b63 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -13251,7 +13251,7 @@ static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T,
}
// Helper function to filter out cases for constant width constant conversion.
-// Don't warn on char / unsigned char array initialization or for non-decimal
+// Don't warn on unsigned character array initialization or for non-decimal
// values.
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T,
SourceLocation CC) {
@@ -13265,16 +13265,12 @@ static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T,
return false;
}
- // If the CC location points to a '{', and the destination type is char or
- // unsigned char, then assume this is an array initialization. Keep warning
- // for signed char arrays, where values such as 255 change sign.
- if (CC.isValid() && T->isCharType()) {
- const auto *BT =
- dyn_cast<BuiltinType>(S.Context.getCanonicalType(T).getTypePtr());
+ // If the CC location points to a '{' and the type is an unsigned character
+ // type, assume it is an array initialization.
+ if (T->isCharType() && !T->isSignedIntegerType() && CC.isValid()) {
const char FirstContextCharacter =
S.getSourceManager().getCharacterData(CC)[0];
- if (BT && BT->getKind() != BuiltinType::SChar &&
- FirstContextCharacter == '{')
+ if (FirstContextCharacter == '{')
return false;
}
diff --git a/clang/test/Sema/constant-conversion.c b/clang/test/Sema/constant-conversion.c
index b40379e2180ce..adba3315cc9b4 100644
--- a/clang/test/Sema/constant-conversion.c
+++ b/clang/test/Sema/constant-conversion.c
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify=expected,one-bit -triple x86_64-apple-darwin %s
-// RUN: %clang_cc1 -fsyntax-only -ffreestanding -Wno-single-bit-bitfield-constant-conversion -verify -triple x86_64-apple-darwin %s
+// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify=expected,signed-plain-char,one-bit -triple x86_64-apple-darwin %s
+// RUN: %clang_cc1 -fsyntax-only -ffreestanding -Wno-single-bit-bitfield-constant-conversion -verify=expected,signed-plain-char -triple x86_64-apple-darwin %s
+// RUN: %clang_cc1 -fsyntax-only -ffreestanding -Wno-single-bit-bitfield-constant-conversion -verify -triple x86_64-apple-darwin -fno-signed-char %s
#include <stdbool.h>
@@ -103,7 +104,7 @@ void test9(void) {
const int max_short_plus_one = (int)max_short + 1;
const long max_int_plus_one = (long)max_int + 1;
- char new_char = max_char_plus_one; // expected-warning {{implicit conversion from 'const short' to 'char' changes value from 128 to -128}}
+ char new_char = max_char_plus_one; // signed-plain-char-warning {{implicit conversion from 'const short' to 'char' changes value from 128 to -128}}
short new_short = max_short_plus_one; // expected-warning {{implicit conversion from 'const int' to 'short' changes value from 32768 to -32768}}
int new_int = max_int_plus_one; // expected-warning {{implicit conversion from 'const long' to 'int' changes value from 2147483648 to -2147483648}}
@@ -122,9 +123,9 @@ void test9(void) {
#define CHAR_MACRO_HEX 0xff
char macro_char_hex = CHAR_MACRO_HEX;
#define CHAR_MACRO_DEC 255
- char macro_char_dec = CHAR_MACRO_DEC; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 255 to -1}}
+ char macro_char_dec = CHAR_MACRO_DEC; // signed-plain-char-warning {{implicit conversion from 'int' to 'char' changes value from 255 to -1}}
- char array_init[] = { 255, 127, 128, 129, 0 };
+ char array_init[] = { 255 }; // signed-plain-char-warning {{implicit conversion from 'int' to 'char' changes value from 255 to -1}}
unsigned char unsigned_array_init[] = { 255 };
unsigned char unsigned_array_init_multi[] = { 255, 127, 128, 129, 0 };
signed char signed_array_init[] = { 255 }; // expected-warning {{implicit conversion from 'int' to 'signed char' changes value from 255 to -1}}
More information about the cfe-commits
mailing list