]> granicus.if.org Git - clang/commitdiff
disable array bounds overflow warning for cases where an array
authorChris Lattner <sabre@nondot.org>
Tue, 2 Aug 2011 21:44:23 +0000 (21:44 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 2 Aug 2011 21:44:23 +0000 (21:44 +0000)
has a single element.  This disables the warning in cases where
there is a clear bug, but this is really rare (who uses arrays
with one element?) and it also silences a large class of false
positive issues with C89 code that is using tail padding in structs.

A better version of this patch would detect when an array is in
a tail position in a struct, but at least patch fixes the huge
false positives that are hitting postgres and other code.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136724 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaChecking.cpp
test/SemaCXX/array-bounds.cpp

index 28085ef6eab667380326e5dca5696a2e814922ad..81ae7b3afb02aa6654ffe57422e6df884adb71a7 100644 (file)
@@ -3491,7 +3491,9 @@ static void CheckArrayAccess_Check(Sema &S,
     else if (size.getBitWidth() < index.getBitWidth())
       size = size.sext(index.getBitWidth());
 
-    if (index.slt(size))
+    // Don't warn for valid indexes, or arrays of size 1 (which are often
+    // tail-allocated arrays that are emulating flexible arrays in C89 code).
+    if (index.slt(size) || size == 1)
       return;
 
     S.DiagRuntimeBehavior(E->getBase()->getLocStart(), BaseExpr,
index 3bd6c35420d7b578b733f6343d2a9586e3d76226..044949200e0e9230a986fb450d844f49b46e960a 100644 (file)
@@ -24,8 +24,8 @@ void f1(int a[1]) {
   int val = a[3]; // no warning for function argumnet
 }
 
-void f2(const int (&a)[1]) { // expected-note {{declared here}}
-  int val = a[3];  // expected-warning {{array index of '3' indexes past the end of an array (that contains 1 elements)}}
+void f2(const int (&a)[2]) { // expected-note {{declared here}}
+  int val = a[3];  // expected-warning {{array index of '3' indexes past the end of an array (that contains 2 elements)}}
 }
 
 void test() {
@@ -42,8 +42,8 @@ void test() {
   u.c[3] = 1; // no warning
 
   const int const_subscript = 3;
-  int array[1]; // expected-note {{declared here}}
-  array[const_subscript] = 0;  // expected-warning {{array index of '3' indexes past the end of an array (that contains 1 elements)}}
+  int array[2]; // expected-note {{declared here}}
+  array[const_subscript] = 0;  // expected-warning {{array index of '3' indexes past the end of an array (that contains 2 elements)}}
 
   int *ptr;
   ptr[3] = 0; // no warning for pointer references
@@ -58,8 +58,8 @@ void test() {
   const char str2[] = "foo"; // expected-note {{declared here}}
   char c2 = str2[5]; // expected-warning {{array index of '5' indexes past the end of an array (that contains 4 elements)}}
 
-  int (*array_ptr)[1];
-  (*array_ptr)[3] = 1; // expected-warning {{array index of '3' indexes past the end of an array (that contains 1 elements)}}
+  int (*array_ptr)[2];
+  (*array_ptr)[3] = 1; // expected-warning {{array index of '3' indexes past the end of an array (that contains 2 elements)}}
 }
 
 template <int I> struct S {
@@ -173,3 +173,14 @@ void test_all_enums_covered(enum Values v) {
   }
   x[2] = 0; // no-warning
 }
+
+namespace tailpad {
+  struct foo {
+    int x;
+    char c[1];
+  };
+  
+  char bar(struct foo *F) {
+    return F->c[3];  // no warning, foo could have tail padding allocated.
+  }
+}