Commit Graph

128 Commits

Author SHA1 Message Date
Robert Marsh
8905159de7 C++: add InitializeIndirection for pointer params 2019-10-18 11:06:09 -07:00
Robert Marsh
e57fef093b C++: accept syntax-zoo changes 2019-10-18 10:08:53 -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
6e61b1dcd0 C++: Fix up after merge from master
The one interesting piece that needed to be fixed up was the type of an `Indirect[Read|Write]SideEffect` operand/result. If the parameter type is a pointer or reference to an incomplete type, we need to set the type of the side effect memory access to `Unknown`, because we don't model incomplete types in the IR type system.

I also added minimal support for `__assume` (generated as a `NoOp`), because lack of `__assume` support got in the way of debugging the other issue above.
2019-10-16 15:55:56 -07:00
Dave Bartolomeo
167d2289c4 Merge from master 2019-10-16 10:10:10 -07:00
Robert Marsh
b60e7c204d C++: autoformat and accept test output 2019-10-07 14:07:25 -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
Dave Bartolomeo
9b8b364c8f Merge from master 2019-09-26 22:15:02 -07:00
Jonas Jensen
0aafa0b0e2 C++: Accept test changes in IR sanity queries
These looks harmless.
2019-09-25 08:55:55 +02:00
Jonas Jensen
b75bf06649 C++: Accept test changes in other IR tests 2019-09-24 13:00:21 +02: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
307b92feed C++: Unknown template literals are constant 2019-09-19 10:23:26 +02:00
Jonas Jensen
e0d1da3b67 C++: Test for template enum constant CFG 2019-09-18 15:17:24 +02:00
Jonas Jensen
7d8396fa65 C++: Constant template pointer-to-member literals 2019-09-18 14:44:25 +02:00
Jonas Jensen
d644150ead C++: Test for template pointer-to-member CFG 2019-09-18 14:30:18 +02:00
Jonas Jensen
0f2731064d C++: Annotate tellDifferent with template status
This is helpful for turning real-world cases into test cases.
2019-09-18 14:23:52 +02:00
Jonas Jensen
c90fd32a78 C++: Pointer-to-member-function is constant 2019-09-18 13:55:56 +02:00
Jonas Jensen
55edfe4224 C++: Test for pointer-to-member-function CFG 2019-09-18 13:37:52 +02:00
Jonas Jensen
ee16b239de C++: Add PointerToFieldLiteral class
Marking these expressions as constants fixes the CFG discrepancies that
can be observed on the affected test and on snapshots of MySQL.
2019-09-11 13:40:24 +02:00
Jonas Jensen
bd59029e2b C++: Add pointer-to-member test to syntax-zoo
This test was inspired by problems observed in a MySQL snapshot. The
results show there are problems with both the QL CFG and the IR.
2019-09-10 16:23:23 +02: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
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
Jonas Jensen
f160447c20 C++: Update test results to latest master 2019-08-06 14:42:47 +02:00
Jonas Jensen
d0d6b2b70c C++: Add IR sanity queries to syntax-zoo test dir 2019-08-06 14:10:25 +02:00
Jonas Jensen
d18181f032 C++: Rename qlcfg -> syntax-zoo 2019-08-06 14:10:25 +02:00