brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · 0c80da6 Raw
152 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage -fcxx-exceptions -fsafe-buffer-usage-suggestions -verify %s2// RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage -fcxx-exceptions -fdiagnostics-parseable-fixits -fsafe-buffer-usage-suggestions %s 2>&1 | FileCheck %s3 4typedef int * TYPEDEF_PTR;5#define MACRO_PTR int*6 7// We CANNOT fix a pointer whose type is defined in a typedef or a8// macro. Because if the typedef is changed after the fix, the fix9// becomes incorrect and may not be noticed.10 11// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE+1]]12void typedefPointer(TYPEDEF_PTR p) {  // expected-warning{{'p' is an unsafe pointer used for buffer access}}13  if (++p) {  // expected-note{{used in pointer arithmetic here}}14  }15}16 17// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE+1]]18void macroPointer(MACRO_PTR p) {  // expected-warning{{'p' is an unsafe pointer used for buffer access}}19  if (++p) {  // expected-note{{used in pointer arithmetic here}}20  }21}22 23// The analysis requires accurate source location informations from24// `TypeLoc`s of types of variable (parameter) declarations in order25// to generate fix-its for them. But those information is not always26// available (probably due to some bugs in clang but it is irrelevant27// to the safe-buffer project).  The following is an example.  When28// `_Atomic` is used, we cannot get valid source locations of the29// pointee type of `unsigned *`.  The analysis gives up in such a30// case.31// CHECK-NOT: fix-it:32void typeLocSourceLocationInvalid(_Atomic unsigned *map) { // expected-warning{{'map' is an unsafe pointer used for buffer access}}33  map[5] = 5; // expected-note{{used in buffer access here}}34}35 36// CHECK: fix-it:"{{.*}}":{[[@LINE+1]]:33-[[@LINE+1]]:46}:"std::span<unsigned> map"37void typeLocSourceLocationValid(unsigned *map) { // expected-warning{{'map' is an unsafe pointer used for buffer access}} \38						    expected-note{{change type of 'map' to 'std::span' to preserve bounds information}}39  map[5] = 5; // expected-note{{used in buffer access here}}40}41// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:2-[[@LINE-1]]:2}:"\n{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} void typeLocSourceLocationValid(unsigned *map) {return typeLocSourceLocationValid(std::span<unsigned>(map, <# size #>));}\n"42 43// We do not fix parameters participating unsafe operations for the44// following functions/methods or function-like expressions:45 46// CHECK-NOT: fix-it:47class A {48  // constructor & descructor49  A(int * p) {  // expected-warning{{'p' is an unsafe pointer used for buffer access}}50    int tmp;51    tmp = p[5]; // expected-note{{used in buffer access here}}52  }53 54  // class member methods55  void foo(int *p) { // expected-warning{{'p' is an unsafe pointer used for buffer access}}56    int tmp;57    tmp = p[5];      // expected-note{{used in buffer access here}}58  }59 60  // overload operator61  int operator+(int * p) { // expected-warning{{'p' is an unsafe pointer used for buffer access}}62    int tmp;63    tmp = p[5];            // expected-note{{used in buffer access here}}64    return tmp;65  }66};67 68// lambdas69void foo() {70  auto Lamb = [&](int *p) // expected-warning{{'p' is an unsafe pointer used for buffer access}}71    -> int {72    int tmp;73    tmp = p[5];           // expected-note{{used in buffer access here}}74    return tmp;75  };76}77 78// template79template<typename T>80void template_foo(T * p) { // expected-warning{{'p' is an unsafe pointer used for buffer access}}81  T tmp;82  tmp = p[5];              // expected-note{{used in buffer access here}}83}84 85void instantiate_template_foo() {86  int * p;87  template_foo(p);        // FIXME expected note {{in instantiation of function template specialization 'template_foo<int>' requested here}}88}89 90// variadic function91void vararg_foo(int * p...) { // expected-warning{{'p' is an unsafe pointer used for buffer access}}92  int tmp;93  tmp = p[5];                 // expected-note{{used in buffer access here}}94}95 96// constexpr functions97constexpr int constexpr_foo(int * p) { // expected-warning{{'p' is an unsafe pointer used for buffer access}}98  return p[5];                         // expected-note{{used in buffer access here}}99}100 101// function body is a try-block102void fn_with_try_block(int* p)    // expected-warning{{'p' is an unsafe pointer used for buffer access}}103  try {104    int tmp;105 106    if (p == nullptr)107      throw 42;108    tmp = p[5];                   // expected-note{{used in buffer access here}}109  }110  catch (int) {111    *p = 0;112  }113 114// The following two unsupported cases are not specific to115// parm-fixits. Adding them here in case they get forgotten.116void isArrayDecayToPointerUPC(int a[][10], int (*b)[10]) {117// expected-warning@-1{{'a' is an unsafe pointer used for buffer access}}118// expected-warning@-2{{'b' is an unsafe pointer used for buffer access}}119  int tmp;120 121  tmp = a[5][5] + b[5][5];  // expected-note2{{used in buffer access here}}122}123 124// parameter having default values:125void parmWithDefaultValue(int * x = 0) {126  // expected-warning@-1{{'x' is an unsafe pointer used for buffer access}}127  int tmp;128  tmp = x[5]; // expected-note{{used in buffer access here}}129}130 131void parmWithDefaultValueDecl(int * x = 0);132 133void parmWithDefaultValueDecl(int * x) {134  // expected-warning@-1{{'x' is an unsafe pointer used for buffer access}}135  int tmp;136  tmp = x[5]; // expected-note{{used in buffer access here}}137}138 139#define MACRO_NAME MyName140 141// The fix-it ends with a macro. It will be discarded due to overlap with macros.142// CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]143void macroIdentifier(int * MACRO_NAME) { // expected-warning{{'MyName' is an unsafe pointer used for buffer access}}144  if (++MyName){} // expected-note{{used in pointer arithmetic here}}145}146 147// CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]148void parmHasNoName(int *p, int *) { // cannot fix the function because there is one parameter has no name. \149				       expected-warning{{'p' is an unsafe pointer used for buffer access}}150  p[5] = 5; // expected-note{{used in buffer access here}}151}152