brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · 25fb7f0 Raw
158 lines · c
1// RUN: %clang_analyze_cc1 -analyzer-checker=security.PointerSub -analyzer-output=text-minimal -verify %s2 3typedef int * Ptr;4 5void f1(void) {6  int x, y, z[10];7  int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point into the same array is undefined behavior}}8  d = z - &y; // expected-warning{{Subtraction of two pointers that do not point into the same array is undefined behavior}}9  d = &x - &x; // no-warning (subtraction of any two identical pointers is allowed)10  d = (long *)&x - (long *)&x;11  d = (&x + 1) - &x; // no-warning ('&x' is like a single-element array)12  d = &x - (&x + 1); // no-warning13  d = (&x + 0) - &x; // no-warning14  d = (z + 10) - z; // no-warning15  d = (long long)&y - (long long)&x; // no-warning16  long long l = 1;17  d = l - (long long)&y; // no-warning18  Ptr p1 = &x;19  Ptr p2 = &y;20  d = p1 - p2; // expected-warning{{Subtraction of two pointers that do not point into the same array is undefined behavior}}21}22 23void f2(void) {24  int a[10], b[10], c; // expected-note{{Array at the left-hand side of subtraction}} \25                       // expected-note2{{Array at the right-hand side of subtraction}}26  int *p = &a[2];27  int *q = &a[8];28  int d = q - p; // no-warning (pointers into the same array)29 30  q = &b[3];31  d = q - p; // expected-warning{{Subtraction of two pointers that}}32 33  d = &a[4] - a; // no-warning34  d = &a[2] - p; // no-warning35  d = &c - p; // expected-warning{{Subtraction of two pointers that}}36 37  d = (int *)((char *)(&a[4]) + sizeof(int)) - &a[4]; // no-warning (pointers into the same array data)38  d = (int *)((char *)(&a[4]) + 1) - &a[4]; // expected-warning{{Subtraction of two pointers that}}39 40  long long a1 = (long long)&a[1];41  long long b1 = (long long)&b[1];42  d = a1 - b1;43}44 45void f3(void) {46  int a[3][4]; // expected-note{{Array at the left-hand side of subtraction}} \47               // expected-note2{{Array at the right-hand side of subtraction}}48  int d;49 50  d = &(a[2]) - &(a[1]);51  d = a[2] - a[1]; // expected-warning{{Subtraction of two pointers that}}52  d = a[1] - a[1];53  d = &(a[1][2]) - &(a[1][0]);54  d = &(a[1][2]) - &(a[0][0]); // expected-warning{{Subtraction of two pointers that}}55 56  d = (int *)((char *)(&a[2][2]) + sizeof(int)) - &a[2][2]; // expected-warning{{Subtraction of two pointers that}}57  d = (int *)((char *)(&a[2][2]) + 1) - &a[2][2]; // expected-warning{{Subtraction of two pointers that}}58  d = (int (*)[4])((char *)&a[2] + sizeof(int (*)[4])) - &a[2]; // expected-warning{{Subtraction of two pointers that}}59  d = (int (*)[4])((char *)&a[2] + 1) - &a[2]; // expected-warning{{Subtraction of two pointers that}}60}61 62void f4(void) {63  int n = 4, m = 3;64  int a[n][m];65  int (*p)[m] = a; // p == &a[0]66  p += 1; // p == &a[1]67 68  // FIXME: This is a known problem with -Wpointer-arith (https://github.com/llvm/llvm-project/issues/28328)69  int d = p - a; // d == 1 // expected-warning{{subtraction of pointers to type 'int[m]' of zero size has undefined behavior}}70 71  // FIXME: This is a known problem with -Wpointer-arith (https://github.com/llvm/llvm-project/issues/28328)72  d = &(a[2]) - &(a[1]); // expected-warning{{subtraction of pointers to type 'int[m]' of zero size has undefined behavior}}73 74  d = a[2] - a[1]; // expected-warning{{Subtraction of two pointers that}}75}76 77struct S {78  int a;79  int b;80  int c[10]; // expected-note2{{Array at the right-hand side of subtraction}}81  int d[10]; // expected-note2{{Array at the left-hand side of subtraction}}82};83 84void f5(void) {85  struct S s;86  int y;87  int d;88 89  d = &s.b - &s.a; // expected-warning{{Subtraction of two pointers that}}90  d = &s.c[0] - &s.a; // expected-warning{{Subtraction of two pointers that}}91  d = &s.b - &y; // expected-warning{{Subtraction of two pointers that}}92  d = &s.c[3] - &s.c[2];93  d = &s.d[3] - &s.c[2]; // expected-warning{{Subtraction of two pointers that}}94  d = s.d - s.c; // expected-warning{{Subtraction of two pointers that}}95 96  struct S sa[10];97  d = &sa[2] - &sa[1];98  d = &sa[2].a - &sa[1].b; // expected-warning{{Subtraction of two pointers that}}99}100 101void f6(void) {102  long long l = 2;103  char *a1 = (char *)&l;104  int d = a1[3] - l;105 106  long long la1[3] = {1}; // expected-note{{Array at the right-hand side of subtraction}}107  long long la2[3] = {1}; // expected-note{{Array at the left-hand side of subtraction}}108  char *pla1 = (char *)la1;109  char *pla2 = (char *)la2;110  d = pla1[1] - pla1[0];111  d = (long long *)&pla1[1] - &l; // expected-warning{{Subtraction of two pointers that}}112  d = &pla2[3] - &pla1[3]; // expected-warning{{Subtraction of two pointers that}}113}114 115void f7(int *p) {116  int a[10];117  int d = &a[10] - p; // no-warning ('p' is unknown, even if it cannot point into 'a')118}119 120void f8(int n) {121  int a[10] = {1};122  int d = a[n] - a[0]; // no-warning123}124 125int f9(const char *p1) {126  const char *p2 = p1;127  --p1;128  ++p2;129  return p1 - p2; // no-warning130}131 132int f10(struct S *p1, struct S *p2) {133  return &p1->c[5] - &p2->c[5]; // no-warning134}135 136struct S1 {137  int a;138  int b; // expected-note{{Object at the right-hand side of subtraction}}139};140 141int f11() {142  struct S1 s; // expected-note{{Object at the left-hand side of subtraction}}143  return (char *)&s - (char *)&s.b; // expected-warning{{Subtraction of two pointers that}}144}145 146struct S2 {147  char *p1;148  char *p2;149};150 151void init_S2(struct S2 *);152 153int f12() {154  struct S2 s;155  init_S2(&s);156  return s.p1 - s.p2; // no-warning (pointers are unknown)157}158