Skip to content

performance-unnecessary-value-param not detected for STL container when accessed via index operator #69577

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
firewave opened this issue Oct 19, 2023 · 4 comments

Comments

@firewave
Copy link

#include <string>

void f(std::string type)
{
    const char Type = type[0];
}

https://godbolt.org/z/ae3efnTvs

@llvmbot
Copy link
Member

llvmbot commented Oct 19, 2023

@llvm/issue-subscribers-clang-tidy

Author: Oliver Stöneberg (firewave)

```cpp #include <string>

void f(std::string type)
{
const char Type = type[0];
}

https://godbolt.org/z/ae3efnTvs
</details>

@firewave
Copy link
Author

Also not detected with other STL containers:

#include <vector>

void cb(const int *);

void f(std::vector<const int*> v)
{
    if (v.size() != 2)
        return;
    cb(v[0]);
}

https://godbolt.org/z/bcsr8hs3c

@firewave firewave changed the title performance-unnecessary-value-param not detected for std::string when accessed via index operator performance-unnecessary-value-param not detected for STL container when accessed via index operator Oct 19, 2023
@neoncube2
Copy link
Contributor

I did some digging into this :)

The code results in this AST:

CompoundStmt 0x166f9b9c8b8 <D:\llvm\bugs\UnnecessaryValueParam\Example.cpp:4:1, line:6:1>
`-DeclStmt 0x166f9b9c8a0 <line:5:5, col:30>
  `-VarDecl 0x166f9b9c6d0 <col:5, col:29> col:16 Type 'const char' cinit
    `-ImplicitCastExpr 0x166f9b9c840 <col:23, col:29> 'value_type':'char' <LValueToRValue>
      `-CXXOperatorCallExpr 0x166f9b9c7d0 <col:23, col:29> 'value_type':'char' lvalue '[]'
        |-ImplicitCastExpr 0x166f9b9c7b8 <col:27, col:29> 'reference (*)(const size_type) noexcept' <FunctionToPointerDecay>
        | `-DeclRefExpr 0x166f9b9c798 <col:27, col:29> 'reference (const size_type) noexcept' lvalue CXXMethod 0x166fa443d58 'operator[]' 'reference (const size_type) noexcept'
        |-DeclRefExpr 0x166f9b9c738 <col:23> 'std::string':'std::basic_string<char>' lvalue ParmVar 0x166f9b9c4f8 'type' 'std::string':'std::basic_string<char>'
        `-ImplicitCastExpr 0x166f9b9c780 <col:28> 'size_type':'unsigned long long' <IntegralCast>
          `-IntegerLiteral 0x166f9b9c758 <col:28> 'int' 0

The CXXOperatorCallExpr is causing performance-unnecessary-value-param not to fire.

There are two different methods in std::basic_string<CharT,Traits,Allocator>::operator[], one const and one non-const:

  • reference operator[]( size_type pos );
  • const_reference operator[]( size_type pos ) const;

For some reason, it looks like clang is picking up the non-const method, and performance-unnecessary-value-param only works if all of the method calls are const.

@firewave
Copy link
Author

Related/duplicate: #59750.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants