There are 3 different cases when an ArrayInitLoopExpr is used to initialize an array.
- in the implicit copy/move constructor for a class with an array member
- when a lambda-expression captures an array by value
- when a decomposition declaration decomposes an array
The AST of such expression (usually) looks like this:
|-ArrayInitLoopExpr 'int[3]' | | |-OpaqueValueExpr 'int[3]' lvalue | | | `-DeclRefExpr 'int[3]' lvalue Var 'arr' 'int[3]' | | `-ImplicitCastExpr 'int' <LValueToRValue> | | `-ArraySubscriptExpr 'int' lvalue | | |-ImplicitCastExpr 'int *' <ArrayToPointerDecay> | | | `-OpaqueValueExpr 'int[3]' lvalue | | | `-DeclRefExpr 'int[3]' lvalue Var 'arr' 'int[3]' | | `-ArrayInitIndexExpr <<invalid sloc>> 'unsigned long'
We basically always have an ArraySubscriptExpr, where the index is an ArrayInitIndexExpr.
ArrayInitIndexExpr is not a constant, so the checker mentioned in the title reports a warning.
This false positive warning only happens in case of decomposition declaration and lambda capture.
Some example without this patch:
void foo() { int arr[3]; auto [a, b, c] = arr; } --------------------------------------------------------------- warning: do not use array subscript when the index is not an integer constant expression [cppcoreguidelines-pro-bounds-constant-array-index] auto [a, b, c] = arr; ^
void foo() { int arr[3]; [arr]() {}; } --------------------------------------------------------------- warning: do not use array subscript when the index is not an integer constant expression [cppcoreguidelines-pro-bounds-constant-array-index] [arr]() {}; ^
You shouldn't need to add an extra RUN line, check_clang_tidy already loops over all language standards.