JonasToth created this revision. JonasToth added reviewers: njames93, aaron.ballman, alexfh. Herald added subscribers: carlosgalvezp, xazax.hun. Herald added a project: All. JonasToth requested review of this revision. Herald added a project: clang-tools-extra. Herald added a subscriber: cfe-commits.
'misc-const-correctness' previously considered arrays as 'Values' independent of the type of the elements. This is inconsistent with the configuration of the check to disable treating pointers as values. This patch rectifies this inconsistency. Fixes #56749 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D130793 Files: clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
Index: clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp +++ clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp @@ -526,18 +526,11 @@ // CHECK-FIXES: int const p_local1[2] for (const int &const_ref : p_local1) { } +} - int *p_local2[2] = {&np_local0[0], &np_local0[1]}; - // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'int *[2]' can be declared 'const' - // CHECK-FIXES: int *const p_local2[2] - for (const int *con_ptr : p_local2) { - } - - int *p_local3[2] = {nullptr, nullptr}; - // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'int *[2]' can be declared 'const' - // CHECK-FIXES: int *const p_local3[2] - for (const auto *con_ptr : p_local3) { - } +void arrays_of_pointers_are_ignored() { + int *np_local0[2] = {nullptr, nullptr}; + // CHECK-NOT-FIXES: int * const np_local0[2] } inline void *operator new(decltype(sizeof(void *)), void *p) { return p; } @@ -908,41 +901,6 @@ sizeof(int[++N]); } -template <typename T> -struct SmallVectorBase { - T data[4]; - void push_back(const T &el) {} - int size() const { return 4; } - T *begin() { return data; } - const T *begin() const { return data; } - T *end() { return data + 4; } - const T *end() const { return data + 4; } -}; - -template <typename T> -struct SmallVector : SmallVectorBase<T> {}; - -template <class T> -void EmitProtocolMethodList(T &&Methods) { - // Note: If the template is uninstantiated the analysis does not figure out, - // that p_local0 could be const. Not sure why, but probably bails because - // some expressions are type-dependent. - SmallVector<const int *> p_local0; - // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'SmallVector<const int *>' can be declared 'const' - // CHECK-FIXES: SmallVector<const int *> const p_local0 - SmallVector<const int *> np_local0; - for (const auto *I : Methods) { - if (I == nullptr) - np_local0.push_back(I); - } - p_local0.size(); -} -void instantiate() { - int *p_local0[4] = {nullptr, nullptr, nullptr, nullptr}; - // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int *[4]' can be declared 'const' - // CHECK-FIXES: int *const p_local0[4] - EmitProtocolMethodList(p_local0); -} struct base { int member; }; Index: clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp +++ clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp @@ -11,3 +11,57 @@ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double *' can be declared 'const' // CHECK-FIXES: double *const p_local0 } + +void range_for() { + int np_local0[2] = {1, 2}; + int *p_local0[2] = {&np_local0[0], &np_local0[1]}; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int *[2]' can be declared 'const' + // CHECK-FIXES: int *const p_local0[2] + for (const int *p_local1 : p_local0) { + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local1' of type 'const int *' can be declared 'const' + // CHECK-FIXES: for (const int *const p_local1 : p_local0) + } + + int *p_local2[2] = {nullptr, nullptr}; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'int *[2]' can be declared 'const' + // CHECK-FIXES: int *const p_local2[2] + for (const auto *con_ptr : p_local2) { + } + +} + +template <typename T> +struct SmallVectorBase { + T data[4]; + void push_back(const T &el) {} + int size() const { return 4; } + T *begin() { return data; } + const T *begin() const { return data; } + T *end() { return data + 4; } + const T *end() const { return data + 4; } +}; + +template <typename T> +struct SmallVector : SmallVectorBase<T> {}; + +template <class T> +void EmitProtocolMethodList(T &&Methods) { + // Note: If the template is uninstantiated the analysis does not figure out, + // that p_local0 could be const. Not sure why, but probably bails because + // some expressions are type-dependent. + SmallVector<const int *> p_local0; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'SmallVector<const int *>' can be declared 'const' + // CHECK-FIXES: SmallVector<const int *> const p_local0 + SmallVector<const int *> np_local0; + for (const auto *I : Methods) { + if (I == nullptr) + np_local0.push_back(I); + } + p_local0.size(); +} +void instantiate() { + int *p_local0[4] = {nullptr, nullptr, nullptr, nullptr}; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int *[4]' can be declared 'const' + // CHECK-FIXES: int *const p_local0[4] + EmitProtocolMethodList(p_local0); +} Index: clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp +++ clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp @@ -11,6 +11,7 @@ #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" +#include "llvm/Support/Casting.h" #include <iostream> @@ -132,6 +133,12 @@ VC = VariableCategory::Reference; if (Variable->getType()->isPointerType()) VC = VariableCategory::Pointer; + if (Variable->getType()->isArrayType()) { + if (const auto *ArrayT = dyn_cast<ArrayType>(Variable->getType())) { + if (ArrayT->getElementType()->isPointerType()) + VC = VariableCategory::Pointer; + } + } // Each variable can only be in one category: Value, Pointer, Reference. // Analysis can be controlled for every category.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits