<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/79580>79580</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
bugprone-too-small-loop-variable - false-negative when const variable is used as loop bound
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang-tidy,
false-negative
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
PiotrZSL
</td>
</tr>
</table>
<pre>
Example:
```
unsigned int getVal() {
return 300; // or just have some other function calls here that at the end return value above 255
}
int main() {
{
const auto l = getVal();
for (unsigned char i = 0; i < l; ++i) { ; }
}
{
const unsigned int l = getVal();
for (unsigned char i = 0; i < l; ++i) { ; }
}
}
```
Above issues are not detected, and lead to endless loop. This is because in AST this code looks like this:
```
`-ForStmt <line:13:9, line:16:9>
| |-DeclStmt <line:13:14, col:27>
| | `-VarDecl <col:14, col:26> col:22 used i 'uint8_t':'unsigned char' cinit
| | `-ImplicitCastExpr <col:26> 'uint8_t':'unsigned char' <IntegralCast>
| | `-IntegerLiteral <col:26> 'int' 0
| |-<<<NULL>>>
| |-BinaryOperator <col:29, col:33> 'bool' '<'
| | |-ImplicitCastExpr <col:29> 'std::uint32_t':'unsigned int' <IntegralCast>
| | | `-ImplicitCastExpr <col:29> 'uint8_t':'unsigned char' <LValueToRValue>
| | | `-DeclRefExpr <col:29> 'uint8_t':'unsigned char' lvalue Var 0xc827c30 'i' 'uint8_t':'unsigned char'
| | `-ImplicitCastExpr <col:33> 'std::uint32_t':'unsigned int' <LValueToRValue>
| | `-DeclRefExpr <col:33> 'const std::uint32_t':'const unsigned int' lvalue Var 0xc827900 'l' 'const std::uint32_t':'const unsigned int'
| |-UnaryOperator <col:36, col:38> 'uint8_t':'unsigned char' lvalue prefix '++' cannot overflow
| | `-DeclRefExpr <col:38> 'uint8_t':'unsigned char' lvalue Var 0xc827c30 'i' 'uint8_t':'unsigned char'
```
Type used for loop bound is actually const, because local variable is const.
And in check code matcher:
```
StatementMatcher LoopBoundMatcher =
expr(ignoringParenImpCasts(allOf(hasType(isInteger()),
unless(integerLiteral()),
unless(hasType(isConstQualified())),
unless(hasType(enumType())))))
.bind(LoopUpperBoundName);
```
uses `unless(hasType(isConstQualified()))` to ignore code like this:
```
// A suspicious loop is not caught if the iteration's upper bound is a constant variable.
void voidForLoopWithConstBound() {
const long size = 252l;
for (short i = 0; i < size; ++i) { // no warning
}
}
// The used constant variable leads to an infinite loop.
// This is caught by -Wtautological-constant-out-of-range-compare.
void voidForLoopWithBigConstBound() {
const long size = 294967296l;
for (short i = 0; i < size; ++i) { // no warning
}
}
```
Originally this were used to ignore code duplication between -Wtautological-constant-out-of-range-compare compiler warning and this check, but it were implemented incorrectly.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8V91u4zoOfhrlhnDgyvnzRS6StAUG6J45e9rpAfZmIcuMrRlFMiQ5bffpF5SdNGk83XYWmMK1HYHiz0eK_Cy8V5VBXLLpmk2vR6INtXXLP5UN7l_3d6PCli_Lm2exazSybMXSa5au2Cztr_izNVFHCcoEqDA8Cs34gvEc2HzdiQAAOAytM5ClKcvWwPgt47dgHXxvfYBa7BG83SHYUKODbWtkUNaAFFp7qNEhhFoEEAFCjYCmPCjcC90iiMLuEfh02rs4v-5f4p082wllLvw685D-pDU-gGiDBQ0suz4LiGVvpLfWAeOLIwKyFg5U3BejpNcN6C7gNeNrReYByC5AXD442q2eed0LDjl4hvlvdvTVy-PLeUF091XMiPK-RQ_CIRgboMSAMmDJ-AaEKUGjKCFYyqdG70Fb24zhoVYelIcCpWg9gjKwun-AQMvSlkhiPzxo9QPj4s8qk83S5Na6-7ALFJ9Whor4KmPZKicPDguzuJDdnMK-6e7JNUo9pOBqQhqk1Sxb8fnF5vg_S5NH4UgD7e5kz_bNWHZzeOfQekooMD5vlQmLfwdGilf0-zRvjM9BKqPCgLt0n6XJl12jlVRhI3y4eW7cq_nO5EdMsGzzxQSsnNCkZhieWFzRIomiu1MBndAD9pQhW5BewJSwbNNdf3y7uyMz3TWQi7Uywr18bdCJYE-Dyl8xzbLeYGGtjnFQhBu6XyZovnkPqrzX5ENJGGUrwizjQ6D10X0Ms0NtfMD0R7J090gd8MH-FZ_v2OwyReX4F25_1aDu-u2jcJA-ywWfyyyN-e2x_l8KBp17F4xjRj-Vhw-h8g4iR6tdw_257cuGPAhTnkaYDiX5S1qHzsS34SORzU6OxOKTyW0cbtVzPDlxGMSOIww1cLtHt9X2abjbDSP5WfP_Z229GQIPLw12rZWGIA0YKGxrShowQoZWaP3STVVC7DBytJVCw144JQpNY6wTGZ9NOFJiQNYof3RzaSeCrNH9bB7BfRABd2jCPzpBuLO2WZM3hwWWHcYsPjeO8YWqjHXKVH8Kh-bLrqHz4RlfCK2_bhlf1MJThCTp-ybcc4DYFXtlraHxSkJnffo9yVPFG4r9n63QaqtoeB93vb8RTbvrX082HK5u27hQhjQSEt-aBl2E4w-xw1MeM8gwWo-eyu6zLs9SohwRWOz5xCWTGMxfz1pX4FvfKKls21EWqg86HVK0VR1AbSNJjRgTi6XeBS0Fd1J6XUEJE45V1hcX7K0q4-3WOoLlbxXqGE6EZoBbd81CW1OBV__BSOv4lOtTGtgzQF9bFy6ZH217Q_6I-fXxGgtPwhllqqO6ITp4htFD3Z-6izAj6fOUAmFAmS1RGeyY31sVHQ3sUS1eIPk7EDXXtlJS6OSgOrFtSOw2ccJUmEi7a4R7F821qj4PaD7JZ3Oez05g_Q2gDhX-V6cqZWLjipz4iT6PIthv6rpsaajGGoQCwxOi-RSGQE-l0R1cjaS94-HU9WLHbAOo0Pmg6DuR-lscWdI6hzLol_GoXGZlnuVihMureTrjs3ya8VG9lNui4DnKYo6iKGU2ySbzUk7KVMzTTM5nI7XkKZ-kV3x2dTWZZnxc5FJeodzy-YQXZZ6zSYo7ofRY6_1ubF01ip8cy3k-XaQjLQrUPn7dci61MFUSVPnCOKfGxflWaI-JwUoEtUdanl6P3JJ0JUVbeTZJtfLBv2oPKmhcFm3VOGswCdYmfie0TqiAk2ONJ3CuGp5qNH1dnU6VmDXhT-bSqHV6WYfQxGYUa6VSoW6LsbQ7xm_Jk_6RNM5-RxkYv-2-sxi_jXH_NwAA__9ltKOL">