-
Notifications
You must be signed in to change notification settings - Fork 1.5k
pass TokenList as reference into ValueFlow::setValues()
#4868
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
Conversation
|
|
||
| struct ValueFlowAnalyzer : Analyzer { | ||
| const TokenList* tokenlist; | ||
| const TokenList& tokenlist; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to use pointers as members instead of references. Otherwise it makes the class non regular(not assignable or default constructible).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, when using the object after move, a pointer can be a nullptr which is easier to diagnose the issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the functionality? They are local objects that are just being passed around.
The point is to avoid that it could ever be a nullptr. Since they are just used internally and the object will always exist it is impossible to happen but I think it would be better not to allow it anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, when using the object after move, a pointer can be a nullptr which is easier to diagnose the issue.
That is a good point. But until #4845 is merged they are not being moved at all. As it seems to complicate things and probably won't give any meaningful improvement I am open to dropping it anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is cppcoreguidelines-avoid-const-or-ref-data-members check in clang tidy which will find these issues. We should enable this check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are also using way too many struct without any access modifiers allowing modification of any members of them if objects are not longer const. We have countless hidden issues because of that which luckily rarely cause issues (as they are mostly in the tests) but just yesterday I ran into one in production code which might cause files to be analyzed with wrong settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay - pointer to const objects are still allowed. That makes things just slightly better. But still being able to re-assign them in the class is dangerous. So to properly get a working const * const-like construct you would need some data class with accessors.
class C1
{
public:
bool f() const;
};
class C2Data
{
protected:
C2Data(const C1 &c1) : mC1(&c1) {}
const C1 &c1() const { return *mC1; }
private:
const C1 * mC1;
};
class C2 : public C2Data
{
public:
C2(const C1 &c1) : C2Data(c1) {}
bool f() {
return c1().f();
}
};
static void f()
{
const C1 c1;
C2 c2(c1);
}Maybe you have to adjust the inheritance access but if I ever knew something about that I have forgotten it.
Still somebody would be able to do stupid things within C2Data. That would require some other check that tells you the data class is only there for storage and accessors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or simply std::reference_wrapper?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea you could use std::reference_wrapper here(which is similar to gsl::non_null)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright. I will start testing it after I am done with most of my backlog. That will probably spill into the next dev cycle since I keep unearthing issues addressing other things and I don't want to pile yet another refactoring on top of it.
If ever we want to use these classes with any generic function/algorithm(ie swap) then we do. These are fundamental operations on types. Making classes non-regular very much limits what we can do in the future. There is already certain types of analysis we can't do because |
Ok. Can we leave the parameter a reference and just store the pointer?
Could you please track those issues in tickets? Thanks. |
|
The |
Yes, parameters should be references, but member variables should not. |
And if I hand it out I could make it a reference again? That sounds like you should have something like a |
|
We want something like gsl::non_null. |
|
Sometimes I am just stupid - what about #4785? I was thinking about disallowing |
|
We already use this pattern all over the place and it is not an isolated case. So could we discuss this in the other ticket and merge this? I have a few more commits depending on this and IIRC those are just parameter and not member changes so things and even if things would just very, very slightly get worse. |
I dont think its helpful to have a non-owning pointer propagate const. It can be simply bypassed by copying the pointer: void f(const safe_ptr<int>& ptr) {
// *ptr += 1 doesnt compile, but the below does
auto ptr2 = ptr;
*ptr += 1;
}Its better to use |
Obviously - but those are not meant to be used outside of the class. It's to enforce the "physical constness" as far as possible and reducing the code which relies on "logical constness".
If it is |
f12375c to
35fc752
Compare
91345e1 to
2b33083
Compare
|
Another |
e011760 to
b403f49
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me
This avoid lots of unchecked pointer dereferences.
There was a single case which checked it and that looked like a leftover. The only way this might have been a
nullptrpointer was through several default constructors which were not used at all so I removed them.