-
Notifications
You must be signed in to change notification settings - Fork 1.8k
C++: Fix node types #12181
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
C++: Fix node types #12181
Conversation
cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll
Outdated
Show resolved
Hide resolved
if this.isGLValue() | ||
then result = globalDef.getUnspecifiedType() | ||
else result = getTypeImpl(type.getUnspecifiedType(), globalDef.getIndirectionIndex() - 1) |
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.
Since we have type = globalDef.getUnspecifiedType()
, I think the following should do.
if this.isGLValue() | |
then result = globalDef.getUnspecifiedType() | |
else result = getTypeImpl(type.getUnspecifiedType(), globalDef.getIndirectionIndex() - 1) | |
if this.isGLValue() | |
then result = type | |
else result = getTypeImpl(type, globalDef.getIndirectionIndex() - 1) |
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.
What I don't understand is why here we do not recurse in the case of a glvalue, while in the two case below we do.
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.
Since we have type = globalDef.getUnspecifiedType(), I think the following should do.
Agreed. Thanks for that!
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.
What I don't understand is why here we do not recurse in the case of a glvalue, while in the two case below we do.
This is still unanswered 😄
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.
Yep. I'm trying to formulate a good response to this right now 😂.
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.
Take your time. I thought it might have slipped through, but apparently it didn't.
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.
What I don't understand is why here we do not recurse in the case of a glvalue, while in the two case below we do.
Yeah, that's a bit unfortunate. I couldn't quite make it fit the pattern as the other cases. The reason is that, the other cases (i.e., IndirectOperand
and IndirectInstruction
) are defined with indirection indices in the range 1 to some max number.
However, the GlobalDef
that defined an InitialGlobalValue
has an index that's in the range 0 to some max number. And that discrepancy between the ranges meant I couldn't figure out how to write it in the same style as the other two cases 😕.
It may be that the real fix is to modify the indices of InitialGlobalValue
so that its indirection index range starts 1 instead of 0 🤔. However, I'd like to delay such a larger change to another PR if you're okay with it. I can also add a version of the above explanation to a comment in this predicate if you think that's a good idea.
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.
So, isGLValue
can only be true is the index has the minimum value?
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.
Short answer: Yes.
Longer answer:
Note that isGLValue
is only implemented for InstructionNode
s, OperandNode
s and InitialGlobalValue
.InstructionNode
and OperandNode
(which intuitively can be seen as IndirectInstructionNode
s and IndirectOperandNode
s with indirection index 0) implement the predicate by checking if the underlying operand or instruction is a glvalue. Similarly, InitialGlobalValue
implements the glvalue check by checking if the indirection index is 0.
Does that make sense? I'd be happy to do a Zoom chat about it if that's any easier.
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
DCA is uneventful (as expected). |
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.
LGTM
2591460
into
github:mathiasvp/replace-ast-with-ir-use-usedataflow
This PR fixes two classes of bugs related to computing the type of a
DataFlow::Node
:Operand
s andInstruction
s weren't using the dataflow specific way to get the type of those entities. In certain cases the IR assigns some instructions anUnknown
type (for soundness reasons, I guess?) whereas there's a more intuitive type to assign to the instruction for dataflow-purposes. We were already doing the correct thing for SSA, but we weren't doing so in the dataflow files.InitialGlobalValue
node's at indirection index 0 was (e.g.)int
instead ofint*
. It should beint*
because its theInitialGlobalValue
at indirection index 1 that represents the value pointed to by the global variable.The first commit adds a new test that reveals these problems. The second commits fixes the issues, and the third commit accepts the test changes (which are all good 🎉).