Skip to content

programmemory.cpp: avoid calls to non-const at() / added utils::as_const()#6651

Merged
chrchr-github merged 2 commits intocppcheck-opensource:mainfrom
firewave:pm-const
Aug 2, 2024
Merged

programmemory.cpp: avoid calls to non-const at() / added utils::as_const()#6651
chrchr-github merged 2 commits intocppcheck-opensource:mainfrom
firewave:pm-const

Conversation

@firewave
Copy link
Copy Markdown
Collaborator

No description provided.

@firewave
Copy link
Copy Markdown
Collaborator Author

firewave commented Jul 31, 2024

-D__GNUC__ --check-level=exhaustive ../lib/utils.cpp

Clang 17 773,369,412 -> 756,793,758
GCC 14 794,493,015 -> 778,810,008

The example from https://trac.cppcheck.net/ticket/10765#comment:4:

Clang 17 3,988,168,871 -> 3,958,401,0425
GCC 14 4,098,327,498 -> 4,074,480,389

@firewave firewave marked this pull request as draft July 31, 2024 23:29
@firewave firewave changed the title ProgramMemory: avoid unnecessary copy in Executor::executeImpl() ProgramMemory: avoid calls to non-const at() Jul 31, 2024
@firewave firewave changed the title ProgramMemory: avoid calls to non-const at() programmemory.cpp: avoid calls to non-const at() Jul 31, 2024
@firewave
Copy link
Copy Markdown
Collaborator Author

There is still one case I have to look at.

@firewave
Copy link
Copy Markdown
Collaborator Author

And we really need an as_const() helper.

@firewave
Copy link
Copy Markdown
Collaborator Author

firewave commented Aug 1, 2024

There is still one case I have to look at.

I will leave that out for now because the impact is currently quite neglectable.

@firewave firewave marked this pull request as ready for review August 1, 2024 08:01
@chrchr-github
Copy link
Copy Markdown
Collaborator

Why would this have a performance impact?

@firewave
Copy link
Copy Markdown
Collaborator Author

firewave commented Aug 1, 2024

Why would this have a performance impact?

As we are working in a mutable context it will chose the non-const implementation. And if we return something mutable we need to do copy-on-write first so the (potential) changes are only applied to the copy.

@chrchr-github
Copy link
Copy Markdown
Collaborator

Why would this have a performance impact?

As we are working in a mutable context it will chose the non-const implementation. And if we return something mutable we need to do copy-on-write first so the (potential) changes are only applied to the copy.

I see. I somehow confused this with mValues->at().

@firewave
Copy link
Copy Markdown
Collaborator Author

firewave commented Aug 1, 2024

I see. I somehow confused this with mValues->at().

Yeah, it should have probably been called getValue() to be in line with hasValue().

@chrchr-github
Copy link
Copy Markdown
Collaborator

And we really need an as_const() helper.

It would make the intent more clear and maybe prevent someone from "cleaning up" in the future.
The implementation seems quite simple: https://en.cppreference.com/w/cpp/utility/as_const

@firewave
Copy link
Copy Markdown
Collaborator Author

firewave commented Aug 1, 2024

And we really need an as_const() helper.

It would make the intent more clear and maybe prevent someone from "cleaning up" in the future. The implementation seems quite simple: https://en.cppreference.com/w/cpp/utility/as_const

I ran into issue with that and need to check how the actual implementation behaves so it will be drop-in in the future.

Also it would be great to have tooling which tells you where to use it because checking the code manually is quite tedious even with IDE tooltips.

Comment thread lib/programmemory.cpp Outdated
if (pm->hasValue(expr->exprId())) {
const ValueFlow::Value& v = pm->at(expr->exprId());
const auto& pm2 = *pm;
const ValueFlow::Value& v = pm2.at(expr->exprId());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just remove the non-const overload for at? I dont think its ever used.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used in three places in Executor::executeImpl().

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can rename the mutable version as mutate_at to make it explicit when we want to mutate.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that is unnecessary. I will add a barebones as_const() to clean up the code.

@firewave firewave changed the title programmemory.cpp: avoid calls to non-const at() programmemory.cpp: avoid calls to non-const at() / added utils::as_const() Aug 1, 2024
Comment thread test/testutils.cpp
{
C c;
C* cp = &c;
utils::as_const(cp)->f(); // (correctly) calls non-const version
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's why we need to dereference the pointers in the actual code.

I filed tickets about detecting this: llvm/llvm-project#101580 / https://trac.cppcheck.net/ticket/12977.

@chrchr-github chrchr-github merged commit d863262 into cppcheck-opensource:main Aug 2, 2024
@firewave firewave deleted the pm-const branch August 2, 2024 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants