https://github.com/wheatman updated https://github.com/llvm/llvm-project/pull/69061
>From 20e471721bbb17701954c3c6bf7f4342dd9bc3e2 Mon Sep 17 00:00:00 2001 From: Brian Wheatman <bwheat...@gmail.com> Date: Sat, 14 Oct 2023 12:02:19 -0400 Subject: [PATCH] Remove warnings from -Wchar-subscripts for known positive constants --- clang/docs/ReleaseNotes.rst | 2 + clang/lib/Sema/SemaExpr.cpp | 11 ++- clang/test/Sema/warn-char-subscripts.c | 25 ++++++ clang/test/Sema/warn-char-subscripts.cpp | 103 +++++++++++++++++++++++ 4 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 clang/test/Sema/warn-char-subscripts.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4696836b3a00caa..e43b43acf0f05bf 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -541,6 +541,8 @@ Bug Fixes in This Version Fixes (`#67687 <https://github.com/llvm/llvm-project/issues/67687>`_) - Fix crash from constexpr evaluator evaluating uninitialized arrays as rvalue. Fixes (`#67317 <https://github.com/llvm/llvm-project/issues/67317>`_) +- Clang's ``-Wchar-subscripts`` no longer warns on chars whose values are known non-negative constants. + Fixes (`#18763 <https://github.com/llvm/llvm-project/issues/18763>`_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4a4cb02b0e4a6d7..68ab63552a5e94f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6041,9 +6041,14 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, << IndexExpr->getSourceRange()); if ((IndexExpr->getType()->isSpecificBuiltinType(BuiltinType::Char_S) || - IndexExpr->getType()->isSpecificBuiltinType(BuiltinType::Char_U)) - && !IndexExpr->isTypeDependent()) - Diag(LLoc, diag::warn_subscript_is_char) << IndexExpr->getSourceRange(); + IndexExpr->getType()->isSpecificBuiltinType(BuiltinType::Char_U)) && + !IndexExpr->isTypeDependent()) { + std::optional<llvm::APSInt> IntegerContantExpr = + IndexExpr->getIntegerConstantExpr(getASTContext()); + if (!IntegerContantExpr.has_value() || + IntegerContantExpr.value().isNegative()) + Diag(LLoc, diag::warn_subscript_is_char) << IndexExpr->getSourceRange(); + } // C99 6.5.2.1p1: "shall have type "pointer to *object* type". Similarly, // C++ [expr.sub]p1: The type "T" shall be a completely-defined object diff --git a/clang/test/Sema/warn-char-subscripts.c b/clang/test/Sema/warn-char-subscripts.c index 2e72d90fa612aed..0a012f68feae07f 100644 --- a/clang/test/Sema/warn-char-subscripts.c +++ b/clang/test/Sema/warn-char-subscripts.c @@ -62,3 +62,28 @@ void t10(void) { UnsignedCharTy subscript = 0; int val = array[subscript]; // no warning for unsigned char } + +void t11(void) { + int array[256] = { 0 }; + int val = array['a']; // no warning for char with known positive value +} + +void t12(void) { + int array[256] = { 0 }; + char b = 'a'; + int val = array[b]; // expected-warning{{array subscript is of type 'char'}} +} + +void t13(void) { + int array[256] = { 0 }; + const char b = 'a'; + int val = array[b]; // expected-warning{{array subscript is of type 'char'}} +} + +void t14(void) { + int array[256] = { 0 }; // expected-note {{array 'array' declared here}} + const char b = -1; + // expected-warning@+2 {{array subscript is of type 'char'}} + // expected-warning@+1 {{array index -1 is before the beginning of the array}} + int val = array[b]; +} diff --git a/clang/test/Sema/warn-char-subscripts.cpp b/clang/test/Sema/warn-char-subscripts.cpp new file mode 100644 index 000000000000000..929fb372c5173fd --- /dev/null +++ b/clang/test/Sema/warn-char-subscripts.cpp @@ -0,0 +1,103 @@ +// RUN: %clang_cc1 -Wchar-subscripts -fsyntax-only -verify %s + +void t1(void) { + int array[1] = { 0 }; + char subscript = 0; + int val = array[subscript]; // expected-warning{{array subscript is of type 'char'}} +} + +void t2(void) { + int array[1] = { 0 }; + char subscript = 0; + int val = subscript[array]; // expected-warning{{array subscript is of type 'char'}} +} + +void t3(void) { + int *array = 0; + char subscript = 0; + int val = array[subscript]; // expected-warning{{array subscript is of type 'char'}} +} + +void t4(void) { + int *array = 0; + char subscript = 0; + int val = subscript[array]; // expected-warning{{array subscript is of type 'char'}} +} + +char returnsChar(void); +void t5(void) { + int *array = 0; + int val = array[returnsChar()]; // expected-warning{{array subscript is of type 'char'}} +} + +void t6(void) { + int array[1] = { 0 }; + signed char subscript = 0; + int val = array[subscript]; // no warning for explicit signed char +} + +void t7(void) { + int array[1] = { 0 }; + unsigned char subscript = 0; + int val = array[subscript]; // no warning for unsigned char +} + +typedef char CharTy; +void t8(void) { + int array[1] = { 0 }; + CharTy subscript = 0; + int val = array[subscript]; // expected-warning{{array subscript is of type 'char'}} +} + +typedef signed char SignedCharTy; +void t9(void) { + int array[1] = { 0 }; + SignedCharTy subscript = 0; + int val = array[subscript]; // no warning for explicit signed char +} + +typedef unsigned char UnsignedCharTy; +void t10(void) { + int array[1] = { 0 }; + UnsignedCharTy subscript = 0; + int val = array[subscript]; // no warning for unsigned char +} + +void t11(void) { + int array[256] = { 0 }; + int val = array['a']; // no warning for char with known positive value +} + +void t12(void) { + int array[256] = { 0 }; + char b = 'a'; + int val = array[b]; // expected-warning{{array subscript is of type 'char'}} +} + +void t13(void) { + int array[256] = { 0 }; + const char b = 'a'; + int val = array[b]; // no warning for char with known positive value +} + +void t14(void) { + int array[256] = { 0 }; + constexpr char b = 'a'; + int val = array[b]; // no warning for char with known positive value +} + +void t15(void) { + int array[256] = { 0 }; // expected-note {{array 'array' declared here}} + const char b = -1; + // expected-warning@+2 {{array subscript is of type 'char'}} + // expected-warning@+1 {{array index -1 is before the beginning of the array}} + int val = array[b]; +} + +void t16(void) { + int array[256] = { 0 }; // expected-note {{array 'array' declared here}} + constexpr char b = -1; + // expected-warning@+2 {{array subscript is of type 'char'}} + // expected-warning@+1 {{array index -1 is before the beginning of the array}} + int val = array[b]; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits