Commit Graph

359 Commits

Author SHA1 Message Date
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
2cd694756b C++: Remove mistakenly-added file 2019-10-21 15:58:38 -07: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
bc973973df C++: accept test changes 2019-10-03 14:43:54 -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
53f522c7f6 C++: respond to PR comments and autoformat 2019-10-02 10:11:58 -07:00
Robert Marsh
bace8c723d C++: side effect instrs for constructor qualifiers
This adds IndirectMustWriteSideEffects for constructor qualifiers. The
introduced sanity failures result from constructor calls without qualifier
operands in the IR
2019-10-01 14:53:37 -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
043e5f716b C++, C#: Autoformat 2019-09-29 22:39:09 -07:00
Matthew Gretton-Dann
c10ed5e114 C++: Update results for vector_size atrr changes 2019-09-27 11:28:31 +01: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
Matthew Gretton-Dann
9ff38ebeee C++: Update tests for new CTypedefType. 2019-09-23 13:57:50 +01:00
Jonas Jensen
4ef5c9af62 C++: Autoformat everything
Some files that will change in #1736 have been spared.

    ./build -j4 target/jars/qlformat
    find ql/cpp/ql -name "*.ql"  -print0 | xargs -0 target/jars/qlformat --input
    find ql/cpp/ql -name "*.qll" -print0 | xargs -0 target/jars/qlformat --input
    (cd ql && git checkout 'cpp/ql/src/semmle/code/cpp/ir/implementation/**/*SSA*.qll')
    buildutils-internal/scripts/pr-checks/sync-identical-files.py --latest
2019-09-09 11:25:53 +02:00
Dave Bartolomeo
a84a7e8c8a C++: Fixup after rebase 2019-08-22 11:36:15 -07:00
Dave Bartolomeo
3108d97ea5 C++: Minimal IR support for GNUVectorType
Lack of support for the GCC vector extensions was causing a bunch of sanity failures in the syntax zoo. This PR adds minimal IR generation support for these types.

Added `VectorAggregateLiteral`, and factored most of `ArrayAggregateLiteral` out into the common base class `ArrayOrVectorAggregateLiteral`. I'd be happy to merge these all into `ArrayAggregateLiteral` if we don't care about the distinction.

Made a few tweaks to `TranslatedArrayExpr` to compute the element type by looking at the result type of the `ArrayExpr`, not the type of the base operand. Note that this means that for `T a[10]; a[i] = foo;`, the result of the `PointerAdd` for `a[i]` will now be `glvalue<T>`, not `T*`. This is actually more faithful to the source language, and has no semantic difference on the IR.

Added some missing `getInstructionElementSize()` overrides.

Added the new `BuiltIn` opcode, renamed the existing `BuiltInInstruction` to `BuiltInOperationInstruction`, and made any `BuiltInOperation` that we don't specifically handle translate to `BuiltIn`. `BuiltInOperationInstruction` now has a way to get the specific `BuiltInOperation`.

Added `getCanonicalQLClass()` overrides for `GNUVectorType` and `BuiltInOperation`.

Added a simple IR test for vector types.
2019-08-22 10:43:30 -07:00
zlaski-semmle
ce71b45649 Zlaski/cpp386a (#1753)
* [CPP-386] Cumulative patch.

* Restore dataflow libraries clobbered by my last commit.
2019-08-19 10:03:18 +02:00
Jonas Jensen
d378da33e8 C++ IR: Fix performance of large array value init
There were two problems here.

1. The inline predicates `isInitialized` and `isValueInitialized` on
   `ArrayAggregateLiteral` caused their callers to materialize every
   `int` that was a valid index into the array. This was slow on huge
   value-initialized arrays.
2. The `isInitialized` predicate was used in the `TInstructionTag` IPA
   type, creating a numbered tuple for each integer in it. This seemed
   to be entirely unnecessary since the `TranslatedElement`s using those
   tags were already indexed appropriately.
2019-08-06 14:50:57 +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
Dave Bartolomeo
912679ef8c C++: Two IR fixes
My original fix in https://github.com/Semmle/ql/pull/1661 fixed my minimal test case, but did not fix the original failure in a Linux snapshot. The real fix is to simply not create a `TranslatedDeclarationEntry` for an extern declaration, and have `TranslatedDeclStmt` skip any such declarations. I've added a regression test for that case (multiple extern declarations with same location in a macro expansion, with control flow between them). I did verify that it generates correct IR, and that it fixes all of the "use not dominated by definition" failures in Linux.

The underlying extractor bug, that caused the above issue also caused PrintAST to print garbage. I've worked around the bug in PrintAST.qll.

I've also fixed a bug in the control flow for `try`/`catch`, where there was missing flow from the `CatchByType` of the last handler of a `try` to the enclosing handler (or `Unwind`). Hat tip to @AndreiDiaconu1 for spotting this bug.
2019-08-01 14:38:19 -07:00
Dave Bartolomeo
972f0d97d3 C++: Stop generating NoOp instructions for declarations of externs
Previously, where we had a function-scoped `DeclarationEntry` for an extern variable or function, we would generate a `NoOp` instruction for it. There's nothing wrong with this by itself, although it was unnecessary. However, I've hit an extractor issue (Jira ticket already opened) that commonly causes multiple `DeclStmt`s to share a single `DeclarationEntry` child on extern declarations, so removing the `NoOp` instructions is an easy way to work around the extractor issue.
2019-07-30 16:49:24 -07:00
Ziemowit Laski
a0570213d7 [CPP-386] Separate printing of casts and conversion, per Dave's request. 2019-07-19 16:56:22 -07:00
Ziemowit Laski
45d944411f [CPP-386] Fix Local{Class,Struct,Union}, macro invocations,
printing of member functions and operators.
2019-07-18 16:09:04 -07:00
Ziemowit Laski
926742561b [CPP-340] Eliminate superfluous print-outs of NestedStruct,
`NestedUnion` and `MemberFunction`
2019-07-17 13:39:43 -07:00
Ziemowit Laski
f0982791e3 [CPP-340] Remove colons and extraenous QLDoc comments; add a few more classes. 2019-07-16 17:58:39 -07:00
Ziemowit Laski
c906560edd Fix up expected IR output after rebase. 2019-07-13 12:57:25 -07:00
Ziemowit Laski
960a41be85 Handle __builtin_addressof. 2019-07-13 12:23:40 -07:00