Author: Artem Dergachev Date: 2021-05-10T14:00:31-07:00 New Revision: 91ca3269a1b544db1303b496101fd9d6fe953277
URL: https://github.com/llvm/llvm-project/commit/91ca3269a1b544db1303b496101fd9d6fe953277 DIFF: https://github.com/llvm/llvm-project/commit/91ca3269a1b544db1303b496101fd9d6fe953277.diff LOG: [clang-tidy] Aliasing: Add support for aggregates with references. When a variable is used in an initializer of an aggregate for its reference-type field this counts as aliasing. Differential Revision: https://reviews.llvm.org/D101791 Added: Modified: clang-tools-extra/clang-tidy/utils/Aliasing.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp index 12a8ca8185b0f..69aea1145de50 100644 --- a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp +++ b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp @@ -50,6 +50,13 @@ static bool isPtrOrReferenceForVar(const Stmt *S, const VarDecl *Var) { } else if (const auto *LE = dyn_cast<LambdaExpr>(S)) { // Treat lambda capture by reference as a form of taking a reference. return capturesByRef(LE->getLambdaClass(), Var); + } else if (const auto *ILE = dyn_cast<InitListExpr>(S)) { + return llvm::any_of(ILE->inits(), [Var](const Expr *ChildE) { + // If the child expression is a reference to Var, this means that it's + // used as an initializer of a reference-typed field. Otherwise + // it would have been surrounded with an implicit lvalue-to-rvalue cast. + return isAccessForVar(ChildE, Var); + }); } return false; diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp index 5b477130a7b01..2765b181db2c5 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp @@ -566,3 +566,29 @@ int foo(void) { } return 0; } + +struct AggregateWithReference { + int &y; +}; + +void test_structured_bindings_good() { + int x = 0; + AggregateWithReference ref { x }; + auto &[y] = ref; + for (; x < 10; ++y) { + // No warning. The loop is finite because 'y' is a reference to 'x'. + } +} + +struct AggregateWithValue { + int y; +}; + +void test_structured_bindings_bad() { + int x = 0; + AggregateWithValue val { x }; + auto &[y] = val; + for (; x < 10; ++y) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of its condition variables (x) are updated in the loop body [bugprone-infinite-loop] + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits