// RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage \ // RUN: -fsafe-buffer-usage-suggestions \ // RUN: -fdiagnostics-parseable-fixits \ // RUN: -fsyntax-only %s 2>&1 | FileCheck %s // TODO test we don't mess up vertical whitespace // TODO test different whitespaces // TODO test different contexts // when it's on the right side void basic() { int *ptr; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"std::span ptr" *(ptr+5)=1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:5}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:8-[[@LINE-2]]:9}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:11}:"]" } // The weird preceding semicolon ensures that we preserve that range intact. void char_ranges() { int *p; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:9}:"std::span p" ;* ( p + 5 ) = 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:8}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:9-[[@LINE-2]]:12}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:13-[[@LINE-3]]:15}:"]" ;* (p+5)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:9}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:11}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:13}:"]" ;*( p+5)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:9}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:11}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:13}:"]" ;*( p+5)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:9}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:11}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:13}:"]" ;*( p +5)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:7}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:8-[[@LINE-2]]:12}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:13-[[@LINE-3]]:14}:"]" ;*(p+ 5)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:11}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:13}:"]" ;*(p+ 5 )= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:9}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:14}:"]" ;*(p+ 5) = 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:9}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:11}:"]" ; *(p+5)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:9}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:11}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:13}:"]" ;*(p+123456)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:8}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:14-[[@LINE-3]]:15}:"]" ;* (p+123456)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:9}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:11}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:"]" ;*( p+123456)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:9}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:11}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:"]" ;*( p+123456)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:9}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:11}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:"]" ;*(p +123456)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:11}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:"]" ;*(p+ 123456)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:11}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:"]" ;*(p+123456 )= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:8}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:14-[[@LINE-3]]:18}:"]" ;*(p+123456) = 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:8}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:14-[[@LINE-3]]:15}:"]" int *ptrrrrrr; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:16}:"std::span ptrrrrrr" ;* ( ptrrrrrr + 123456 )= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:8}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:19}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:25-[[@LINE-3]]:27}:"]" ;* (ptrrrrrr+123456)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:9}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:18}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:25}:"]" ;*( ptrrrrrr+123456)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:9}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:18}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:25}:"]" ;*( ptrrrrrr+123456)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:9}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:18}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:25}:"]" ;*(ptrrrrrr +123456)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:14-[[@LINE-2]]:18}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:25}:"]" ;*(ptrrrrrr+ 123456)= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:14-[[@LINE-2]]:18}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:25}:"]" ;*(ptrrrrrr+123456 )= 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:14-[[@LINE-2]]:15}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:25}:"]" ;*(ptrrrrrr+123456) = 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:14-[[@LINE-2]]:15}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:22}:"]" } void base_on_rhs() { int* ptr; *(10 + ptr) = 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:5}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:10}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:13-[[@LINE-3]]:14}:"]" } void many_parens() { int* ptr; *(( (10 + ptr)) ) = 1; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:8}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:13}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:20}:"]" } void lvaue_to_rvalue() { int * ptr; int tmp = *(ptr + 10); // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:15}:"" // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:18-[[@LINE-2]]:21}:"[" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:23-[[@LINE-3]]:24}:"]" } // Fixits emitted for the cases below would be incorrect. // CHECK-NOT: fix-it: // Array subsctipt opertor of std::span accepts unsigned integer. void negative() { int* ptr; *(ptr + -5) = 1; // skip } void subtraction() { int* ptr; *(ptr - 5) = 1; // skip } void subtraction_of_negative() { int* ptr; *(ptr - -5) = 1; // FIXME: implement fixit (uncommon case - low priority) } void bindingDecl(int *p, int *q) { int * a[2] = {p, q}; auto [x, y] = a; *(x + 1) = 1; // FIXME: deal with `BindingDecl`s }