Author: wheatman Date: 2023-12-04T06:49:37+01:00 New Revision: 0031efe6be19735402656a76b64a173d17f1f935
URL: https://github.com/llvm/llvm-project/commit/0031efe6be19735402656a76b64a173d17f1f935 DIFF: https://github.com/llvm/llvm-project/commit/0031efe6be19735402656a76b64a173d17f1f935.diff LOG: Remove warnings from -Wchar-subscripts for known positive constants (#69061) Fixes #18763 Remove warnings when using a signed char as an array bound if the char is a known positive constant. This goes one step farther than gcc does. For example given the following code ```c++ char upper[300]; int main() { upper['a'] = 'A'; char b = 'a'; upper[b] = 'A'; const char c = 'a'; upper[c] = 'A'; constexpr char d = 'a'; upper[d] = 'A'; char e = -1; upper[e] = 'A'; const char f = -1; upper[f] = 'A'; constexpr char g = -1; upper[g] = 'A'; return 1; } ``` clang currently gives warnings for all cases, while gcc gives warnings for all cases except for 'a' (https://godbolt.org/z/5ahjETTv3) With the change there is no longer any warning for 'a', 'c', or 'd'. Added: clang/test/Sema/warn-char-subscripts.cpp Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaExpr.cpp clang/test/Sema/warn-char-subscripts.c Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c7a948fd3fae5..683d0026bb345 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -651,6 +651,8 @@ Bug Fixes in This Version - Fixed false positive error emitted by clang when performing qualified name lookup and the current class instantiation has dependent bases. Fixes (`#13826 <https://github.com/llvm/llvm-project/issues/13826>`_) +- 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 d1b2b8084b8ff..d629be083d8c3 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6053,9 +6053,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 2e72d90fa612a..0a012f68feae0 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 0000000000000..929fb372c5173 --- /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