Commit Graph

146 Commits

Author SHA1 Message Date
Jonas Jensen
76a3db9eed Merge remote-tracking branch 'upstream/master' into ir-copy-unloaded-result 2019-11-06 15:21:22 +01:00
Robert Marsh
31f25c8cfc C++: primary instrs for constructor side effects 2019-10-31 11:43:47 -07:00
Robert Marsh
86b5e97f76 Merge branch 'master' of github.com:Semmle/ql into rdmarsh/cpp/ir-constructor-side-effects 2019-10-31 11:34:22 -07:00
Robert Marsh
9477bd5698 Merge branch 'master' of github.com:Semmle/ql into rdmarsh/cpp/ir-buffer-read-call-se 2019-10-31 11:00:01 -07:00
Robert Marsh
8076156cb1 Merge branch 'master' into rdmarsh/cpp/ir-callee-side-effects 2019-10-28 16:50:34 -07:00
Robert Marsh
120fa6c330 C++: alias fixes for ReturnIndirection 2019-10-28 15:09:35 -07:00
Robert Marsh
5e946cc9f3 C++: add param read side effects to IR exit blocks 2019-10-28 15:09:04 -07:00
Dave Bartolomeo
cc5a689293 C++/C#: Fix up after merge from master 2019-10-25 14:11:34 -07:00
Jonas Jensen
22de0efc58 Merge pull request #2008 from dave-bartolomeo/dave/IRType2
C++: Implement language-neutral IR type system
2019-10-25 09:42:23 +02:00
Jonas Jensen
7a6ec83572 C++: No CopyValue for immediately discarded exprs
Expressions like the `e` in `e;` or `e, e2`, whose result is immediately
discarded, should not get a synthetic `CopyValue`. This removes a lot of
redundancy from the IR.

To prevent these expressions from being confused with the expressions
from which they get their result, the predicate
`getInstructionConvertedResultExpression` now suppresses results for
expressions that don't produce their own result. This should fix the
mapping between expressions and IR data-flow nodes.
2019-10-23 11:56:30 +02:00
Jonas Jensen
cbbe9b4718 Merge remote-tracking branch 'upstream/master' into ir-copy-unloaded-result
Fixed conflicts by accepting new qltest output.

Conflicts:
      cpp/ql/test/library-tests/ir/ir/raw_ir.expected
      cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected
      cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected
      cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_sanity.expected
      cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_sanity.expected
2019-10-23 08:46:39 +02:00
Dave Bartolomeo
7241c1aae6 C++/C#: More sanity checks for IRType 2019-10-21 14:22:46 -07:00
Dave Bartolomeo
71a6b5dffe C++/C#: Fix some duplicate IRType problems, and add a sanity test 2019-10-21 10:46:30 -07:00
Robert Marsh
8905159de7 C++: add InitializeIndirection for pointer params 2019-10-18 11:06:09 -07:00
Robert Marsh
b29f88450b C++: buffer read side effects on unmodeled funcs 2019-10-17 12:10:23 -07:00
Robert Marsh
30d7238921 C++: fix missing getPrimaryInstruction 2019-10-16 17:05:37 -07:00
Robert Marsh
fffe3c2432 C++: add sanity test for side effect primaries 2019-10-16 16:53:55 -07:00
Dave Bartolomeo
167d2289c4 Merge from master 2019-10-16 10:10:10 -07:00
Robert Marsh
057c634fe4 C++: fix identical chi node operands 2019-10-04 13:05:47 -07:00
Robert Marsh
17e14348d5 C++: sanity test for identical Chi node operands 2019-10-04 12:57:30 -07:00
Robert Marsh
3377f88494 C++: generate Chi nodes on total IndirectMayWrites 2019-10-04 11:59:22 -07:00
Robert Marsh
5f8a3054d1 C++: add UninitializedInstructions for direct init 2019-10-04 11:34:14 -07:00
Robert Marsh
a76c4d9b3b C++: index for constructor qualifier side effects 2019-10-03 12:39:32 -07:00
Robert Marsh
47b9c497fa C++: IR SSA tests for explicit constructor calls 2019-10-03 12:25:41 -07:00
Robert Marsh
a45a6e48f8 C++: remove side effect operands from non-reads 2019-09-30 12:00:55 -07:00
Robert Marsh
8649978a43 C++: add indexes for specific side effects 2019-09-30 12:00:53 -07:00
Robert Marsh
24574be007 C++: add SizedBuffer side effect instructions 2019-09-30 12:00:53 -07:00
Robert Marsh
3d562243e4 C++: add side effects for outparams 2019-09-30 12:00:52 -07:00
Dave Bartolomeo
300e580874 C++: Implement language-neutral IR type system
The C++ IR currently has a very clunky way of specifying the type of an IR entity (`Instruction`, `Operand`, `IRVariable`, etc.). There are three separate predicates: `getType()`, `isGLValue()`, and `getSize()`. All three are necessary, rather than just having a `getType()` predicate, because some IR entities have types that are not represented via an existing `Type` object in the AST. Examples include the type for an lvalue returned from a `VariableAddress` instruction, the type for an array slice being zero-initialized in a variable initializer, and several others. It is very easy for QL code to just check the `getType()` predicate, while forgetting to use `isGLValue()` to determine if that type is the actual type of the entity (the prvalue case) or the type referred to by a glvalue entity. Furthermore, the C++ type system creates potentially many different `Type` objects for the same underlying type (e.g. typedefs, using declarations, `const`/`volatile` qualifiers, etc.), making it more difficult to tell when two entities have semantically equivalent types.

In addition, other languages for which we want to enable the IR have somewhat different type systems. The various language type systems differ in their structure, although they tend to share the basic building blocks necessary for the IR.

To address all of the above problems, I've introduced a new class hierarchy, rooted at the class `IRType`, that represents a bare-bones type system that is independent of source language (at least across C/C++/C#/Java). A type's identity is based on its kind (signed integer, unsigned integer, floating-point, Boolean, blob, etc.), size and in the case of blob types, a "tag" to differentiate between different classes and structs. No distinction is made between, say `signed int` and plain `int`, or between different language integer types that have the same signedness and size (e.g. `unsigned int` vs. `wchar_t` on Linux). `IRType` is intended for use by language-agnostic IR-based analyses, including range analysis, dataflow, SSA construction, and alias analysis. The set of available `IRType`s is determined by predicate provided by the language library implementation (e.g. `hasSignedIntegerType(int byteSize)`.

In addition to `IRType`, each language now defines a type alias named `LanguageType`, representing the type of an IR entity in more language-specific terms. The only predicate requried on `LanguageType` is `getIRType()`, which returns the single `IRType` object for the language-neutral representation of that `LanguageType`. All other predicates on and subclasses of `LanguageType` are language-specific. There may be many instances of `LanguageType` that map to a given `IRType`, to allow for typedefs, etc.

Most of the changes are mechanical changes in the IR construction code, to return the correct type for each IR entity. SSA construction has also been updated to avoid dependencies on language-specific types.

I have not yet removed the original `getType()` predicates that just return `Type`. These can be removed once we move the remaining existing libraries to use `IRType`.

Test results are, by design, pretty much unchanged. Once case changed for inline asm, because the previously IR generation for it played a little fast and loose with the input/output expressions. The test case now includes both input and output variables. The generated IR for `Conditional_LValue` is now more correct, because we now have a way to represent an lvalue of an lvalue. `syntax-zoo` is still a hot mess. Most of the changed outputs are due to wobble from having multiple functions with the same name, but with a slightly different order of evaluation due to the type changes. Others are wobble from already-invalid IR. A couple non-wobbly places have improved slightly, though.

The C# part of this change is waiting for #2005 to be merged, since that has some of the necessary C# implementation.
2019-09-23 16:14:00 -07:00
Jonas Jensen
cd5f3b84a8 C++: Make sure there's a Instruction for each Expr
This change ensures that all `Expr`s (except parentheses) have a
`TranslatedExpr` with a `getResult` that's one of its own instructions,
not an instruction from one of its operands. This means that when we
translate back and forth between `Expr` and `Instruction`, like in
`DataFlow::exprNode`, we will not conflate `e` with `&e` or `... = e`.
2019-09-23 15:23:31 +02:00
Dave Bartolomeo
6370391dbd C++: Add sanity test for definitions that don't dominate their uses. 2019-08-01 15:01:42 -07:00
Robert Marsh
c195420ba1 C++: respond to PR comments 2019-07-11 11:00:52 -07:00
Robert Marsh
41e4d920e3 C++: alias and side effect info for pure functions 2019-07-08 12:26:58 -07:00
Robert Marsh
ea7602b571 C++: add test for Alias and SideEffect models 2019-07-08 11:41:46 -07:00
Robert Marsh
5dd8c9cd4e C++: revert InlineAsm subclassing SideEffectOpcode 2019-05-31 13:28:26 -07:00
Robert Marsh
2770b2a9b9 C++: respond to PR comments 2019-05-31 13:19:40 -07:00
Robert Marsh
98d6f5919f C++: Treat asmStmt operands as input/output in IR 2019-05-31 12:51:44 -07:00
Robert Marsh
23560436a7 C++: add minimal AsmStmt support to IR 2019-05-31 12:29:19 -07:00
Dave Bartolomeo
fef58ec1ee C++: Add "~" prefix to inexact uses 2019-05-02 11:18:09 -07:00
Dave Bartolomeo
e0f7344676 C++: Imprecise definitions in SSA 2019-05-02 11:18:08 -07:00
Dave Bartolomeo
9726428bcc C++: More SSA test cases 2019-05-02 11:18:08 -07:00
Dave Bartolomeo
eed0894029 C++: Add operand labels for more operand tags
I kept forgetting which operand on a Chi instruction was which, so I added dump labels. I added labels for the function target of a `Call`, for positional arguments, and for address operands as well.
2019-05-02 11:18:08 -07:00
Dave Bartolomeo
a7f3160684 C++: New SSA tests 2019-05-02 11:18:08 -07:00
Dave Bartolomeo
b40fd95b8e C++: Better tracking of SSA memory accesses
This change fixes a few key problems with the existing SSA implementations:

For unaliased SSA, we were incorrectly choosing to model a local variable that had accesses that did not cover the entire variable. This has been changed to ensure that all accesses to the variable are at offset zero and have the same type as the variable itself. This was only possible to fix now that every `MemoryOperand` has its own type.

For aliased SSA, we now correctly track the offset and size of each memory access using an interval of bit offsets covered by the access. The offset interval makes the overlap computation more straightforward. Again, this is only possible now that operands have types.
The `getXXXMemoryAccess` predicates are now driven by the `MemoryAccessKind` on the operands and results, instead of by specific opcodes.

This change does fix an existing false negative in the IR dataflow tests.

I added a few simple test cases to the SSA IR tests, covering the various kinds of overlap (MustExcactly, MustTotally, and MayPartially).

I added "PrintSSA.qll", which can dump the SSA memory accesses as part of an IR dump.
2019-02-13 10:44:39 -08:00
Dave Bartolomeo
bd46c43067 C++: Add sanity test for missing operand type 2019-02-11 09:47:00 -08:00
Dave Bartolomeo
bda00bbff2 C++: Split out SSA IR tests
The IR tests were getting kind of unwieldy. We were using "ir.cpp" to contain test cases that covered both IR construction (every language construct imaginable) and SSA construction. We would then build and dump all three flavors of IR. For IR construction tests, examining the SSA dumps when you add a new test case is tedious.

To make this easier to manage, I've split the SSA-specific test cases out into a separate directory. "ir.cpp" should now contain only IR construction test cases, and "ssa.cpp" should contain only SSA construction test cases. We dump just the raw IR for "ir.cpp", and just the two SSA flavors for "ssa.cpp". We still run all three flavors of the IR sanity tests for "ir.cpp", though.

I also removed the "ssa_block_count.ql" test, which wasn't really adding any coverage, because any change to the block count would be reflected in the dump as well.
2019-02-08 15:28:06 -08:00