llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-tidy Author: Zeyi Xu (zeyi2) <details> <summary>Changes</summary> Avoid calling `DeclStmt::getSingleDecl()` unless the declaration statement contains a single declaration. Closes https://github.com/llvm/llvm-project/issues/203856 --- Full diff: https://github.com/llvm/llvm-project/pull/203865.diff 3 Files Affected: - (modified) clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp (+4-2) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+5) - (modified) clang-tools-extra/test/clang-tidy/checkers/altera/unroll-loops.cpp (+53) ``````````diff diff --git a/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp b/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp index 15fa75f19ef28..eb41acaf4650a 100644 --- a/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp +++ b/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp @@ -124,7 +124,8 @@ bool UnrollLoopsCheck::hasKnownBounds(const Stmt *Statement, if (!Initializer || !Conditional || !Increment) return false; // If the loop variable value isn't known, loop bounds are unknown. - if (const auto *InitDeclStatement = dyn_cast<DeclStmt>(Initializer)) { + if (const auto *InitDeclStatement = dyn_cast<DeclStmt>(Initializer); + InitDeclStatement && InitDeclStatement->isSingleDecl()) { if (const auto *VariableDecl = dyn_cast<VarDecl>(InitDeclStatement->getSingleDecl())) { const APValue *Evaluation = VariableDecl->evaluateValue(); @@ -173,7 +174,8 @@ bool UnrollLoopsCheck::hasLargeNumIterations(const Stmt *Statement, const Expr *Increment = ForLoop->getInc(); int InitValue = 0; // If the loop variable value isn't known, we can't know the loop bounds. - if (const auto *InitDeclStatement = dyn_cast<DeclStmt>(Initializer)) { + if (const auto *InitDeclStatement = dyn_cast<DeclStmt>(Initializer); + InitDeclStatement && InitDeclStatement->isSingleDecl()) { if (const auto *VariableDecl = dyn_cast<VarDecl>(InitDeclStatement->getSingleDecl())) { APValue *Evaluation = VariableDecl->evaluateValue(); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 9703bb8f17208..5b1c3fb169fa6 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -343,6 +343,11 @@ Changes in existing checks positives when ordinary variable or field assignments are used in loop conditions and note locations for inferred ID-dependent fields. +- Improved :doc:`altera-unroll-loops + <clang-tidy/checks/altera/unroll-loops>` check by fixing a crash when + analyzing a ``for`` loop whose initialization statement declares multiple + variables. + - Improved :doc:`bugprone-argument-comment <clang-tidy/checks/bugprone/argument-comment>`: diff --git a/clang-tools-extra/test/clang-tidy/checkers/altera/unroll-loops.cpp b/clang-tools-extra/test/clang-tidy/checkers/altera/unroll-loops.cpp index c06cec794e8eb..05a9e1b21c011 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/altera/unroll-loops.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/altera/unroll-loops.cpp @@ -125,6 +125,30 @@ void for_loops(int *A, int size) { A[i]++; } +#pragma unroll + for (int i = 0, j = 0; i < 50; ++i) { + A[i] += j; + } + +#pragma unroll + for (int i = 0, j = 0; i < 50; ++i, ++j) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll <num>' directive + // FIXME: This is a false positive. + A[i] += j; + } + +#pragma unroll + for (int j = size, i = 0; i < 50; ++i) { + A[i] += j; + } + +#pragma unroll + for (int j = 0, i = 100; i < 150; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll <num>' directive + // FIXME: This is a false positive. + A[i] += j; + } + // Loop with unknown size should be partially unrolled. #pragma unroll for (int i = 0; i < size; ++i) { @@ -132,6 +156,18 @@ void for_loops(int *A, int size) { A[i]++; } +#pragma unroll + for (int i = 0, j = 0; i < size; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll <num>' directive + A[i] += j; + } + +#pragma unroll + for (int j = 0, i = size; i < 50; ++i) { + // FIXME: This is a false negative. + A[i] += j; + } + #pragma unroll for (;;) { // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll <num>' directive [altera-unroll-loops] @@ -181,6 +217,11 @@ void for_loops(int *A, int size) { A[i]++; } +#pragma unroll 5 + for (int i = 0, j = 0; i < size; ++i) { + A[i] += j; + } + // Loop with large size should be partially unrolled. #pragma unroll for (int i = 0; i < 51; ++i) { @@ -188,6 +229,18 @@ void for_loops(int *A, int size) { A[i]++; } +#pragma unroll + for (int i = 0, j = 0; i < 51; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll <num>' directive + A[i] += j; + } + +#pragma unroll + for (int j = 100, i = 0; i < 51; ++i) { + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll <num>' directive + A[i] += j; + } + // Loop with large size correctly unrolled. #pragma unroll 5 for (int i = 0; i < 51; ++i) { `````````` </details> https://github.com/llvm/llvm-project/pull/203865 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
