-
Notifications
You must be signed in to change notification settings - Fork 1.8k
C++: Range analysis on EquivalenceClass
es
#12622
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++: Range analysis on EquivalenceClass
es
#12622
Conversation
cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll
Fixed
Show fixed
Hide fixed
CI failure is unrelated (It's complaining about autoformatting in a couple of Java queries). |
3d865d7
to
4dcf5cb
Compare
4dcf5cb
to
cd7ba7c
Compare
176b28b
to
61bafd3
Compare
Looks like this is crashing the QL compiler 😭. It only crashes the compiler with assertions enabled, however. So I was still able to run DCA (which looks fantastic now 🎉). |
29835ba
to
61bac63
Compare
61bac63
to
724d97e
Compare
exists(IR::ConvertInstruction convert | | ||
this = convert and | ||
tFrom = getSemanticType(convert.getUnary().getResultIRType()) and | ||
tTo = getSemanticType(convert.getResultIRType()) | ||
) | ||
or | ||
exists(IR::CopyValueInstruction copy | | ||
this = copy and | ||
tFrom = getSemanticType(copy.getUnary().getResultIRType()) and | ||
tTo = getSemanticType(copy.getResultIRType()) | ||
) |
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.
Minor style point, but I don't see why this can't just be
tFrom = getSemanticType(this.getUnary().getResultIRType()) and
tTo = getSemanticType(this.getResultIRType())
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.
Good call! Fixed in 4602a8a.
rank[n + 1](IR::Instruction instr, int i, IR::IRBlock block | | ||
this = Equiv::getEquivalenceClass(instr) and block.getInstruction(i) = instr | ||
| | ||
instr order by i |
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.
Can there be a situation where a Conversion or CopyValue appears in a different block than its operand?
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've never encountered such a case, no.
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.
Actually, this query:
from ConvertInstruction instr
where instr.getUnary().getBlock() != instr.getBlock()
select instr
did produce up about ~30 results on Wireshark (all related to the ternary operator). I've added d9b2a72 to ensure that we only collapse instructions in the same block.
That was a good catch!
Consider this snippet:
the
n
inn < 0
has an implicit short-to-int conversion which means that the left-hand side of<
is not actually aLoadInstruction
ofn
, but instead aConvertInstruction
of the result of aLoadInstruction
.We could fix up all of these by doing a transitive closure from the
LoadInstruction
, through all "safe conversions" and figure out if we reached the operand of<
. This is a bit ugly though, and we'd have to do this in multiple places.Instead, this PR uses the new-ish
QlBuiltins::EquivalenceRelation
feature to define a new type that unifies unconverted instructions with their safe conversions. This means that then
inn < 0
really is theLoadInstruction
(because theLoadInstruction
and theConvertInstruction
is mapped to the sameExpr
).