https://github.com/wheatman updated https://github.com/llvm/llvm-project/pull/69061
>From af3b7f9a94d7862acf5bd56dfb0ef652a684244d 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/lib/Sema/SemaExpr.cpp | 12 ++- clang/test/Sema/warn-char-subscripts.c | 25 ++++++ clang/test/Sema/warn-char-subscripts.cpp | 103 +++++++++++++++++++++++ 3 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 clang/test/Sema/warn-char-subscripts.cpp diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index aa30a3a03887558..dd9ba5cecaf2404 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6018,9 +6018,15 @@ 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().isNonNegative())) { + 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