diff options
author | Daniel Marjamaki <daniel.marjamaki@evidente.se> | 2016-08-23 10:09:08 +0000 |
---|---|---|
committer | Daniel Marjamaki <daniel.marjamaki@evidente.se> | 2016-08-23 10:09:08 +0000 |
commit | 9e4ecfaec7b7a0821c5083125feba4b94b5e96d5 (patch) | |
tree | af5b0d04a82efae5f8f365fa3bba36a20573b412 /clang-tools-extra/test/clang-tidy/readability-non-const-parameter.cpp | |
parent | 9aa6f010a4438d579016f84302311b9992d0a0e1 (diff) | |
download | bcm5719-llvm-9e4ecfaec7b7a0821c5083125feba4b94b5e96d5.tar.gz bcm5719-llvm-9e4ecfaec7b7a0821c5083125feba4b94b5e96d5.zip |
[clang-tidy] readability-non-const-parameter: add new check that warns when function parameters should be const
The check will warn when the constness will make the function interface safer.
Reviewers: alexfh
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D15332
llvm-svn: 279507
Diffstat (limited to 'clang-tools-extra/test/clang-tidy/readability-non-const-parameter.cpp')
-rw-r--r-- | clang-tools-extra/test/clang-tidy/readability-non-const-parameter.cpp | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/clang-tools-extra/test/clang-tidy/readability-non-const-parameter.cpp b/clang-tools-extra/test/clang-tidy/readability-non-const-parameter.cpp new file mode 100644 index 00000000000..4b1896cfdfd --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/readability-non-const-parameter.cpp @@ -0,0 +1,279 @@ +// RUN: %check_clang_tidy %s readability-non-const-parameter %t + +// Currently the checker only warns about pointer arguments. +// +// It can be defined both that the data is const and that the pointer is const, +// the checker only checks if the data can be const-specified. +// +// It does not warn about pointers to records or function pointers. + +// Some external function where first argument is nonconst and second is const. +char *strcpy1(char *dest, const char *src); +unsigned my_strcpy(char *buf, const char *s); +unsigned my_strlen(const char *buf); + +// CHECK-MESSAGES: :[[@LINE+1]]:29: warning: pointer parameter 'last' can be pointer to const [readability-non-const-parameter] +void warn1(int *first, int *last) { + // CHECK-FIXES: {{^}}void warn1(int *first, const int *last) {{{$}} + *first = 0; + if (first < last) { + } // <- last can be const +} + +// TODO: warning should be written here +void warn2(char *p) { + char buf[10]; + strcpy1(buf, p); +} + +// CHECK-MESSAGES: :[[@LINE+1]]:19: warning: pointer parameter 'p' can be +void assign1(int *p) { + // CHECK-FIXES: {{^}}void assign1(const int *p) {{{$}} + const int *q; + q = p; +} + +// CHECK-MESSAGES: :[[@LINE+1]]:19: warning: pointer parameter 'p' can be +void assign2(int *p) { + // CHECK-FIXES: {{^}}void assign2(const int *p) {{{$}} + const int *q; + q = p + 1; +} + +void assign3(int *p) { + *p = 0; +} + +void assign4(int *p) { + *p += 2; +} + +void assign5(char *p) { + p[0] = 0; +} + +void assign6(int *p) { + int *q; + q = p++; +} + +void assign7(char *p) { + char *a, *b; + a = b = p; +} + +void assign8(char *a, char *b) { + char *x; + x = (a ? a : b); +} + +void assign9(unsigned char *str, const unsigned int i) { + unsigned char *p; + for (p = str + i; *p;) { + } +} + +void assign10(int *buf) { + int i, *p; + for (i = 0, p = buf; i < 10; i++, p++) { + *p = 1; + } +} + +// CHECK-MESSAGES: :[[@LINE+1]]:17: warning: pointer parameter 'p' can be +void init1(int *p) { + // CHECK-FIXES: {{^}}void init1(const int *p) {{{$}} + const int *q = p; +} + +// CHECK-MESSAGES: :[[@LINE+1]]:17: warning: pointer parameter 'p' can be +void init2(int *p) { + // CHECK-FIXES: {{^}}void init2(const int *p) {{{$}} + const int *q = p + 1; +} + +void init3(int *p) { + int *q = p; +} + +void init4(float *p) { + int *q = (int *)p; +} + +void init5(int *p) { + int *i = p ? p : 0; +} + +void init6(int *p) { + int *a[] = {p, p, 0}; +} + +void init7(int *p, int x) { + for (int *q = p + x - 1; 0; q++) + ; +} + +// CHECK-MESSAGES: :[[@LINE+1]]:18: warning: pointer parameter 'p' can be +int return1(int *p) { + // CHECK-FIXES: {{^}}int return1(const int *p) {{{$}} + return *p; +} + +// CHECK-MESSAGES: :[[@LINE+1]]:25: warning: pointer parameter 'p' can be +const int *return2(int *p) { + // CHECK-FIXES: {{^}}const int *return2(const int *p) {{{$}} + return p; +} + +// CHECK-MESSAGES: :[[@LINE+1]]:25: warning: pointer parameter 'p' can be +const int *return3(int *p) { + // CHECK-FIXES: {{^}}const int *return3(const int *p) {{{$}} + return p + 1; +} + +// CHECK-MESSAGES: :[[@LINE+1]]:27: warning: pointer parameter 'p' can be +const char *return4(char *p) { + // CHECK-FIXES: {{^}}const char *return4(const char *p) {{{$}} + return p ? p : ""; +} + +char *return5(char *s) { + return s; +} + +char *return6(char *s) { + return s + 1; +} + +char *return7(char *a, char *b) { + return a ? a : b; +} + +char return8(int *p) { + return ++(*p); +} + +void dontwarn1(int *p) { + ++(*p); +} + +void dontwarn2(int *p) { + (*p)++; +} + +int dontwarn3(_Atomic(int) * p) { + return *p; +} + +void callFunction1(char *p) { + strcpy1(p, "abc"); +} + +void callFunction2(char *p) { + strcpy1(&p[0], "abc"); +} + +void callFunction3(char *p) { + strcpy1(p + 2, "abc"); +} + +char *callFunction4(char *p) { + return strcpy1(p, "abc"); +} + +unsigned callFunction5(char *buf) { + unsigned len = my_strlen(buf); + return len + my_strcpy(buf, "abc"); +} + +void f6(int **p); +void callFunction6(int *p) { f6(&p); } + +typedef union { void *v; } t; +void f7(t obj); +void callFunction7(int *p) { + f7((t){p}); +} + +void f8(int &x); +void callFunction8(int *p) { + f8(*p); +} + +// Don't warn about nonconst function pointers that can be const. +void functionpointer(double f(double), int x) { + f(x); +} + +// TODO: This is a false positive. +// CHECK-MESSAGES: :[[@LINE+1]]:27: warning: pointer parameter 'p' can be +int functionpointer2(int *p) { + return *p; +} +void use_functionpointer2() { + int (*fp)(int *) = functionpointer2; // <- the parameter 'p' can't be const +} + +// Don't warn about nonconst record pointers that can be const. +struct XY { + int *x; + int *y; +}; +void recordpointer(struct XY *xy) { + *(xy->x) = 0; +} + +class C { +public: + C(int *p) : p(p) {} + +private: + int *p; +}; + +class C2 { +public: + // CHECK-MESSAGES: :[[@LINE+1]]:11: warning: pointer parameter 'p' can be + C2(int *p) : p(p) {} + // CHECK-FIXES: {{^}} C2(const int *p) : p(p) {}{{$}} + +private: + const int *p; +}; + +void tempObject(int *p) { + C c(p); +} + +// avoid fp for const pointer array +void constPointerArray(const char *remapped[][2]) { + const char *name = remapped[0][0]; +} + +class Warn { +public: + // CHECK-MESSAGES: :[[@LINE+1]]:21: warning: pointer parameter 'p' can be + void doStuff(int *p) { + // CHECK-FIXES: {{^}} void doStuff(const int *p) {{{$}} + x = *p; + } + +private: + int x; +}; + +class Base { +public: + // Ensure there is no false positive for this method. It is virtual. + virtual void doStuff(int *p) { + int x = *p; + } +}; + +class Derived : public Base { +public: + // Ensure there is no false positive for this method. It overrides a method. + void doStuff(int *p) override { + int x = *p; + } +}; |