From: Ted Kremenek Date: Wed, 16 Feb 2011 04:01:44 +0000 (+0000) Subject: Tweak -Warray-bounds diagnostics based on feedback from Chandler. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8fd0a5dfb025a51f48b7931b95efbf35d3c5dfc3;p=clang Tweak -Warray-bounds diagnostics based on feedback from Chandler. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125649 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 2c82dcb5fd..0efb92462b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -3379,9 +3379,14 @@ def warn_not_compound_assign : Warning< def warn_explicit_conversion_functions : Warning< "explicit conversion functions are a C++0x extension">, InGroup; -def warn_array_index_out_of_bounds : Warning< - "array index %select{precedes first|excedes last}0 array element">, +def warn_array_index_precedes_bounds : Warning< + "array index of '%0' indexes before the beginning of the array">, InGroup>; +def warn_array_index_exceeds_bounds : Warning< + "array index of '%0' indexes past the end of an array (that contains %1 elements)">, + InGroup>; +def note_array_index_out_of_bounds : Note< + "Array %0 declared here">; def warn_printf_write_back : Warning< "use of '%%n' in format string discouraged (potentially insecure)">, diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index ea1f07d783..a4c9eb6841 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -3095,18 +3095,24 @@ void Sema::CheckArrayAccess(const clang::ArraySubscriptExpr *ae) { llvm::APSInt result; if (!idx->isIntegerConstantExpr(result, Context)) return; - unsigned kind = 2; - if (result.slt(0)) - kind = /* precedes */ 0; + + if (result.slt(0)) { + Diag(ae->getBase()->getLocStart(), diag::warn_array_index_precedes_bounds) + << result.toString(10, true) << idx->getSourceRange(); + } else { const llvm::APInt &size = cat->getSize(); if (size.getBitWidth() > result.getBitWidth()) result = result.sext(size.getBitWidth()); - if (result.sge(size)) - kind = /* excedes */ 1; + if (result.sge(size)) { + Diag(ae->getBase()->getLocStart(), diag::warn_array_index_exceeds_bounds) + << result.toString(10, true) << size.toString(10, true) + << idx->getSourceRange(); + } + else + return; } - if (kind < 2) - Diag(ae->getBase()->getLocEnd(), diag::warn_array_index_out_of_bounds) - << kind << idx->getSourceRange(); + Diag(vd->getLocStart(), diag::note_array_index_out_of_bounds) + << vd->getDeclName(); } diff --git a/test/Sema/array-bounds.c b/test/Sema/array-bounds.c index b540885547..0ae53d35d8 100644 --- a/test/Sema/array-bounds.c +++ b/test/Sema/array-bounds.c @@ -1,16 +1,16 @@ // RUN: %clang_cc1 -verify %s int foo() { - int x[2]; - int y[2]; + int x[2]; // expected-note 4 {{Array 'x' declared here}} + int y[2]; // expected-note 2 {{Array 'y' declared here}} int *p = &y[2]; // no-warning (void) sizeof(x[2]); // no-warning - y[2] = 2; // expected-warning{{array index excedes last array element}} - return x[2] + // expected-warning{{array index excedes last array element}} - y[-1] + // expected-warning{{array index precedes first array element}} - x[sizeof(x)] + // expected-warning{{array index excedes last array element}} - x[sizeof(x) / sizeof(x[0])] + // expected-warning{{array index excedes last array element}} + y[2] = 2; // expected-warning{{array index of '2' indexes past the end of an array (that contains 2 elements)}} + return x[2] + // expected-warning{{array index of '2' indexes past the end of an array (that contains 2 elements)}} + y[-1] + // expected-warning{{array index of '-1' indexes before the beginning of the array}} + x[sizeof(x)] + // expected-warning{{array index of '8' indexes past the end of an array (that contains 2 elements)}} + x[sizeof(x) / sizeof(x[0])] + // expected-warning{{array index of '2' indexes past the end of an array (that contains 2 elements)}} x[sizeof(x) / sizeof(x[0]) - 1] + // no-warning - x[sizeof(x[2])]; // expected-warning{{array index excedes last array element}} + x[sizeof(x[2])]; // expected-warning{{array index of '4' indexes past the end of an array (that contains 2 elements)}} }