Skip to content

Fix #15158 mismatchingContainers message refers to data pointers as iterators - #8980

Merged
chrchr-github merged 10 commits into
cppcheck-opensource:mainfrom
chrchr-github:chr_15158
Nov 7, 2026
Merged

chrchr-github merged 10 commits into
cppcheck-opensource:mainfrom
chrchr-github:chr_15158

Conversation

@chrchr-github

Copy link
Copy Markdown
Collaborator

No description provided.

@dmcppcheck

Copy link
Copy Markdown
Contributor

Test results for commit cd98726 (tools/test-my-pr.py, main compared to this PR):

Test: http://ec2-16-170-140-253.eu-north-1.compute.amazonaws.com/pr-8980/
packages: 100
Differing warnings: 6 (+3 -3)
AI review: 6 neutral (http://ec2-16-170-140-253.eu-north-1.compute.amazonaws.com/pr-8980/2026-11-02_06-47-03-cd987265d1ff-review.txt)
Timing: -0.2% (http://ec2-16-170-140-253.eu-north-1.compute.amazonaws.com/pr-8980/2026-11-02_06-47-03-cd987265d1ff_timing.html)

Posted automatically by the cppcheck PR test runner. +N: warnings only with this PR, -N: warnings only with main. The AI review is written by Claude and can be wrong.

@chrchr-github

Copy link
Copy Markdown
Collaborator Author

See https://trac.cppcheck.net/ticket/15166 for the preexisting FP found by AI.

@dmcppcheck dmcppcheck left a comment

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.

AI review

The new wording is still wrong in one case. LifetimeKind::Object is assumed to always mean a container, so taking the addresses of members of two plain structs gives "Pointers of different containers 's1' and 's2'". The objects are not containers, and fixing that kind of misleading message is the point of #15158. Apart from this I found no problems. TestStl passes, and the other variations I tried (vector/string data(), &a[0], unique_ptr<int[]>::get(), arrays, real iterators) get sensible wording.

Testing

I built cppcheck and testrunner in pr/. ./testrunner TestStl passed: 123 tests, 0 failures.

I checked the changed message with /work/pr/cppcheck -q --enable=all --library=std t1.cpp:

#include <algorithm>
#include <vector>
#include <string>
#include <memory>
struct S { int x; int y; };
void f2(std::vector<int>& a, std::vector<int>& b) { std::sort(a.data(), b.data() + 1); }
void f3(S s1, S s2) { std::sort(&s1.x, &s2.y); }
void f5(std::unique_ptr<int[]>& a, std::unique_ptr<int[]>& b) { std::sort(a.get(), b.get()); }
void f6(std::string& a, std::string& b) { std::sort(a.begin(), b.end()); }
void f9() { int a1[10], b1[10]; std::sort(&a1[0], &b1[10]); }

Output (abridged):

t1.cpp:6: error: Pointers of different containers 'a' and 'b' are used together. [mismatchingContainers]
t1.cpp:7: error: Pointers of different containers 's1' and 's2' are used together. [mismatchingContainers]   <-- S is not a container
t1.cpp:8: error: Pointers of different objects 'a' and 'b' are used together. [mismatchingContainers]
t1.cpp:9: error: Iterators of different containers 'a' and 'b' are used together. [mismatchingContainers]
t1.cpp:10: error: Addresses of different objects 'a1' and 'b1' are used together. [mismatchingContainers]

Only the f3 message is wrong. The rest read correctly.


Automated review of cd98726 by Claude. The pull request was built and tested locally.

Comment thread lib/checkstl.cpp
const std::string expr1(tok1 ? tok1->expressionString() : std::string("v1"));
const std::string expr2(tok2 ? tok2->expressionString() : std::string("v2"));
const std::string dataStr = (ltk == ValueFlow::Value::LifetimeKind::Iterator) ? "Iterators" : (ltk == ValueFlow::Value::LifetimeKind::Address ? "Addresses" : "Pointers");
const std::string objectStr = (ltk == ValueFlow::Value::LifetimeKind::Iterator || ltk == ValueFlow::Value::LifetimeKind::Object) ? "containers '" : "objects '";

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.

AI review

This treats LifetimeKind::Object as if it always meant a container, but Object is also the kind for a pointer to a member of any object. For example:

struct S { int x; int y; };
void f3(S s1, S s2) { std::sort(&s1.x, &s2.y); }

This now reports Pointers of different containers 's1' and 's2' are used together., and S is not a container. Choosing between "containers" and "objects" based on whether the token is actually a container (e.g. astIsContainer(tok1)) would fix this.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

do you think this makes sense? If you can fix it please do.. otherwise this PR lgtm..

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 there might be a ValueFlow issue/inconsistency, still need to check that.

@pfultz2 pfultz2 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This LGTM. I think we can file a trac ticket for the remaining issue and fix it later:

struct S { int x; int y; };
void f3(S s1, S s2) { std::sort(&s1.x, &s2.y); }

@chrchr-github

Copy link
Copy Markdown
Collaborator Author

I wonder if this is how things should be:

struct S {
    std::string x;
    std::unique_ptr<int> u;
};
void f(int a, S s) {
    g(&a, &s.x, s.x.c_str(), s.x.begin(), s.u.get());
}
  & {lifetime[Address]=(a),!0}
  & {lifetime[Object]=(s),!0}
  ( {lifetime[Object]=(s.x),lifetime[Object]=(s),!0}
  ( {lifetime[Iterator]=(s.x),lifetime[Object]=(s),start=0}
  ( {lifetime[SubObject]=(s.u),symbolic=(s.u)}

@danmar danmar left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

if you post ticket(s) about remaining issues, feel free to merge this.

@chrchr-github
chrchr-github merged commit 30a9878 into cppcheck-opensource:main Nov 7, 2026
71 checks passed
@chrchr-github
chrchr-github deleted the chr_15158 branch November 7, 2026 12:07
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.

4 participants