Compare commits

..

90 Commits

Author SHA1 Message Date
Owen Mansel-Chan
e660b852c0 Update max supported Go version to 1.23 2024-09-01 21:07:16 +01:00
Owen Mansel-Chan
da12b33b86 Add change note 2024-09-01 21:07:15 +01:00
Owen Mansel-Chan
fe6d3648ae Update labels for alias types
Use object like we do for named types.
2024-09-01 21:07:14 +01:00
Owen Mansel-Chan
649bf5ac3b Improve Aliases test
Restricting to alias types in the source code stops the results from
changing when the standard library changes.

Using `pp()` instead of `getName` lets us see the results where the
underlying type doesn't have a name.
2024-09-01 21:07:13 +01:00
Owen Mansel-Chan
bd89eb075f Improve AliasType.getUnderlyingType
Read through as many aliases as possible before getting
the underlying type.
2024-09-01 21:07:13 +01:00
Owen Mansel-Chan
23d1dfa17d Delete more about alias types in downgrade script 2024-09-01 21:07:12 +01:00
Owen Mansel-Chan
f2695d008f Fix syntax error in test 2024-09-01 21:07:11 +01:00
Owen Mansel-Chan
9ca75369fc Update underlying type of alias
This changed from uint in 1.22 to uint8 in 1.23.
2024-09-01 21:07:11 +01:00
Owen Mansel-Chan
a6557fc4e5 Accept test change related to alias types 2024-09-01 21:07:10 +01:00
Owen Mansel-Chan
7589186583 Use unique type param names in test
This makes it clearer when changes in test results
are due to changes in the standard library.
2024-09-01 21:07:09 +01:00
Owen Mansel-Chan
3a8a7ea67d Fix alias use in HTML template escaping passthrough 2024-09-01 21:07:08 +01:00
Owen Mansel-Chan
f6e577e791 Factor out extractTypeObject 2024-09-01 21:07:07 +01:00
Paolo Tranquilli
77cf0ac7a7 Go: add patch for go 1.23 windows build problem 2024-09-01 21:07:07 +01:00
Michael B. Gale
76e27ff74a Go: Remove alias_rhs table in downgrade script 2024-09-01 21:07:06 +01:00
Michael B. Gale
191f712ab3 Go: Update test for aliases to print immediate RHS and underlying type 2024-09-01 21:07:05 +01:00
Michael B. Gale
5797dbab91 Go: Extract objects for aliases 2024-09-01 21:07:04 +01:00
Michael B. Gale
90068f6f7b Go: Update AliasType to implement getUnderlyingType 2024-09-01 21:07:04 +01:00
Michael B. Gale
47ad284171 Go: Fix formatting and documentation of AliasType 2024-09-01 21:07:03 +01:00
Michael B. Gale
221bab7136 Go: Add test for AliasType extraction 2024-09-01 21:07:02 +01:00
Michael B. Gale
91946de849 Go: Extract alias names 2024-09-01 21:07:01 +01:00
Michael B. Gale
cd7cf4f6b4 Go: Add database upgrade/downgrades for type aliases 2024-09-01 21:07:00 +01:00
Michael B. Gale
bbe24060f9 Go: Extract type aliases 2024-09-01 21:07:00 +01:00
Michael B. Gale
f4b3dfc408 Go: Update dbscheme for aliases 2024-09-01 21:06:59 +01:00
Michael B. Gale
119256452f Go: Update frontend error messages for Go 1.23 2024-09-01 21:06:58 +01:00
Michael B. Gale
6b1bd05e5c Go: Use 1.23 for extractor 2024-09-01 21:06:57 +01:00
Michael B. Gale
299b2e4de8 Go: Use 1.23 in tests 2024-09-01 21:06:56 +01:00
Michael B. Gale
e604749561 Go: Use 1.23 in build process 2024-09-01 21:06:55 +01:00
Tom Hvitved
642ec38589 Merge pull request #17340 from hvitved/csharp/ssa-exclude-enums 2024-08-30 16:31:38 +02:00
Tom Hvitved
4ef4ede0b1 C#: Do not calculate field-based SSA for enums 2024-08-30 11:19:07 +02:00
Tom Hvitved
a9b5faa6ab C#: Add SSA test for enums 2024-08-30 11:19:06 +02:00
Michael Nebel
89c387cf5c Merge pull request #17326 from michaelnebel/shared/contentflowtaint
DataFlow: Bugfix in content flow state for value preservation.
2024-08-30 09:23:50 +02:00
Cornelius Riemenschneider
72e2910d17 Merge pull request #17315 from github/criemen/pytest-java
Java: Port all integration tests to pytest
2024-08-29 18:05:52 +02:00
Cornelius Riemenschneider
5ecc6f9dc8 Merge remote-tracking branch 'origin/main' into criemen/pytest-java 2024-08-29 16:43:46 +02:00
Cornelius Riemenschneider
dd7f757281 Address review. 2024-08-29 16:43:27 +02:00
Michael Nebel
ff31aa540c Address review comments. 2024-08-29 15:54:04 +02:00
Michael Nebel
0df0d8a51f Merge pull request #17236 from michaelnebel/java/viablecallableheuristic
Java: Make more finegrained dataflow dispatch viable callable heuristic.
2024-08-29 10:46:30 +02:00
Michael Nebel
53b2471c9d Java: Update expected test output. 2024-08-29 09:03:46 +02:00
Cornelius Riemenschneider
047a655dec Merge pull request #17324 from github/criemen/move-swift-int-tests
Swift: Move all integration tests.
2024-08-28 21:27:26 +02:00
Simon Friis Vindum
edeefe5bb6 Merge pull request #17298 from paldepind/model-functions-that-dont-throw
C++: Add basic modeling of functions that don't throw
2024-08-28 19:50:31 +02:00
Michael Nebel
fa5d6f12be Java: Update logging test expected output. 2024-08-28 16:16:16 +02:00
Michael Nebel
bd5529cefa Java: Update the Byte- and CharBuffer models and add models for set- and getParameters on LogRecord. 2024-08-28 16:15:09 +02:00
Michael Nebel
395656a1cf Java: Extend the logging test with a test case for parameters. 2024-08-28 16:13:32 +02:00
Cornelius Riemenschneider
123c375d84 Merge pull request #17322 from github/criemen/move-js-int-tests
JS: Move all integration tests.
2024-08-28 16:04:39 +02:00
Jeroen Ketema
40fe39c288 Merge pull request #17311 from jketema/builtins
C++: Add support for more clang builtins
2024-08-28 16:00:08 +02:00
Simon Friis Vindum
d1fecd869b C++: Make StringCchPrintf not extend NonThrowingFunction 2024-08-28 15:40:14 +02:00
Cornelius Riemenschneider
966c3a62dd Merge pull request #17309 from github/criemen/bazel-prerelease
Bazel: switch to a 7.4.0 prerelease.
2024-08-28 15:28:06 +02:00
Jeroen Ketema
2b571cf450 C++: Address review comments 2024-08-28 15:11:42 +02:00
Michael Nebel
e8595e28e9 Update java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2024-08-28 15:04:38 +02:00
Anders Schack-Mulligen
dd49fc932d Merge pull request #17325 from aschackmull/dataflow/state-in-summary
Dataflow: Include FlowState in SummaryCtx.
2024-08-28 15:03:18 +02:00
Cornelius Riemenschneider
ab56e63f96 Merge branch 'main' into criemen/pytest-java 2024-08-28 14:47:49 +02:00
Michael Nebel
6d346dbedd DataFlow: Bugfix in flow state for value preservation. 2024-08-28 14:40:04 +02:00
Anders Schack-Mulligen
6a9bd0de1d Dataflow: Include FlowState in SummaryCtx. 2024-08-28 14:13:28 +02:00
Jeroen Ketema
026969b6e9 C++: Add change note 2024-08-28 13:08:44 +02:00
Jeroen Ketema
9e861ce717 C++: Add support for more clang builtins 2024-08-28 13:08:42 +02:00
Tom Hvitved
7f8e6bf574 Merge pull request #16970 from hvitved/dataflow/local-big-step-stage
Data flow: Compute local big step relation as stage output
2024-08-28 12:28:16 +02:00
Tom Hvitved
27bc8ed6af Address review comment 2024-08-28 11:38:29 +02:00
Chris Smowton
464b552cad Merge pull request #17321 from github/criemen/move-go-int-tests
Go: Move all integration tests.
2024-08-28 10:30:55 +01:00
Cornelius Riemenschneider
d349ddba57 Merge pull request #17323 from github/criemen/move-ruby-int-tests
Ruby: Move all integration tests.
2024-08-28 11:18:05 +02:00
Simon Friis Vindum
d6049cd98b C++: Add additional implementations of NonThrowingFunction and make minor fixes to docs 2024-08-28 10:54:16 +02:00
Cornelius Riemenschneider
a92a845719 Swift: Move all integration tests.
We are no longer bound to the platform-specific directories,
so simplify the test organization.
If you don't want this change, just skip merging this PR. It's purely optional.
2024-08-28 10:47:17 +02:00
Cornelius Riemenschneider
3326bc417c Ruby: Move all integration tests.
We no longer need the platform-specific directories, so simplify the test organization.
If you don't want this change, just skip merging this PR. It's purely optional.
2024-08-28 10:45:05 +02:00
Cornelius Riemenschneider
b7b475d13b JS: Move all integration tests.
We no longer need the platform-specific directories, so simplify the test organization.
If you don't want this change, just skip merging this PR.
It's purely optional.

The PR also deletes a spurious qlpack.yml that I missed when converting the tests to pytest.
2024-08-28 10:43:08 +02:00
Cornelius Riemenschneider
bfc6fee828 Go: Move all integration tests.
We no longer need the platform-specific directories,
so simplify the test organization.
If you want to retain the `linux` directory for two tests,
or not do this at all, just skip merging this PR.
It's purely optional.
2024-08-28 10:37:59 +02:00
Tom Hvitved
22e1921391 Merge pull request #17313 from hvitved/dataflow/to-normal-sink-node-ex
Data flow: Move `toNormalSinkNodeEx` into `PathNodeMid`
2024-08-28 09:06:41 +02:00
Tom Hvitved
b589fcad11 Data flow: Tweak join-order in toNormalSinkNodeEx 2024-08-27 15:42:24 +02:00
Tom Hvitved
80b6135a64 Data flow: Move toNormalSinkNodeEx into PathNodeMid 2024-08-27 15:42:13 +02:00
Michael Nebel
15b06907dd Java: Updated expected test output. 2024-08-27 14:48:14 +02:00
Michael Nebel
8f734ad1b2 Java: Tighten the criteria for when we disregard generated models. 2024-08-27 14:48:11 +02:00
Michael Nebel
021fd1450e Java: Add some dispatch examples to the external flow step test. 2024-08-27 14:48:03 +02:00
Michael Nebel
43b52a0921 Java: Add change note. 2024-08-27 13:28:18 +02:00
Michael Nebel
7488cc0811 Java: Updated expected test output. 2024-08-27 13:28:13 +02:00
Michael Nebel
d79aa294ec Java: Move some neutrals into the model.yml file (they have previosly been ignored due to wrong file extension). 2024-08-27 13:28:09 +02:00
Michael Nebel
db51604f46 Java: Promote some generated models and add some manual neutrals. 2024-08-27 13:28:05 +02:00
Michael Nebel
6cb5e13a23 Java: Re-factor tests and update expected test output. 2024-08-27 13:28:00 +02:00
Michael Nebel
68880b2056 Java: Update expected test output. Generated models are no longer applied as there exist a source implementation. 2024-08-27 13:27:55 +02:00
Michael Nebel
fe6693739a Java: Make more finegrained dataflow dispatch viable callable heuristic. 2024-08-27 13:27:52 +02:00
Cornelius Riemenschneider
1c3b9f7031 Delete legacy test utils. 2024-08-27 13:14:24 +02:00
Cornelius Riemenschneider
c69df1a6e3 Port java integration tests to pytest.
Some notes:
* These tests rely on a variety of fixtures
* The previous maven-wrapper checks were checking for the version of maven installed by looking at the checked-in wrapper script. I dropped this behavior.
* I replaced a lot of test queries that queried for a (subset of) source archive files with the source_archive fixture. In particular, tests that excluded properties files from being listed in the expected output now include them.
   It's much faster to generate this list via the fixture instead of using CodeQL for it.
2024-08-27 13:14:23 +02:00
Cornelius Riemenschneider
5fa30c33b8 Remove legacy java files. 2024-08-27 13:14:21 +02:00
Cornelius Riemenschneider
19606b1903 Add *.actual to the gitignore file.
This is also used by the integration tests.
2024-08-27 13:14:20 +02:00
Ian Lynagh
3a864d3de2 Merge pull request #17292 from igfoo/igfoo/open
Kotlin: Remove a redundant 'open'
2024-08-27 12:14:04 +01:00
Ian Lynagh
085bf2f662 Merge pull request #17293 from igfoo/igfoo/dtw
Kotlin: Restrict some TrapWriter types to DiagnosticTrapWriter
2024-08-27 12:13:59 +01:00
Cornelius Riemenschneider
123507e2dc No need to disable the layering check anymore, this was fixed upstream. 2024-08-27 13:00:56 +02:00
Cornelius Riemenschneider
62219fae60 Bazel: switch to a 7.4.0 prerelease. 2024-08-27 12:27:53 +02:00
Simon Friis Vindum
d9dbcdba34 C++: Fix imports 2024-08-26 12:42:44 +02:00
Tom Hvitved
e5d626f907 Data flow: Only recompute local big step in stage 6 2024-08-26 09:58:29 +02:00
Simon Friis Vindum
128053e214 C++: Add basic modeling of functions that don't throw 2024-08-26 09:37:44 +02:00
Tom Hvitved
c92c96fa78 Data flow: Compute local big step relation per stage 2024-08-26 09:15:27 +02:00
Ian Lynagh
6a7d8b5301 Kotlin: Restrict some TrapWriter types to DiagnosticTrapWriter
We never use the greater generality, so this makes it easier to see
what's happening.
2024-08-23 15:41:21 +01:00
Ian Lynagh
7d500cf58c Kotlin: Remove a redundant 'open' 2024-08-23 15:08:10 +01:00
877 changed files with 29899 additions and 7605 deletions

View File

@@ -1 +1 @@
7.2.1
5f5d70b6c4d2fb1a889479569107f1692239e8a7

View File

@@ -37,7 +37,7 @@ jobs:
with:
languages: cpp
config-file: ./.github/codeql/codeql-config.yml
- name: "[Ubuntu] Remove GCC 13 from runner image"
shell: bash
run: |
@@ -48,7 +48,7 @@ jobs:
- name: "Build Swift extractor using Bazel"
run: |
bazel clean --expunge
bazel run //swift:create-extractor-pack --nouse_action_cache --noremote_accept_cached --noremote_upload_local_results --spawn_strategy=local --features=-layering_check
bazel run //swift:create-extractor-pack --nouse_action_cache --noremote_accept_cached --noremote_upload_local_results --spawn_strategy=local
bazel shutdown
- name: Perform CodeQL Analysis

2
.gitignore vendored
View File

@@ -7,8 +7,8 @@
.cache
# qltest projects and artifacts
*.actual
*/ql/test/**/*.testproj
*/ql/test/**/*.actual
*/ql/test/**/go.sum
# Visual studio temporaries, except a file used by QL4VS

View File

@@ -15,7 +15,7 @@ local_path_override(
# see https://registry.bazel.build/ for a list of available packages
bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "rules_go", version = "0.49.0")
bazel_dep(name = "rules_go", version = "0.49.0-codeql.1")
bazel_dep(name = "rules_pkg", version = "0.10.1")
bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1")
bazel_dep(name = "rules_python", version = "0.32.2")
@@ -153,7 +153,7 @@ use_repo(
)
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
go_sdk.download(version = "1.22.2")
go_sdk.download(version = "1.23.0")
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//go/extractor:go.mod")

View File

@@ -0,0 +1,17 @@
class Expr extends @expr {
string toString() { none() }
}
class Location extends @location_expr {
string toString() { none() }
}
predicate isExprWithNewBuiltin(Expr expr) {
exists(int kind | exprs(expr, kind, _) | 385 <= kind and kind <= 388)
}
from Expr expr, int kind, int kind_new, Location location
where
exprs(expr, kind, location) and
if isExprWithNewBuiltin(expr) then kind_new = 1 else kind_new = kind
select expr, kind_new, location

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
class Expr extends @expr {
string toString() { none() }
}
class Type extends @type {
string toString() { none() }
}
from Expr expr, Type type, int kind
where
sizeof_bind(expr, type) and
exprs(expr, kind, _) and
(kind = 93 or kind = 94)
select expr, type

View File

@@ -0,0 +1,4 @@
description: Add new builtin operations
compatibility: partial
exprs.rel: run exprs.qlo
sizeof_bind.rel: run sizeof_bind.qlo

View File

@@ -0,0 +1,5 @@
---
category: feature
---
* Added subclasses of `BuiltInOperations` for the `__is_scoped_enum`, `__is_trivially_equality_comparable`, and `__is_trivially_relocatable` builtin operations.
* Added a subclass of `Expr` for `__datasizeof` expressions.

View File

@@ -1885,3 +1885,59 @@ class BuiltInOperationIsWinInterface extends BuiltInOperation, @iswininterface {
override string getAPrimaryQlClass() { result = "BuiltInOperationIsWinInterface" }
}
/**
* A C++ `__is_trivially_equality_comparable` built-in operation.
*
* Returns `true` if comparing two objects of type `_Tp` is equivalent to
* comparing their object representations.
*
* ```
* template<typename _Tp>
* struct is_trivially_equality_comparable
* : public integral_constant<bool, __is_trivially_equality_comparable(_Tp)>
* {};
* ```
*/
class BuiltInOperationIsTriviallyEqualityComparable extends BuiltInOperation,
@istriviallyequalitycomparable
{
override string toString() { result = "__is_trivially_equality_comparable" }
override string getAPrimaryQlClass() { result = "BuiltInOperationIsTriviallyEqualityComparable" }
}
/**
* A C++ `__is_scoped_enum` built-in operation (used by some implementations
* of the `<type_traits>` header).
*
* Returns `true` if a type is a scoped enum.
* ```
* template<typename _Tp>
* constexpr bool is_scoped_enum = __is_scoped_enum(_Tp);
* ```
*/
class BuiltInOperationIsScopedEnum extends BuiltInOperation, @isscopedenum {
override string toString() { result = "__is_scoped_enum" }
override string getAPrimaryQlClass() { result = "BuiltInOperationIsScopedEnum" }
}
/**
* A C++ `__is_trivially_relocatable` built-in operation.
*
* Returns `true` if moving an object of type `_Tp` is equivalent to
* copying the underlying bytes.
*
* ```
* template<typename _Tp>
* struct is_trivially_relocatable
* : public integral_constant<bool, __is_trivially_relocatable(_Tp)>
* {};
* ```
*/
class BuiltInOperationIsTriviallyRelocatable extends BuiltInOperation, @istriviallyrelocatable {
override string toString() { result = "__is_trivially_relocatable" }
override string getAPrimaryQlClass() { result = "BuiltInOperationIsTriviallyRelocatable" }
}

View File

@@ -791,6 +791,53 @@ class AlignofTypeOperator extends AlignofOperator {
override string toString() { result = "alignof(" + this.getTypeOperand().getName() + ")" }
}
/**
* A C++ `__datasizeof` expression (used by some implementations
* of the `<type_traits>` header).
*
* The `__datasizeof` expression behaves identically to `sizeof` except
* that the result ignores tail padding.
*/
class DatasizeofOperator extends Expr, @datasizeof {
override int getPrecedence() { result = 16 }
}
/**
* A C++ `__datasizeof` expression whose operand is an expression.
*/
class DatasizeofExprOperator extends DatasizeofOperator {
DatasizeofExprOperator() { exists(this.getChild(0)) }
override string getAPrimaryQlClass() { result = "DatasizeofExprOperator" }
/** Gets the contained expression. */
Expr getExprOperand() { result = this.getChild(0) }
override string toString() { result = "__datasizeof(<expr>)" }
override predicate mayBeImpure() { this.getExprOperand().mayBeImpure() }
override predicate mayBeGloballyImpure() { this.getExprOperand().mayBeGloballyImpure() }
}
/**
* A C++ `__datasizeof` expression whose operand is a type name.
*/
class DatasizeofTypeOperator extends DatasizeofOperator {
DatasizeofTypeOperator() { sizeof_bind(underlyingElement(this), _) }
override string getAPrimaryQlClass() { result = "DatasizeofTypeOperator" }
/** Gets the contained type. */
Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) }
override string toString() { result = "__datasizeof(" + this.getTypeOperand().getName() + ")" }
override predicate mayBeImpure() { none() }
override predicate mayBeGloballyImpure() { none() }
}
/**
* A C/C++ array to pointer conversion.
*

View File

@@ -304,6 +304,8 @@ class Expr extends StmtParent, @expr {
e instanceof NoExceptExpr
or
e instanceof AlignofOperator
or
e instanceof DatasizeofOperator
)
or
exists(Decltype d | d.getExpr() = this.getParentWithConversions*())

View File

@@ -42,6 +42,7 @@ private import implementations.Accept
private import implementations.Poll
private import implementations.Select
private import implementations.MySql
private import implementations.NoexceptFunction
private import implementations.ODBC
private import implementations.SqLite3
private import implementations.PostgreSql

View File

@@ -9,13 +9,14 @@ import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.NonThrowing
/**
* The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant
* `__builtin___memcpy_chk`.
*/
private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction,
AliasFunction
AliasFunction, NonThrowingFunction
{
MemcpyFunction() {
// memcpy(dest, src, num)

View File

@@ -8,9 +8,10 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.NonThrowing
private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction,
SideEffectFunction
SideEffectFunction, NonThrowingFunction
{
MemsetFunctionModel() {
this.hasGlobalOrStdOrBslName("memset")

View File

@@ -0,0 +1,11 @@
import semmle.code.cpp.models.interfaces.NonThrowing
/**
* A function that is annotated with a `noexcept` specifier (or the equivalent
* `throw()` specifier) guaranteeing that the function can not throw exceptions.
*
* Note: The `throw` specifier was deprecated in C++11 and removed in C++17.
*/
class NoexceptFunction extends NonThrowingFunction {
NoexceptFunction() { this.isNoExcept() or this.isNoThrow() }
}

View File

@@ -8,11 +8,12 @@
import semmle.code.cpp.models.interfaces.FormattingFunction
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.NonThrowing
/**
* The standard functions `printf`, `wprintf` and their glib variants.
*/
private class Printf extends FormattingFunction, AliasFunction {
private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunction {
Printf() {
this instanceof TopLevelFunction and
(
@@ -36,7 +37,7 @@ private class Printf extends FormattingFunction, AliasFunction {
/**
* The standard functions `fprintf`, `fwprintf` and their glib variants.
*/
private class Fprintf extends FormattingFunction {
private class Fprintf extends FormattingFunction, NonThrowingFunction {
Fprintf() {
this instanceof TopLevelFunction and
(
@@ -54,7 +55,7 @@ private class Fprintf extends FormattingFunction {
/**
* The standard function `sprintf` and its Microsoft and glib variants.
*/
private class Sprintf extends FormattingFunction {
private class Sprintf extends FormattingFunction, NonThrowingFunction {
Sprintf() {
this instanceof TopLevelFunction and
(
@@ -97,7 +98,7 @@ private class Sprintf extends FormattingFunction {
/**
* Implements `Snprintf`.
*/
private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction {
private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, NonThrowingFunction {
SnprintfImpl() {
this instanceof TopLevelFunction and
(
@@ -204,7 +205,7 @@ private class StringCchPrintf extends FormattingFunction {
/**
* The standard function `syslog`.
*/
private class Syslog extends FormattingFunction {
private class Syslog extends FormattingFunction, NonThrowingFunction {
Syslog() {
this instanceof TopLevelFunction and
this.hasGlobalName("syslog") and

View File

@@ -7,13 +7,16 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.NonThrowing
/**
* The standard function `strcat` and its wide, sized, and Microsoft variants.
*
* Does not include `strlcat`, which is covered by `StrlcatFunction`
*/
class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction {
class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction,
NonThrowingFunction
{
StrcatFunction() {
this.hasGlobalOrStdOrBslName([
"strcat", // strcat(dst, src)

View File

@@ -7,11 +7,14 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.NonThrowing
/**
* The standard function `strcpy` and its wide, sized, and Microsoft variants.
*/
class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction {
class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction,
NonThrowingFunction
{
StrcpyFunction() {
this.hasGlobalOrStdOrBslName([
"strcpy", // strcpy(dst, src)

View File

@@ -0,0 +1,11 @@
/**
* Provides an abstract class for modeling functions that never throw.
*/
import semmle.code.cpp.Function
import semmle.code.cpp.models.Models
/**
* A function that is guaranteed to never throw.
*/
abstract class NonThrowingFunction extends Function { }

View File

@@ -1788,6 +1788,10 @@ case @expr.kind of
| 382 = @isvalidwinrttype
| 383 = @iswinclass
| 384 = @iswininterface
| 385 = @istriviallyequalitycomparable
| 386 = @isscopedenum
| 387 = @istriviallyrelocatable
| 388 = @datasizeof
;
@var_args_expr = @vastartexpr
@@ -1901,6 +1905,9 @@ case @expr.kind of
| @isvalidwinrttype
| @iswinclass
| @iswininterface
| @istriviallyequalitycomparable
| @isscopedenum
| @istriviallyrelocatable
;
new_allocated_type(
@@ -1961,7 +1968,7 @@ uuidof_bind(
int type_id: @type ref
);
@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof;
@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof;
sizeof_bind(
unique int expr: @runtime_sizeof_or_alignof ref,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Add new builtin operations
compatibility: backwards

View File

@@ -16,6 +16,7 @@
import cpp
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import semmle.code.cpp.controlflow.Guards
import semmle.code.cpp.models.implementations.NoexceptFunction
/** Gets the `Constructor` invoked when `newExpr` allocates memory. */
Constructor getConstructorForAllocation(NewOrNewArrayExpr newExpr) {
@@ -44,9 +45,8 @@ predicate deleteMayThrow(DeleteOrDeleteArrayExpr deleteExpr) {
* like it might throw an exception, and the function does not have a `noexcept` or `throw()` specifier.
*/
predicate functionMayThrow(Function f) {
(not exists(f.getBlock()) or stmtMayThrow(f.getBlock())) and
not f.isNoExcept() and
not f.isNoThrow()
not f instanceof NonThrowingFunction and
(not exists(f.getBlock()) or stmtMayThrow(f.getBlock()))
}
/** Holds if the evaluation of `stmt` may throw an exception. */
@@ -172,8 +172,7 @@ class ThrowingAllocator extends Function {
not exists(Parameter p | p = this.getAParameter() |
p.getUnspecifiedType().stripType() instanceof NoThrowType
) and
not this.isNoExcept() and
not this.isNoThrow()
not this instanceof NoexceptFunction
)
}
}

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Add modeling of C functions that don't throw, thereby increasing the precision of the `cpp/incorrect-allocation-error-handling` ("Incorrect allocation-error handling") query. The query now produces additional true positives.

View File

@@ -1,4 +1,4 @@
// semmle-extractor-options: --clang --clang_version 180000
// semmle-extractor-options: --clang --edg --clang_version --edg 190000
struct S {
void f() {}
@@ -108,3 +108,16 @@ bool b_is_unbounded_array2 = __is_unbounded_array(int[42]);
bool b_is_referenceable1 = __is_referenceable(int);
bool b_is_referenceable2 = __is_referenceable(void);
bool b_is_trivially_equality_comparable1 = __is_trivially_equality_comparable(int);
bool b_is_trivially_equality_comparable2 = __is_trivially_equality_comparable(void);
enum class E {
a, b
};
bool b_is_scoped_enum1 = __is_scoped_enum(E);
bool b_is_scoped_enum2 = __is_scoped_enum(int);
bool b_is_trivially_relocatable1 = __is_trivially_relocatable(int);
bool b_is_trivially_relocatable2 = __is_trivially_relocatable(void);

View File

@@ -153,7 +153,21 @@
| clang.cpp:109:28:109:50 | int | | <none> |
| clang.cpp:110:28:110:51 | __is_referenceable | void | 0 |
| clang.cpp:110:28:110:51 | void | | <none> |
| clang.cpp:112:44:112:82 | __is_trivially_equality_comparable | int | 1 |
| clang.cpp:112:44:112:82 | int | | <none> |
| clang.cpp:113:44:113:83 | __is_trivially_equality_comparable | void | 0 |
| clang.cpp:113:44:113:83 | void | | <none> |
| clang.cpp:119:26:119:44 | E | | <none> |
| clang.cpp:119:26:119:44 | __is_scoped_enum | E | 1 |
| clang.cpp:120:26:120:46 | __is_scoped_enum | int | 0 |
| clang.cpp:120:26:120:46 | int | | <none> |
| clang.cpp:122:36:122:66 | __is_trivially_relocatable | int | 1 |
| clang.cpp:122:36:122:66 | int | | <none> |
| clang.cpp:123:36:123:67 | __is_trivially_relocatable | void | 0 |
| clang.cpp:123:36:123:67 | void | | <none> |
| file://:0:0:0:0 | 0 | | 0 |
| file://:0:0:0:0 | 0 | | 0 |
| file://:0:0:0:0 | 1 | | 1 |
| file://:0:0:0:0 | 1 | | 1 |
| file://:0:0:0:0 | 2 | | 2 |
| gcc.cpp:3:25:3:25 | 8 | | 8 |

View File

@@ -450,7 +450,7 @@ void test_qualifiers()
b.member = source();
sink(b); // $ ir MISSING: ast
sink(b.member); // $ ast,ir
sink(b.getMember()); // $ ir MISSING: ast
sink(b.getMember()); // $ MISSING: ir ast
c = new MyClass2(0);

View File

@@ -115,8 +115,8 @@ void test_vector_swap() {
v3.swap(v4);
sink(v1);
sink(v2); // $ ir MISSING:ast
sink(v3); // $ ir MISSING:ast
sink(v2); // $ MISSING:ir ast
sink(v3); // $ MISSING:ir ast
sink(v4);
}

View File

@@ -0,0 +1,30 @@
// semmle-extractor-options: --clang --edg --clang_version --edg 190000
typedef unsigned int size_t;
class MyClass
{
public:
int x;
int *ptr;
char c;
};
void func() {
int i;
char c;
int * ptr;
MyClass mc;
int arr[10];
size_t sz1 = __datasizeof(int);
size_t sz2 = __datasizeof(char);
size_t sz3 = __datasizeof(int *);
size_t sz4 = __datasizeof(MyClass);
size_t sz5 = __datasizeof(i);
size_t sz6 = __datasizeof(c);
size_t sz7 = __datasizeof(ptr);
size_t sz8 = __datasizeof(mc);
size_t sz9 = __datasizeof(arr);
size_t sz10 = __datasizeof(arr[4]);
}

View File

@@ -0,0 +1,10 @@
| datasizeof.cpp:20:15:20:31 | __datasizeof(int) | 4 | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int |
| datasizeof.cpp:21:15:21:32 | __datasizeof(char) | 1 | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char |
| datasizeof.cpp:22:15:22:33 | __datasizeof(int *) | 8 | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * |
| datasizeof.cpp:23:15:23:35 | __datasizeof(MyClass) | 24 | DatasizeofTypeOperator.getTypeOperand() | datasizeof.cpp:5:7:5:13 | MyClass |
| datasizeof.cpp:24:15:24:29 | __datasizeof(<expr>) | 4 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:24:28:24:28 | i |
| datasizeof.cpp:25:15:25:29 | __datasizeof(<expr>) | 1 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:25:28:25:28 | c |
| datasizeof.cpp:26:15:26:31 | __datasizeof(<expr>) | 8 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:26:28:26:30 | ptr |
| datasizeof.cpp:27:15:27:30 | __datasizeof(<expr>) | 24 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:27:28:27:29 | mc |
| datasizeof.cpp:28:15:28:31 | __datasizeof(<expr>) | 40 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:28:28:28:30 | arr |
| datasizeof.cpp:29:16:29:35 | __datasizeof(<expr>) | 4 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:29:29:29:34 | access to array |

View File

@@ -0,0 +1,10 @@
import cpp
from DatasizeofOperator sto, string elemDesc, Element e
where
elemDesc = "DatasizeofTypeOperator.getTypeOperand()" and
e = sto.(DatasizeofTypeOperator).getTypeOperand()
or
elemDesc = "DatasizeofExprOperator.getExprOperand()" and
e = sto.(DatasizeofExprOperator).getExprOperand()
select sto, sto.getValue(), elemDesc, e

View File

@@ -1,10 +1,10 @@
| sizeof.cpp:19:15:19:25 | sizeof(int) | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int |
| sizeof.cpp:20:15:20:26 | sizeof(char) | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char |
| sizeof.cpp:21:15:21:27 | sizeof(int *) | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * |
| sizeof.cpp:22:15:22:29 | sizeof(MyClass) | SizeofTypeOperator.getTypeOperand() | sizeof.cpp:4:7:4:13 | MyClass |
| sizeof.cpp:23:15:23:23 | sizeof(<expr>) | SizeofExprOperator.getExprOperand() | sizeof.cpp:23:22:23:22 | i |
| sizeof.cpp:24:15:24:23 | sizeof(<expr>) | SizeofExprOperator.getExprOperand() | sizeof.cpp:24:22:24:22 | c |
| sizeof.cpp:25:15:25:25 | sizeof(<expr>) | SizeofExprOperator.getExprOperand() | sizeof.cpp:25:22:25:24 | ptr |
| sizeof.cpp:26:15:26:24 | sizeof(<expr>) | SizeofExprOperator.getExprOperand() | sizeof.cpp:26:22:26:23 | mc |
| sizeof.cpp:27:15:27:25 | sizeof(<expr>) | SizeofExprOperator.getExprOperand() | sizeof.cpp:27:22:27:24 | arr |
| sizeof.cpp:28:16:28:29 | sizeof(<expr>) | SizeofExprOperator.getExprOperand() | sizeof.cpp:28:23:28:28 | access to array |
| sizeof.cpp:19:15:19:25 | sizeof(int) | 4 | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int |
| sizeof.cpp:20:15:20:26 | sizeof(char) | 1 | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char |
| sizeof.cpp:21:15:21:27 | sizeof(int *) | 8 | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * |
| sizeof.cpp:22:15:22:29 | sizeof(MyClass) | 16 | SizeofTypeOperator.getTypeOperand() | sizeof.cpp:4:7:4:13 | MyClass |
| sizeof.cpp:23:15:23:23 | sizeof(<expr>) | 4 | SizeofExprOperator.getExprOperand() | sizeof.cpp:23:22:23:22 | i |
| sizeof.cpp:24:15:24:23 | sizeof(<expr>) | 1 | SizeofExprOperator.getExprOperand() | sizeof.cpp:24:22:24:22 | c |
| sizeof.cpp:25:15:25:25 | sizeof(<expr>) | 8 | SizeofExprOperator.getExprOperand() | sizeof.cpp:25:22:25:24 | ptr |
| sizeof.cpp:26:15:26:24 | sizeof(<expr>) | 16 | SizeofExprOperator.getExprOperand() | sizeof.cpp:26:22:26:23 | mc |
| sizeof.cpp:27:15:27:25 | sizeof(<expr>) | 40 | SizeofExprOperator.getExprOperand() | sizeof.cpp:27:22:27:24 | arr |
| sizeof.cpp:28:16:28:29 | sizeof(<expr>) | 4 | SizeofExprOperator.getExprOperand() | sizeof.cpp:28:23:28:28 | access to array |

View File

@@ -7,4 +7,4 @@ where
or
elemDesc = "SizeofExprOperator.getExprOperand()" and
e = sto.(SizeofExprOperator).getExprOperand()
select sto, elemDesc, e
select sto, sto.getValue(), elemDesc, e

View File

@@ -16,7 +16,6 @@ edges
| test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:153:5:153:5 | a | provenance | |
| test_free.cpp:233:14:233:15 | pointer to free output argument | test_free.cpp:234:9:234:11 | *... ++ | provenance | |
| test_free.cpp:234:9:234:11 | *... ++ | test_free.cpp:236:9:236:10 | * ... | provenance | |
| test_free.cpp:238:15:238:17 | *... ++ | test_free.cpp:238:15:238:17 | *... ++ | provenance | |
| test_free.cpp:238:15:238:17 | *... ++ | test_free.cpp:241:9:241:10 | * ... | provenance | |
| test_free.cpp:239:14:239:15 | pointer to free output argument | test_free.cpp:238:15:238:17 | *... ++ | provenance | |
| test_free.cpp:245:10:245:11 | pointer to free output argument | test_free.cpp:246:9:246:10 | * ... | provenance | |

View File

@@ -22,11 +22,9 @@ edges
| test.c:41:5:41:24 | ... = ... | test.c:44:7:44:10 | len2 | provenance | |
| test.c:41:5:41:24 | ... = ... | test.c:44:7:44:12 | ... -- | provenance | |
| test.c:44:7:44:12 | ... -- | test.c:44:7:44:10 | len2 | provenance | |
| test.c:44:7:44:12 | ... -- | test.c:44:7:44:12 | ... -- | provenance | |
| test.c:51:5:51:24 | ... = ... | test.c:54:7:54:10 | len3 | provenance | |
| test.c:51:5:51:24 | ... = ... | test.c:54:7:54:12 | ... -- | provenance | |
| test.c:54:7:54:12 | ... -- | test.c:54:7:54:10 | len3 | provenance | |
| test.c:54:7:54:12 | ... -- | test.c:54:7:54:12 | ... -- | provenance | |
nodes
| test2.cpp:12:21:12:21 | v | semmle.label | v |
| test2.cpp:14:11:14:11 | v | semmle.label | v |

View File

@@ -17,3 +17,4 @@
| test.cpp:229:15:229:35 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:231:16:231:19 | { ... } | This catch block |
| test.cpp:242:14:242:34 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:243:34:243:36 | { ... } | This catch block |
| test.cpp:276:17:276:31 | new[] | This allocation cannot return null. $@ is unnecessary. | test.cpp:277:8:277:12 | ! ... | This check |
| test.cpp:288:19:288:47 | new[] | This allocation cannot throw. $@ is unnecessary. | test.cpp:291:30:293:5 | { ... } | This catch block |

View File

@@ -282,7 +282,7 @@ namespace qhelp {
}
// BAD: the allocation won't throw an exception, but
// instead return a null pointer. [NOT DETECTED]
// instead return a null pointer.
void bad2(std::size_t length) noexcept {
try {
int* dest = new(std::nothrow) int[length];

View File

@@ -108,7 +108,11 @@ private module SourceVariableImpl {
*/
predicate isPlainFieldOrPropAccess(FieldOrPropAccess fpa, FieldOrProp fp, Callable c) {
fieldOrPropAccessInCallable(fpa, fp, c) and
(ownFieldOrPropAccess(fpa) or fp.isStatic())
(
ownFieldOrPropAccess(fpa)
or
fp.isStatic() and not fp instanceof EnumConstant
)
}
/**

View File

@@ -0,0 +1,14 @@
enum E
{
A
}
class EnumTest
{
void M()
{
// enums are modelled as fields; this test checks that we do not compute SSA for them
var e1 = E.A;
var e2 = E.A;
}
}

View File

@@ -12,13 +12,11 @@ edges
| InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Byte | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | provenance | MaD:1 |
| InsecureRandomness.cs:31:16:31:21 | access to local variable result : StringBuilder | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | provenance | MaD:3 |
| InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | provenance | |
| InsecureRandomness.cs:60:13:60:18 | access to local variable result : String | InsecureRandomness.cs:60:13:60:18 | access to local variable result : String | provenance | |
| InsecureRandomness.cs:60:13:60:18 | access to local variable result : String | InsecureRandomness.cs:62:16:62:21 | access to local variable result : String | provenance | |
| InsecureRandomness.cs:60:23:60:40 | access to array element : String | InsecureRandomness.cs:60:13:60:18 | access to local variable result : String | provenance | |
| InsecureRandomness.cs:60:31:60:39 | call to method Next : Int32 | InsecureRandomness.cs:60:23:60:40 | access to array element : String | provenance | Config |
| InsecureRandomness.cs:62:16:62:21 | access to local variable result : String | InsecureRandomness.cs:62:16:62:32 | call to method ToString : String | provenance | MaD:4 |
| InsecureRandomness.cs:62:16:62:32 | call to method ToString : String | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | provenance | |
| InsecureRandomness.cs:72:13:72:18 | access to local variable result : String | InsecureRandomness.cs:72:13:72:18 | access to local variable result : String | provenance | |
| InsecureRandomness.cs:72:13:72:18 | access to local variable result : String | InsecureRandomness.cs:74:16:74:21 | access to local variable result : String | provenance | |
| InsecureRandomness.cs:72:23:72:40 | access to indexer : String | InsecureRandomness.cs:72:13:72:18 | access to local variable result : String | provenance | |
| InsecureRandomness.cs:72:31:72:39 | call to method Next : Int32 | InsecureRandomness.cs:72:23:72:40 | access to indexer : String | provenance | Config |

View File

@@ -16,7 +16,7 @@
.NET Core up to 3.1
.NET 5, .NET 6, .NET 7, .NET 8","``.sln``, ``.csproj``, ``.cs``, ``.cshtml``, ``.xaml``"
Go (aka Golang), "Go up to 1.22", "Go 1.11 or more recent", ``.go``
Go (aka Golang), "Go up to 1.23", "Go 1.11 or more recent", ``.go``
Java,"Java 7 to 22 [5]_","javac (OpenJDK and Oracle JDK),
Eclipse compiler for Java (ECJ) [6]_",``.java``

View File

@@ -4,7 +4,7 @@ inputs:
go-test-version:
description: Which Go version to use for running the tests
required: false
default: ~1.22.0
default: "1.23.0"
run-code-checks:
description: Whether to run formatting, code and qhelp generation checks
required: false

View File

@@ -0,0 +1,546 @@
/** Auto-generated dbscheme; do not edit. */
/** Duplicate code **/
duplicateCode(
unique int id : @duplication,
varchar(900) relativePath : string ref,
int equivClass : int ref);
similarCode(
unique int id : @similarity,
varchar(900) relativePath : string ref,
int equivClass : int ref);
@duplication_or_similarity = @duplication | @similarity;
tokens(
int id : @duplication_or_similarity ref,
int offset : int ref,
int beginLine : int ref,
int beginColumn : int ref,
int endLine : int ref,
int endColumn : int ref);
/** External data **/
externalData(
int id : @externalDataElement,
varchar(900) path : string ref,
int column: int ref,
varchar(900) value : string ref
);
snapshotDate(unique date snapshotDate : date ref);
sourceLocationPrefix(varchar(900) prefix : string ref);
/*
* XML Files
*/
xmlEncoding(
unique int id: @file ref,
string encoding: string ref
);
xmlDTDs(
unique int id: @xmldtd,
string root: string ref,
string publicId: string ref,
string systemId: string ref,
int fileid: @file ref
);
xmlElements(
unique int id: @xmlelement,
string name: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int fileid: @file ref
);
xmlAttrs(
unique int id: @xmlattribute,
int elementid: @xmlelement ref,
string name: string ref,
string value: string ref,
int idx: int ref,
int fileid: @file ref
);
xmlNs(
int id: @xmlnamespace,
string prefixName: string ref,
string URI: string ref,
int fileid: @file ref
);
xmlHasNs(
int elementId: @xmlnamespaceable ref,
int nsId: @xmlnamespace ref,
int fileid: @file ref
);
xmlComments(
unique int id: @xmlcomment,
string text: string ref,
int parentid: @xmlparent ref,
int fileid: @file ref
);
xmlChars(
unique int id: @xmlcharacters,
string text: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int isCDATA: int ref,
int fileid: @file ref
);
@xmlparent = @file | @xmlelement;
@xmlnamespaceable = @xmlelement | @xmlattribute;
xmllocations(
int xmlElement: @xmllocatable ref,
int location: @location_default ref
);
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
compilations(unique int id: @compilation, string cwd: string ref);
#keyset[id, num]
compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref);
#keyset[id, num, kind]
compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref);
diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref);
compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref);
#keyset[id, num]
compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref);
diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref,
string full_error_message: string ref, int location: @location ref);
locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref,
int endLine: int ref, int endColumn: int ref);
numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref);
files(unique int id: @file, string name: string ref);
folders(unique int id: @folder, string name: string ref);
containerparent(int parent: @container ref, unique int child: @container ref);
has_location(unique int locatable: @locatable ref, int location: @location ref);
#keyset[parent, idx]
comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref);
comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref);
doc_comments(unique int node: @documentable ref, int comment: @comment_group ref);
#keyset[parent, idx]
exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref);
literals(unique int expr: @expr ref, string value: string ref, string raw: string ref);
constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref);
fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref);
typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref);
#keyset[parent, idx]
stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref);
#keyset[parent, idx]
decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref);
#keyset[parent, idx]
specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref);
scopes(unique int id: @scope, int kind: int ref);
scopenesting(unique int inner: @scope ref, int outer: @scope ref);
scopenodes(unique int node: @scopenode ref, int scope: @localscope ref);
objects(unique int id: @object, int kind: int ref, string name: string ref);
objectscopes(unique int object: @object ref, int scope: @scope ref);
objecttypes(unique int object: @object ref, int tp: @type ref);
methodreceivers(unique int method: @object ref, int receiver: @object ref);
fieldstructs(unique int field: @object ref, int struct: @structtype ref);
methodhosts(int method: @object ref, int host: @namedtype ref);
defs(int ident: @ident ref, int object: @object ref);
uses(int ident: @ident ref, int object: @object ref);
types(unique int id: @type, int kind: int ref);
type_of(unique int expr: @expr ref, int tp: @type ref);
typename(unique int tp: @type ref, string name: string ref);
key_type(unique int map: @maptype ref, int tp: @type ref);
element_type(unique int container: @containertype ref, int tp: @type ref);
base_type(unique int ptr: @pointertype ref, int tp: @type ref);
underlying_type(unique int named: @namedtype ref, int tp: @type ref);
#keyset[parent, index]
component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref);
array_length(unique int tp: @arraytype ref, string len: string ref);
type_objects(unique int tp: @type ref, int object: @object ref);
packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref);
#keyset[parent, idx]
modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref);
#keyset[parent, idx]
modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref);
#keyset[package, idx]
errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref,
string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref);
has_ellipsis(int id: @callorconversionexpr ref);
variadic(int id: @signaturetype ref);
#keyset[parent, idx]
typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref,
int parent: @typeparamparentobject ref, int idx: int ref);
@container = @file | @folder;
@locatable = @xmllocatable | @node | @localscope;
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent
| @scopenode | @comment_group | @comment;
@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr;
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec;
@modexprparent = @file | @modexpr;
@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr;
@stmtparent = @funcdef | @stmt | @decl;
@declparent = @file | @declstmt;
@typeparamdeclparent = @funcdecl | @typespec;
@funcdef = @funclit | @funcdecl;
@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt;
@location = @location_default;
@sourceline = @locatable;
case @comment.kind of
0 = @slashslashcomment
| 1 = @slashstarcomment;
case @expr.kind of
0 = @badexpr
| 1 = @ident
| 2 = @ellipsis
| 3 = @intlit
| 4 = @floatlit
| 5 = @imaglit
| 6 = @charlit
| 7 = @stringlit
| 8 = @funclit
| 9 = @compositelit
| 10 = @parenexpr
| 11 = @selectorexpr
| 12 = @indexexpr
| 13 = @genericfunctioninstantiationexpr
| 14 = @generictypeinstantiationexpr
| 15 = @sliceexpr
| 16 = @typeassertexpr
| 17 = @callorconversionexpr
| 18 = @starexpr
| 19 = @keyvalueexpr
| 20 = @arraytypeexpr
| 21 = @structtypeexpr
| 22 = @functypeexpr
| 23 = @interfacetypeexpr
| 24 = @maptypeexpr
| 25 = @typesetliteralexpr
| 26 = @plusexpr
| 27 = @minusexpr
| 28 = @notexpr
| 29 = @complementexpr
| 30 = @derefexpr
| 31 = @addressexpr
| 32 = @arrowexpr
| 33 = @lorexpr
| 34 = @landexpr
| 35 = @eqlexpr
| 36 = @neqexpr
| 37 = @lssexpr
| 38 = @leqexpr
| 39 = @gtrexpr
| 40 = @geqexpr
| 41 = @addexpr
| 42 = @subexpr
| 43 = @orexpr
| 44 = @xorexpr
| 45 = @mulexpr
| 46 = @quoexpr
| 47 = @remexpr
| 48 = @shlexpr
| 49 = @shrexpr
| 50 = @andexpr
| 51 = @andnotexpr
| 52 = @sendchantypeexpr
| 53 = @recvchantypeexpr
| 54 = @sendrcvchantypeexpr;
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;
@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr;
@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr;
@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr;
@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr;
@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr;
@logicalunaryexpr = @notexpr;
@bitwiseunaryexpr = @complementexpr;
@arithmeticunaryexpr = @plusexpr | @minusexpr;
@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison;
@logicalbinaryexpr = @lorexpr | @landexpr;
@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr;
@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr;
@shiftexpr = @shlexpr | @shrexpr;
@comparison = @equalitytest | @relationalcomparison;
@equalitytest = @eqlexpr | @neqexpr;
@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr;
@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr;
case @stmt.kind of
0 = @badstmt
| 1 = @declstmt
| 2 = @emptystmt
| 3 = @labeledstmt
| 4 = @exprstmt
| 5 = @sendstmt
| 6 = @incstmt
| 7 = @decstmt
| 8 = @gostmt
| 9 = @deferstmt
| 10 = @returnstmt
| 11 = @breakstmt
| 12 = @continuestmt
| 13 = @gotostmt
| 14 = @fallthroughstmt
| 15 = @blockstmt
| 16 = @ifstmt
| 17 = @caseclause
| 18 = @exprswitchstmt
| 19 = @typeswitchstmt
| 20 = @commclause
| 21 = @selectstmt
| 22 = @forstmt
| 23 = @rangestmt
| 24 = @assignstmt
| 25 = @definestmt
| 26 = @addassignstmt
| 27 = @subassignstmt
| 28 = @mulassignstmt
| 29 = @quoassignstmt
| 30 = @remassignstmt
| 31 = @andassignstmt
| 32 = @orassignstmt
| 33 = @xorassignstmt
| 34 = @shlassignstmt
| 35 = @shrassignstmt
| 36 = @andnotassignstmt;
@incdecstmt = @incstmt | @decstmt;
@assignment = @simpleassignstmt | @compoundassignstmt;
@simpleassignstmt = @assignstmt | @definestmt;
@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt
| @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt;
@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt;
@switchstmt = @exprswitchstmt | @typeswitchstmt;
@loopstmt = @forstmt | @rangestmt;
case @decl.kind of
0 = @baddecl
| 1 = @importdecl
| 2 = @constdecl
| 3 = @typedecl
| 4 = @vardecl
| 5 = @funcdecl;
@gendecl = @importdecl | @constdecl | @typedecl | @vardecl;
case @spec.kind of
0 = @importspec
| 1 = @valuespec
| 2 = @typedefspec
| 3 = @aliasspec;
@typespec = @typedefspec | @aliasspec;
case @object.kind of
0 = @pkgobject
| 1 = @decltypeobject
| 2 = @builtintypeobject
| 3 = @declconstobject
| 4 = @builtinconstobject
| 5 = @declvarobject
| 6 = @declfunctionobject
| 7 = @builtinfunctionobject
| 8 = @labelobject;
@typeparamparentobject = @decltypeobject | @declfunctionobject;
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
@typeobject = @decltypeobject | @builtintypeobject;
@valueobject = @constobject | @varobject | @functionobject;
@constobject = @declconstobject | @builtinconstobject;
@varobject = @declvarobject;
@functionobject = @declfunctionobject | @builtinfunctionobject;
case @scope.kind of
0 = @universescope
| 1 = @packagescope
| 2 = @localscope;
case @type.kind of
0 = @invalidtype
| 1 = @boolexprtype
| 2 = @inttype
| 3 = @int8type
| 4 = @int16type
| 5 = @int32type
| 6 = @int64type
| 7 = @uinttype
| 8 = @uint8type
| 9 = @uint16type
| 10 = @uint32type
| 11 = @uint64type
| 12 = @uintptrtype
| 13 = @float32type
| 14 = @float64type
| 15 = @complex64type
| 16 = @complex128type
| 17 = @stringexprtype
| 18 = @unsafepointertype
| 19 = @boolliteraltype
| 20 = @intliteraltype
| 21 = @runeliteraltype
| 22 = @floatliteraltype
| 23 = @complexliteraltype
| 24 = @stringliteraltype
| 25 = @nilliteraltype
| 26 = @typeparamtype
| 27 = @arraytype
| 28 = @slicetype
| 29 = @structtype
| 30 = @pointertype
| 31 = @interfacetype
| 32 = @tupletype
| 33 = @signaturetype
| 34 = @maptype
| 35 = @sendchantype
| 36 = @recvchantype
| 37 = @sendrcvchantype
| 38 = @namedtype
| 39 = @typesetliteraltype;
@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype;
@booltype = @boolexprtype | @boolliteraltype;
@numerictype = @integertype | @floattype | @complextype;
@integertype = @signedintegertype | @unsignedintegertype;
@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype;
@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype;
@floattype = @float32type | @float64type | @floatliteraltype;
@complextype = @complex64type | @complex128type | @complexliteraltype;
@stringtype = @stringexprtype | @stringliteraltype;
@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype
| @stringliteraltype | @nilliteraltype;
@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype
| @signaturetype | @namedtype | @typesetliteraltype;
@containertype = @arraytype | @slicetype | @maptype | @chantype;
@chantype = @sendchantype | @recvchantype | @sendrcvchantype;
case @modexpr.kind of
0 = @modcommentblock
| 1 = @modline
| 2 = @modlineblock
| 3 = @modlparen
| 4 = @modrparen;
case @error.kind of
0 = @unknownerror
| 1 = @listerror
| 2 = @parseerror
| 3 = @typeerror;

View File

@@ -0,0 +1,14 @@
class Type_ extends @type {
string toString() { result = "Type" }
}
// The schema for types and typename are:
//
// types(unique int id: @type, int kind: int ref);
// objects(unique int id: @object, int kind: int ref, string name: string ref);
from Type_ type, int object, int kind
where
objects(type, object) and
types(type, kind) and
kind != 40 // @typealias
select type, object

View File

@@ -0,0 +1,549 @@
/** Auto-generated dbscheme; do not edit. */
/** Duplicate code **/
duplicateCode(
unique int id : @duplication,
varchar(900) relativePath : string ref,
int equivClass : int ref);
similarCode(
unique int id : @similarity,
varchar(900) relativePath : string ref,
int equivClass : int ref);
@duplication_or_similarity = @duplication | @similarity;
tokens(
int id : @duplication_or_similarity ref,
int offset : int ref,
int beginLine : int ref,
int beginColumn : int ref,
int endLine : int ref,
int endColumn : int ref);
/** External data **/
externalData(
int id : @externalDataElement,
varchar(900) path : string ref,
int column: int ref,
varchar(900) value : string ref
);
snapshotDate(unique date snapshotDate : date ref);
sourceLocationPrefix(varchar(900) prefix : string ref);
/*
* XML Files
*/
xmlEncoding(
unique int id: @file ref,
string encoding: string ref
);
xmlDTDs(
unique int id: @xmldtd,
string root: string ref,
string publicId: string ref,
string systemId: string ref,
int fileid: @file ref
);
xmlElements(
unique int id: @xmlelement,
string name: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int fileid: @file ref
);
xmlAttrs(
unique int id: @xmlattribute,
int elementid: @xmlelement ref,
string name: string ref,
string value: string ref,
int idx: int ref,
int fileid: @file ref
);
xmlNs(
int id: @xmlnamespace,
string prefixName: string ref,
string URI: string ref,
int fileid: @file ref
);
xmlHasNs(
int elementId: @xmlnamespaceable ref,
int nsId: @xmlnamespace ref,
int fileid: @file ref
);
xmlComments(
unique int id: @xmlcomment,
string text: string ref,
int parentid: @xmlparent ref,
int fileid: @file ref
);
xmlChars(
unique int id: @xmlcharacters,
string text: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int isCDATA: int ref,
int fileid: @file ref
);
@xmlparent = @file | @xmlelement;
@xmlnamespaceable = @xmlelement | @xmlattribute;
xmllocations(
int xmlElement: @xmllocatable ref,
int location: @location_default ref
);
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
compilations(unique int id: @compilation, string cwd: string ref);
#keyset[id, num]
compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref);
#keyset[id, num, kind]
compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref);
diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref);
compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref);
#keyset[id, num]
compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref);
diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref,
string full_error_message: string ref, int location: @location ref);
locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref,
int endLine: int ref, int endColumn: int ref);
numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref);
files(unique int id: @file, string name: string ref);
folders(unique int id: @folder, string name: string ref);
containerparent(int parent: @container ref, unique int child: @container ref);
has_location(unique int locatable: @locatable ref, int location: @location ref);
#keyset[parent, idx]
comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref);
comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref);
doc_comments(unique int node: @documentable ref, int comment: @comment_group ref);
#keyset[parent, idx]
exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref);
literals(unique int expr: @expr ref, string value: string ref, string raw: string ref);
constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref);
fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref);
typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref);
#keyset[parent, idx]
stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref);
#keyset[parent, idx]
decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref);
#keyset[parent, idx]
specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref);
scopes(unique int id: @scope, int kind: int ref);
scopenesting(unique int inner: @scope ref, int outer: @scope ref);
scopenodes(unique int node: @scopenode ref, int scope: @localscope ref);
objects(unique int id: @object, int kind: int ref, string name: string ref);
objectscopes(unique int object: @object ref, int scope: @scope ref);
objecttypes(unique int object: @object ref, int tp: @type ref);
methodreceivers(unique int method: @object ref, int receiver: @object ref);
fieldstructs(unique int field: @object ref, int struct: @structtype ref);
methodhosts(int method: @object ref, int host: @namedtype ref);
defs(int ident: @ident ref, int object: @object ref);
uses(int ident: @ident ref, int object: @object ref);
types(unique int id: @type, int kind: int ref);
type_of(unique int expr: @expr ref, int tp: @type ref);
typename(unique int tp: @type ref, string name: string ref);
key_type(unique int map: @maptype ref, int tp: @type ref);
element_type(unique int container: @containertype ref, int tp: @type ref);
base_type(unique int ptr: @pointertype ref, int tp: @type ref);
underlying_type(unique int named: @namedtype ref, int tp: @type ref);
alias_rhs(unique int alias: @typealias ref, int tp: @type ref);
#keyset[parent, index]
component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref);
array_length(unique int tp: @arraytype ref, string len: string ref);
type_objects(unique int tp: @type ref, int object: @object ref);
packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref);
#keyset[parent, idx]
modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref);
#keyset[parent, idx]
modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref);
#keyset[package, idx]
errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref,
string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref);
has_ellipsis(int id: @callorconversionexpr ref);
variadic(int id: @signaturetype ref);
#keyset[parent, idx]
typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref,
int parent: @typeparamparentobject ref, int idx: int ref);
@container = @file | @folder;
@locatable = @xmllocatable | @node | @localscope;
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent
| @scopenode | @comment_group | @comment;
@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr;
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec;
@modexprparent = @file | @modexpr;
@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr;
@stmtparent = @funcdef | @stmt | @decl;
@declparent = @file | @declstmt;
@typeparamdeclparent = @funcdecl | @typespec;
@funcdef = @funclit | @funcdecl;
@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt;
@location = @location_default;
@sourceline = @locatable;
case @comment.kind of
0 = @slashslashcomment
| 1 = @slashstarcomment;
case @expr.kind of
0 = @badexpr
| 1 = @ident
| 2 = @ellipsis
| 3 = @intlit
| 4 = @floatlit
| 5 = @imaglit
| 6 = @charlit
| 7 = @stringlit
| 8 = @funclit
| 9 = @compositelit
| 10 = @parenexpr
| 11 = @selectorexpr
| 12 = @indexexpr
| 13 = @genericfunctioninstantiationexpr
| 14 = @generictypeinstantiationexpr
| 15 = @sliceexpr
| 16 = @typeassertexpr
| 17 = @callorconversionexpr
| 18 = @starexpr
| 19 = @keyvalueexpr
| 20 = @arraytypeexpr
| 21 = @structtypeexpr
| 22 = @functypeexpr
| 23 = @interfacetypeexpr
| 24 = @maptypeexpr
| 25 = @typesetliteralexpr
| 26 = @plusexpr
| 27 = @minusexpr
| 28 = @notexpr
| 29 = @complementexpr
| 30 = @derefexpr
| 31 = @addressexpr
| 32 = @arrowexpr
| 33 = @lorexpr
| 34 = @landexpr
| 35 = @eqlexpr
| 36 = @neqexpr
| 37 = @lssexpr
| 38 = @leqexpr
| 39 = @gtrexpr
| 40 = @geqexpr
| 41 = @addexpr
| 42 = @subexpr
| 43 = @orexpr
| 44 = @xorexpr
| 45 = @mulexpr
| 46 = @quoexpr
| 47 = @remexpr
| 48 = @shlexpr
| 49 = @shrexpr
| 50 = @andexpr
| 51 = @andnotexpr
| 52 = @sendchantypeexpr
| 53 = @recvchantypeexpr
| 54 = @sendrcvchantypeexpr;
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;
@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr;
@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr;
@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr;
@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr;
@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr;
@logicalunaryexpr = @notexpr;
@bitwiseunaryexpr = @complementexpr;
@arithmeticunaryexpr = @plusexpr | @minusexpr;
@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison;
@logicalbinaryexpr = @lorexpr | @landexpr;
@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr;
@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr;
@shiftexpr = @shlexpr | @shrexpr;
@comparison = @equalitytest | @relationalcomparison;
@equalitytest = @eqlexpr | @neqexpr;
@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr;
@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr;
case @stmt.kind of
0 = @badstmt
| 1 = @declstmt
| 2 = @emptystmt
| 3 = @labeledstmt
| 4 = @exprstmt
| 5 = @sendstmt
| 6 = @incstmt
| 7 = @decstmt
| 8 = @gostmt
| 9 = @deferstmt
| 10 = @returnstmt
| 11 = @breakstmt
| 12 = @continuestmt
| 13 = @gotostmt
| 14 = @fallthroughstmt
| 15 = @blockstmt
| 16 = @ifstmt
| 17 = @caseclause
| 18 = @exprswitchstmt
| 19 = @typeswitchstmt
| 20 = @commclause
| 21 = @selectstmt
| 22 = @forstmt
| 23 = @rangestmt
| 24 = @assignstmt
| 25 = @definestmt
| 26 = @addassignstmt
| 27 = @subassignstmt
| 28 = @mulassignstmt
| 29 = @quoassignstmt
| 30 = @remassignstmt
| 31 = @andassignstmt
| 32 = @orassignstmt
| 33 = @xorassignstmt
| 34 = @shlassignstmt
| 35 = @shrassignstmt
| 36 = @andnotassignstmt;
@incdecstmt = @incstmt | @decstmt;
@assignment = @simpleassignstmt | @compoundassignstmt;
@simpleassignstmt = @assignstmt | @definestmt;
@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt
| @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt;
@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt;
@switchstmt = @exprswitchstmt | @typeswitchstmt;
@loopstmt = @forstmt | @rangestmt;
case @decl.kind of
0 = @baddecl
| 1 = @importdecl
| 2 = @constdecl
| 3 = @typedecl
| 4 = @vardecl
| 5 = @funcdecl;
@gendecl = @importdecl | @constdecl | @typedecl | @vardecl;
case @spec.kind of
0 = @importspec
| 1 = @valuespec
| 2 = @typedefspec
| 3 = @aliasspec;
@typespec = @typedefspec | @aliasspec;
case @object.kind of
0 = @pkgobject
| 1 = @decltypeobject
| 2 = @builtintypeobject
| 3 = @declconstobject
| 4 = @builtinconstobject
| 5 = @declvarobject
| 6 = @declfunctionobject
| 7 = @builtinfunctionobject
| 8 = @labelobject;
@typeparamparentobject = @decltypeobject | @declfunctionobject;
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
@typeobject = @decltypeobject | @builtintypeobject;
@valueobject = @constobject | @varobject | @functionobject;
@constobject = @declconstobject | @builtinconstobject;
@varobject = @declvarobject;
@functionobject = @declfunctionobject | @builtinfunctionobject;
case @scope.kind of
0 = @universescope
| 1 = @packagescope
| 2 = @localscope;
case @type.kind of
0 = @invalidtype
| 1 = @boolexprtype
| 2 = @inttype
| 3 = @int8type
| 4 = @int16type
| 5 = @int32type
| 6 = @int64type
| 7 = @uinttype
| 8 = @uint8type
| 9 = @uint16type
| 10 = @uint32type
| 11 = @uint64type
| 12 = @uintptrtype
| 13 = @float32type
| 14 = @float64type
| 15 = @complex64type
| 16 = @complex128type
| 17 = @stringexprtype
| 18 = @unsafepointertype
| 19 = @boolliteraltype
| 20 = @intliteraltype
| 21 = @runeliteraltype
| 22 = @floatliteraltype
| 23 = @complexliteraltype
| 24 = @stringliteraltype
| 25 = @nilliteraltype
| 26 = @typeparamtype
| 27 = @arraytype
| 28 = @slicetype
| 29 = @structtype
| 30 = @pointertype
| 31 = @interfacetype
| 32 = @tupletype
| 33 = @signaturetype
| 34 = @maptype
| 35 = @sendchantype
| 36 = @recvchantype
| 37 = @sendrcvchantype
| 38 = @namedtype
| 39 = @typesetliteraltype
| 40 = @typealias;
@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype;
@booltype = @boolexprtype | @boolliteraltype;
@numerictype = @integertype | @floattype | @complextype;
@integertype = @signedintegertype | @unsignedintegertype;
@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype;
@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype;
@floattype = @float32type | @float64type | @floatliteraltype;
@complextype = @complex64type | @complex128type | @complexliteraltype;
@stringtype = @stringexprtype | @stringliteraltype;
@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype
| @stringliteraltype | @nilliteraltype;
@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype
| @signaturetype | @namedtype | @typesetliteraltype | @typealias;
@containertype = @arraytype | @slicetype | @maptype | @chantype;
@chantype = @sendchantype | @recvchantype | @sendrcvchantype;
case @modexpr.kind of
0 = @modcommentblock
| 1 = @modline
| 2 = @modlineblock
| 3 = @modlparen
| 4 = @modrparen;
case @error.kind of
0 = @unknownerror
| 1 = @listerror
| 2 = @parseerror
| 3 = @typeerror;

View File

@@ -0,0 +1,18 @@
class Type_ extends @type {
string toString() { result = "Type" }
}
class Object_ extends @object {
string toString() { result = "Object" }
}
// The schema for types and typename are:
//
// types(unique int id: @type, int kind: int ref);
// type_objects(unique int tp: @type ref, int object: @object ref);
from Type_ type, Object_ object, int kind
where
type_objects(type, object) and
types(type, kind) and
kind != 40 // @typealias
select type, object

View File

@@ -0,0 +1,14 @@
class Type_ extends @type {
string toString() { result = "Type" }
}
// The schema for types and typename are:
//
// types(unique int id: @type, int kind: int ref);
// typename(unique int tp: @type ref, string name: string ref);
from Type_ type, string name, int kind
where
typename(type, name) and
types(type, kind) and
kind != 40 // @typealias
select type, name

View File

@@ -0,0 +1,12 @@
class Type_ extends @type {
string toString() { result = "Type" }
}
// The schema for types is:
//
// types(unique int id: @type, int kind: int ref);
from Type_ type, int kind
where
types(type, kind) and
kind != 40 // @typealias
select type, kind

View File

@@ -0,0 +1,7 @@
description: Remove support for type aliases
compatibility: full
alias_rhs.rel: delete
types.rel: run types.qlo
typename.rel: run typename.qlo
type_objects.rel: run type_objects.qlo

View File

@@ -12,7 +12,7 @@ import (
)
var minGoVersion = util.NewSemVer("1.11")
var maxGoVersion = util.NewSemVer("1.22")
var maxGoVersion = util.NewSemVer("1.23")
type versionInfo struct {
goModVersion util.SemVer // The version of Go found in the go directive in the `go.mod` file.

View File

@@ -861,6 +861,9 @@ var NamedType = TypeKind.NewBranch("@namedtype", CompositeType)
// TypeSetLiteral is the type of type set literals
var TypeSetLiteral = TypeKind.NewBranch("@typesetliteraltype", CompositeType)
// TypeAlias is the type of type aliases
var TypeAlias = TypeKind.NewBranch("@typealias", CompositeType)
// PackageType is the type of packages
var PackageType = NewPrimaryKeyType("@package")
@@ -1142,6 +1145,12 @@ var UnderlyingTypeTable = NewTable("underlying_type",
EntityColumn(TypeType, "tp"),
)
// AliasRhsTable is the table associating type aliases with their RHS.
var AliasRhsTable = NewTable("alias_rhs",
EntityColumn(TypeAlias, "alias").Unique(),
EntityColumn(TypeType, "tp"),
)
// ComponentTypesTable is the table associating composite types with their component types
var ComponentTypesTable = NewTable("component_types",
EntityColumn(CompositeType, "parent"),

View File

@@ -1607,15 +1607,7 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
extractUnderlyingType(tw, lbl, underlying)
trackInstantiatedStructFields(tw, tp, origintp)
entitylbl, exists := tw.Labeler.LookupObjectID(origintp.Obj(), lbl)
if entitylbl == trap.InvalidLabel {
log.Printf("Omitting type-object binding for unknown object %v.\n", origintp.Obj())
} else {
if !exists {
extractObject(tw, origintp.Obj(), entitylbl)
}
dbscheme.TypeObjectTable.Emit(tw, lbl, entitylbl)
}
extractTypeObject(tw, lbl, origintp.Obj())
// ensure all methods have labels - note that methods do not have a
// parent scope, so they are not dealt with by `extractScopes`
@@ -1647,6 +1639,12 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
}
extractComponentType(tw, lbl, i, tildeStr, term.Type())
}
case *types.Alias:
kind = dbscheme.TypeAlias.Index()
dbscheme.TypeNameTable.Emit(tw, lbl, tp.Obj().Name())
dbscheme.AliasRhsTable.Emit(tw, lbl, extractType(tw, tp.Rhs()))
extractTypeObject(tw, lbl, tp.Obj())
default:
log.Fatalf("unexpected type %T", tp)
}
@@ -1790,6 +1788,19 @@ func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) {
fmt.Fprintf(&b, "{%s}", compLbl)
}
lbl = tw.Labeler.GlobalID(fmt.Sprintf("%s;typesetliteraltype", b.String()))
case *types.Alias:
// Ensure that the definition of the aliased type gets extracted
// (which may be an alias in itself).
extractType(tw, tp.Rhs())
entitylbl, exists := tw.Labeler.LookupObjectID(tp.Obj(), lbl)
if entitylbl == trap.InvalidLabel {
panic(fmt.Sprintf("Cannot construct label for alias type %v (underlying object is %v).\n", tp, tp.Obj()))
}
if !exists {
extractObject(tw, tp.Obj(), entitylbl)
}
lbl = tw.Labeler.GlobalID(fmt.Sprintf("{%s};aliastype", entitylbl))
default:
log.Fatalf("(getTypeLabel) unexpected type %T", tp)
}
@@ -1798,6 +1809,19 @@ func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) {
return lbl, exists
}
// extractTypeObject extracts a single type object and emits it to the type object table.
func extractTypeObject(tw *trap.Writer, lbl trap.Label, entity *types.TypeName) {
entitylbl, exists := tw.Labeler.LookupObjectID(entity, lbl)
if entitylbl == trap.InvalidLabel {
log.Printf("Omitting type-object binding for unknown object %v.\n", entity)
} else {
if !exists {
extractObject(tw, entity, entitylbl)
}
dbscheme.TypeObjectTable.Emit(tw, lbl, entitylbl)
}
}
// extractKeyType extracts `key` as the key type of the map type `mp`
func extractKeyType(tw *trap.Writer, mp trap.Label, key types.Type) {
dbscheme.KeyTypeTable.Emit(tw, mp, extractType(tw, key))

View File

@@ -1,6 +1,8 @@
module github.com/github/codeql-go/extractor
go 1.22.0
go 1.23
toolchain go1.23.0
// when updating this, run
// bazel run @rules_go//go -- mod tidy

Some files were not shown because too many files have changed in this diff Show More