diff --git a/change-notes/1.19/analysis-cpp.md b/change-notes/1.19/analysis-cpp.md
index f22f5dc638f..6d274150621 100644
--- a/change-notes/1.19/analysis-cpp.md
+++ b/change-notes/1.19/analysis-cpp.md
@@ -9,21 +9,33 @@
| Cast between `HRESULT` and a Boolean type (`cpp/hresult-boolean-conversion`) | external/cwe/cwe-253 | Finds logic errors caused by mistakenly treating the Windows `HRESULT` type as a Boolean instead of testing it with the appropriate macros. Enabled by default. |
| Setting a DACL to `NULL` in a `SECURITY_DESCRIPTOR` (`cpp/unsafe-dacl-security-descriptor`) | external/cwe/cwe-732 | This query finds code that creates world-writable objects on Windows by setting their DACL to `NULL`. Enabled by default. |
| Cast from `char*` to `wchar_t*` | security, external/cwe/cwe-704 | Detects potentially dangerous casts from `char*` to `wchar_t*`. Enabled by default on LGTM. |
-| Dead code due to `goto` or `break` statement (`cpp/dead-code-goto`) | maintainability, external/cwe/cwe-561 | Detects dead code following a goto or break statement. Enabled by default on LGTM. |
+| Dead code due to `goto` or `break` statement (`cpp/dead-code-goto`) | maintainability, external/cwe/cwe-561 | Detects dead code following a `goto` or `break` statement. Enabled by default on LGTM. |
+| Inconsistent direction of for loop | correctness, external/cwe/cwe-835 | This query detects `for` loops where the increment and guard condition don't appear to correspond. Enabled by default on LGTM. |
+| Incorrect Not Operator Usage | security, external/cwe/cwe-480 | This query finds uses of the logical not (`!`) operator that look like they should be bit-wise not (`~`). Available but not displayed by default on LGTM. |
+| NULL application name with an unquoted path in call to CreateProcess | security, external/cwe/cwe-428 | This query finds unsafe uses of the `CreateProcess` function. Available but not displayed by default on LGTM. |
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
+| Array offset used before range check | More results and fewer false positive results | The query now recognizes array accesses in different positions within the expression. False positives where the range is checked before and after the array access have been fixed. |
| Empty branch of conditional | Fewer false positive results | The query now recognizes commented blocks more reliably. |
| Expression has no effect | Fewer false positive results | Expressions in template instantiations are now excluded from this query. |
+| Global could be static | Fewer false positive results | Variables with declarations in header files are now excluded from this query. |
| Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. Also fixed an issue where false positives could occur if the destructor body was not in the snapshot. |
| Missing return statement (`cpp/missing-return`) | Visible by default | The precision of this query has been increased from 'medium' to 'high', which makes it visible by default in LGTM. It was 'medium' in release 1.17 and 1.18 because it had false positives due to an extractor bug that was fixed in 1.18. |
-| Missing return statement | Fewer false positive results | The query is now produces correct results when a function returns a template-dependent type. |
+| Missing return statement | Fewer false positive results | The query is now produces correct results when a function returns a template-dependent type, or makes a non-returning call to another function. |
+| Static array access may cause overflow | More correct results | Data flow to the size argument of a buffer operation is now checked in this query. |
| Call to memory access function may overflow buffer | More correct results | Array indexing with a negative index is now detected by this query. |
+| Self comparison | Fewer false positive results | Code inside macro invocations is now excluded from the query. |
| Suspicious call to memset | Fewer false positive results | Types involving decltype are now correctly compared. |
| Suspicious add with sizeof | Fewer false positive results | Arithmetic with void pointers (where allowed) is now excluded from this query. |
| Wrong type of arguments to formatting function | Fewer false positive results | False positive results involving typedefs have been removed. Expected argument types are determined more accurately, especially for wide string and pointer types. Custom (non-standard) formatting functions are also identified more accurately. |
+| AV Rule 164 | Fewer false positive results | This query now accounts for explicit casts. |
+| Negation of unsigned value | Fewer false positive results | This query now accounts for explicit casts. |
+| Variable scope too large | Fewer false positive results | Variables with declarations in header files, or that are used at file scope, are now excluded from this query. |
+| Comparison result is always the same | Fewer false positive results | Comparisons in template instantiations are now excluded from this query. |
+| Unsigned comparison to zero | Fewer false positive results | Comparisons in template instantiations are now excluded from this query. |
## Changes to QL libraries
diff --git a/change-notes/1.19/analysis-csharp.md b/change-notes/1.19/analysis-csharp.md
index f650fcc5813..d5ace2e7bff 100644
--- a/change-notes/1.19/analysis-csharp.md
+++ b/change-notes/1.19/analysis-csharp.md
@@ -29,3 +29,7 @@
* `getArgument()` on `AccessorCall` has been improved so it now takes tuple assignments into account. For example, the argument for the implicit `value` parameter in the setter of property `P` is `0` in `(P, x) = (0, 1)`. Additionally, the argument for the `value` parameter in compound assignments is now only the expanded value, for example, in `P += 7` the argument is `P + 7` and not `7`.
* The predicate `isInArgument()` has been added to the `AssignableAccess` class. This holds for expressions that are passed as arguments using `in`.
+
+## Changes to the autobuilder
+
+* When determining the target of `msbuild` or `dotnet build`, first look for `.proj` files, then `.sln` files, and finally `.csproj`/`.vcxproj` files. In all three cases, choose the project/solution file closest to the root.
diff --git a/change-notes/1.19/analysis-java.md b/change-notes/1.19/analysis-java.md
index 6458ff1d010..e9594966b6e 100644
--- a/change-notes/1.19/analysis-java.md
+++ b/change-notes/1.19/analysis-java.md
@@ -16,6 +16,7 @@
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
| Array index out of bounds (`java/index-out-of-bounds`) | Fewer false positive results | False positives involving arrays with a length evenly divisible by 3 or some greater number and an index being increased with a similar stride length are no longer reported. |
+| Confusing overloading of methods (`java/confusing-method-signature`) | Fewer false positive results | A bugfix in the inheritance relation ensures that spurious results on certain generic classes no longer occur. |
| Query built from user-controlled sources (`java/sql-injection`) | More results | Sql injection sinks from the Spring JDBC, MyBatis, and Hibernate frameworks are now reported. |
| Query built without neutralizing special characters (`java/concatenated-sql-query`) | More results | Sql injection sinks from the Spring JDBC, MyBatis, and Hibernate frameworks are now reported. |
| Unreachable catch clause (`java/unreachable-catch-clause`) | Fewer false positive results | This rule now accounts for calls to generic methods that throw generic exceptions. |
diff --git a/change-notes/1.19/analysis-javascript.md b/change-notes/1.19/analysis-javascript.md
index 63679cb0174..b45cb8ad8f7 100644
--- a/change-notes/1.19/analysis-javascript.md
+++ b/change-notes/1.19/analysis-javascript.md
@@ -4,8 +4,6 @@
* Modelling of taint flow through array operations has been improved. This may give additional results for the security queries.
-* The taint tracking library now recognizes additional sanitization patterns. This may give fewer false-positive results for the security queries.
-
* Support for AMD modules has been improved. This may give additional results for the security queries as well as any queries that use type inference on code bases that use such modules.
* Support for popular libraries has been improved. Consequently, queries may produce more results on code bases that use the following features:
@@ -13,6 +11,8 @@
- outbound network access, for example through the [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
- the [lodash](https://lodash.com), [underscore](https://underscorejs.org/), [async](https://www.npmjs.com/package/async) and [async-es](https://www.npmjs.com/package/async-es) libraries
+* The taint tracking library now recognizes additional sanitization patterns. This may give fewer false-positive results for the security queries.
+
* Type inference for function calls has been improved. This may give additional results for queries that rely on type inference.
* Where applicable, path explanations have been added to the security queries.
@@ -35,29 +35,38 @@
| **Query** | **Expected impact** | **Change** |
|--------------------------------|----------------------------|----------------------------------------------|
+| Ambiguous HTML id attribute | Lower severity | The severity of this rule has been revised to "warning". |
+| Clear-text logging of sensitive information | Fewer results | This rule now tracks flow more precisely. |
| Client side cross-site scripting | More results | This rule now also flags HTML injection in the body of an email. |
+| Client-side URL redirect | Fewer false-positive results | This rule now recognizes safe redirects in more cases. |
+| Conflicting HTML element attributes | Lower severity | The severity of this rule has been revised to "warning". |
+| Duplicate 'if' condition | Lower severity | The severity of this rule has been revised to "warning". |
+| Duplicate switch case | Lower severity | The severity of this rule has been revised to "warning". |
| Information exposure through a stack trace | More results | This rule now also flags cases where the entire exception object (including the stack trace) may be exposed. |
| Missing CSRF middleware | Fewer false-positive results | This rule now recognizes additional CSRF protection middlewares. |
+| Missing 'this' qualifier | Fewer false-positive results | This rule now recognizes additional intentional calls to global functions. |
+| Missing variable declaration | Lower severity | The severity of this rule has been revised to "warning". |
| Regular expression injection | Fewer false-positive results | This rule now identifies calls to `String.prototype.search` with more precision. |
| Remote property injection | Fewer results | The precision of this rule has been revised to "medium". Results are no longer shown on LGTM by default. |
| Self assignment | Fewer false-positive results | This rule now ignores self-assignments preceded by a JSDoc comment with a `@type` tag. |
+| Server-side URL redirect | Fewer false-positive results | This rule now recognizes safe redirects in more cases. |
| Server-side URL redirect | More results | This rule now recognizes redirection calls in more cases. |
| Unbound event handler receiver | Fewer false-positive results | This rule now recognizes additional ways class methods can be bound. |
| Uncontrolled data used in remote request | More results | This rule now recognizes additional kinds of requests. |
+| Unknown directive | Fewer false positives results | This rule now recognizes YUI compressor directives. |
| Unused import | Fewer false-positive results | This rule no longer flags imports used by the `transform-react-jsx` Babel plugin. |
| Unused variable, import, function or class | Fewer false-positive results | This rule now flags fewer variables that may be used by `eval` calls. |
| Unused variable, import, function or class | Fewer results | This rule now flags import statements with multiple unused imports once. |
| Useless assignment to local variable | Fewer false-positive results | This rule now recognizes additional ways default values can be set. |
| Whitespace contradicts operator precedence | Fewer false-positive results | This rule no longer flags operators with asymmetric whitespace. |
-| Client-side URL redirect | Fewer false-positive results | This rule now recognizes safe redirects in more cases. |
-| Server-side URL redirect | Fewer false-positive results | This rule now recognizes safe redirects in more cases. |
+| Wrong use of 'this' for static method | More results, fewer false-positive results | This rule now recognizes inherited methods. |
## Changes to QL libraries
-* The flow configuration framework now supports distinguishing and tracking different kinds of taint, specified by an extensible class `FlowLabel` (which can also be referred to by its alias `TaintKind`).
-
-* The `DataFlow::ThisNode` class now corresponds to the implicit receiver parameter of a function, as opposed to an indivdual `this` expression. This means `getALocalSource` now maps all `this` expressions within a given function to the same source. The data-flow node associated with a `ThisExpr` can no longer be cast to `DataFlow::SourceNode` or `DataFlow::ThisNode` - it is recomended to use `getALocalSource` before casting or instead of casting.
+* A `DataFlow::ParameterNode` instance now exists for all function parameters. Previously, unused parameters did not have a corresponding dataflow node.
* `ReactComponent::getAThisAccess` has been renamed to `getAThisNode`. The old name is still usable but is deprecated. It no longer gets individual `this` expressions, but the `ThisNode` mentioned above.
-* A `DataFlow::ParameterNode` instance now exists for all function parameters. Previously, unused parameters did not have a corresponding dataflow node.
+* The `DataFlow::ThisNode` class now corresponds to the implicit receiver parameter of a function, as opposed to an indivdual `this` expression. This means `getALocalSource` now maps all `this` expressions within a given function to the same source. The data-flow node associated with a `ThisExpr` can no longer be cast to `DataFlow::SourceNode` or `DataFlow::ThisNode` - it is recomended to use `getALocalSource` before casting or instead of casting.
+
+* The flow configuration framework now supports distinguishing and tracking different kinds of taint, specified by an extensible class `FlowLabel` (which can also be referred to by its alias `TaintKind`).
diff --git a/change-notes/1.19/extractor-javascript.md b/change-notes/1.19/extractor-javascript.md
index 4b8a4842892..8aa278e623c 100644
--- a/change-notes/1.19/extractor-javascript.md
+++ b/change-notes/1.19/extractor-javascript.md
@@ -16,8 +16,16 @@
## General improvements
-> Changes that affect alerts in many files or from many queries
-> For example, changes to file classification
+* On LGTM, files whose name ends in `.min.js` or `-min.js` are no longer extracted by default, since they most likely contain minified code and results in these files would be hidden by default anyway. To extract such files anyway, you can add the following filters to your `lgtm.yml` file (or add them to existing filters):
+
+```yaml
+extraction:
+ javascript:
+ index:
+ filters:
+ - include: "**/*.min.js"
+ - include: "**/*-min.js"
+```
## Changes to code extraction
diff --git a/cpp/ql/src/Architecture/General Top-Level Information/GeneralStatistics.qhelp b/cpp/ql/src/Architecture/General Top-Level Information/GeneralStatistics.qhelp
index a8230232c93..1bb15f10ed3 100644
--- a/cpp/ql/src/Architecture/General Top-Level Information/GeneralStatistics.qhelp
+++ b/cpp/ql/src/Architecture/General Top-Level Information/GeneralStatistics.qhelp
@@ -15,20 +15,9 @@ functions, and the total number of source code resp. comment lines.
depends on third-party libraries: low self-containedness means that many dependencies
are to library classes (as opposed to source classes within the same application).
-
-
-
The results of this query are purely informative and more useful for getting an overall impression of the application than for
-identifying particular defects.
+identifying particular problems with the code.
+
-
-
-
-
-
-
-
-
-
diff --git a/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql b/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql
index 872f01d4421..7a7e589fb34 100644
--- a/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql
+++ b/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql
@@ -5,6 +5,7 @@
* @kind problem
* @id cpp/offset-use-before-range-check
* @problem.severity warning
+ * @precision medium
* @tags reliability
* security
* external/cwe/cwe-120
@@ -13,10 +14,29 @@
import cpp
-from Variable v, LogicalAndExpr andexpr, ArrayExpr access, LTExpr rangecheck
-where access.getArrayOffset() = v.getAnAccess()
- and andexpr.getLeftOperand().getAChild() = access
- and andexpr.getRightOperand() = rangecheck
- and rangecheck.getLeftOperand() = v.getAnAccess()
- and not access.isInMacroExpansion()
+predicate beforeArrayAccess(Variable v, ArrayExpr access, Expr before) {
+ exists(LogicalAndExpr andexpr |
+ access.getArrayOffset() = v.getAnAccess() and
+ andexpr.getRightOperand().getAChild*() = access and
+ andexpr.getLeftOperand() = before
+ )
+}
+
+predicate afterArrayAccess(Variable v, ArrayExpr access, Expr after) {
+ exists(LogicalAndExpr andexpr |
+ access.getArrayOffset() = v.getAnAccess() and
+ andexpr.getLeftOperand().getAChild*() = access and
+ andexpr.getRightOperand() = after
+ )
+}
+
+from Variable v, ArrayExpr access, LTExpr rangecheck
+where
+ afterArrayAccess(v, access, rangecheck) and
+ rangecheck.getLeftOperand() = v.getAnAccess() and
+ not access.isInMacroExpansion() and
+ not exists(LTExpr altcheck |
+ beforeArrayAccess(v, access, altcheck) and
+ altcheck.getLeftOperand() = v.getAnAccess()
+ )
select access, "This use of offset '" + v.getName() + "' should follow the $@.", rangecheck, "range check"
diff --git a/cpp/ql/src/Best Practices/Magic Constants/MagicNumbersUseConstant.ql b/cpp/ql/src/Best Practices/Magic Constants/MagicNumbersUseConstant.ql
index 1a9852990ff..2c8ceac2753 100644
--- a/cpp/ql/src/Best Practices/Magic Constants/MagicNumbersUseConstant.ql
+++ b/cpp/ql/src/Best Practices/Magic Constants/MagicNumbersUseConstant.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/use-number-constant
* @problem.severity recommendation
+ * @precision low
+ * @tags maintainability
*/
import cpp
import MagicConstants
diff --git a/cpp/ql/src/Best Practices/Magic Constants/MagicStringsUseConstant.ql b/cpp/ql/src/Best Practices/Magic Constants/MagicStringsUseConstant.ql
index 990de6048e5..9cd129c88dc 100644
--- a/cpp/ql/src/Best Practices/Magic Constants/MagicStringsUseConstant.ql
+++ b/cpp/ql/src/Best Practices/Magic Constants/MagicStringsUseConstant.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/use-string-constant
* @problem.severity recommendation
+ * @precision low
+ * @tags maintainability
*/
import cpp
import MagicConstants
diff --git a/cpp/ql/src/Best Practices/NVI.ql b/cpp/ql/src/Best Practices/NVI.ql
index 5e5a20fd15a..723395769c3 100644
--- a/cpp/ql/src/Best Practices/NVI.ql
+++ b/cpp/ql/src/Best Practices/NVI.ql
@@ -4,7 +4,9 @@
* to enforce invariants that should hold for the whole hierarchy.
* @kind problem
* @id cpp/nvi
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @precision low
+ * @tags maintainability
*/
import cpp
diff --git a/cpp/ql/src/Best Practices/NVIHub.ql b/cpp/ql/src/Best Practices/NVIHub.ql
index 6d4600b68f9..a5e67a2cbee 100644
--- a/cpp/ql/src/Best Practices/NVIHub.ql
+++ b/cpp/ql/src/Best Practices/NVIHub.ql
@@ -4,8 +4,11 @@
* to enforce invariants that should hold for the whole hierarchy.
* This is especially problematic in classes with many
* dependencies or dependents.
- * @kind table
+ * @kind problem
* @id cpp/nvi-hub
+ * @problem.severity recommendation
+ * @precision low
+ * @tags maintainability
*/
import cpp
@@ -19,4 +22,4 @@ where f.hasSpecifier("public") and
fclass = f.getDeclaringType() and
hubIndex = fclass.getMetrics().getAfferentCoupling() * fclass.getMetrics().getEfferentCoupling() and
hubIndex > 100
-select f.getFile(), f, "Avoid having public virtual methods (NVI idiom)"
+select f, "Avoid having public virtual methods (NVI idiom)"
diff --git a/cpp/ql/src/Best Practices/Unused Entities/UnusedIncludes.ql b/cpp/ql/src/Best Practices/Unused Entities/UnusedIncludes.ql
index c8480a037b6..42d5d910fb7 100644
--- a/cpp/ql/src/Best Practices/Unused Entities/UnusedIncludes.ql
+++ b/cpp/ql/src/Best Practices/Unused Entities/UnusedIncludes.ql
@@ -4,7 +4,10 @@
* the included elements are used.
* @kind problem
* @id cpp/unused-includes
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @precision low
+ * @tags maintainability
+ * useless-code
*/
import cpp
diff --git a/cpp/ql/src/Critical/OverflowStatic.ql b/cpp/ql/src/Critical/OverflowStatic.ql
index e8503d3a25d..386212cb676 100644
--- a/cpp/ql/src/Critical/OverflowStatic.ql
+++ b/cpp/ql/src/Critical/OverflowStatic.ql
@@ -82,22 +82,31 @@ class CallWithBufferSize extends FunctionCall
Expr buffer() {
exists(int i |
bufferAndSizeFunction(this.getTarget(), i, _) and
- result = this.getArgument(i))
+ result = this.getArgument(i)
+ )
}
- Expr statedSize() {
+ Expr statedSizeExpr() {
exists(int i |
bufferAndSizeFunction(this.getTarget(), _, i) and
- result = this.getArgument(i))
+ result = this.getArgument(i)
+ )
+ }
+ int statedSizeValue() {
+ exists(Expr statedSizeSrc |
+ DataFlow::localFlow(DataFlow::exprNode(statedSizeSrc), DataFlow::exprNode(statedSizeExpr())) and
+ result = statedSizeSrc.getValue().toInt()
+ )
}
}
predicate wrongBufferSize(Expr error, string msg) {
- exists(CallWithBufferSize call, int bufsize, Variable buf |
+ exists(CallWithBufferSize call, int bufsize, Variable buf, int statedSize |
staticBuffer(call.buffer(), buf, bufsize) and
- call.statedSize().getValue().toInt() > bufsize and
- error = call.statedSize() and
+ statedSize = min(call.statedSizeValue()) and
+ statedSize > bufsize and
+ error = call.statedSizeExpr() and
msg = "Potential buffer-overflow: '" + buf.getName() +
- "' has size " + bufsize.toString() + " not " + call.statedSize().getValue() + ".")
+ "' has size " + bufsize.toString() + " not " + statedSize + ".")
}
predicate outOfBounds(BufferAccess bufaccess, string msg)
diff --git a/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFile.ql b/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFile.ql
index a895174e215..8367fb996fe 100644
--- a/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFile.ql
+++ b/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFile.ql
@@ -12,5 +12,6 @@ from GlobalVariable v
where forex(VariableAccess va | va.getTarget() = v | va.getFile() = v.getDefinitionLocation().getFile())
and not v.hasSpecifier("static")
and strictcount(v.getAnAccess().getEnclosingFunction()) > 1 // If = 1, variable should be function-scope.
+ and not v.getADeclarationEntry().getFile() instanceof HeaderFile // intended to be accessed elsewhere
select v, "The global variable " + v.getName() + " is not accessed outside of " + v.getFile().getBaseName()
+ " and could be made static."
diff --git a/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql b/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql
index 40fa3b48a2d..b54e824be05 100644
--- a/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql
+++ b/cpp/ql/src/JPL_C/LOC-3/Rule 13/LimitedScopeFunction.ql
@@ -10,5 +10,7 @@ import cpp
from GlobalVariable v, Function f
where v.getAnAccess().getEnclosingFunction() = f and
- strictcount(v.getAnAccess().getEnclosingFunction()) = 1
+ strictcount(v.getAnAccess().getEnclosingFunction()) = 1 and
+ forall(VariableAccess a | a = v.getAnAccess() | exists(a.getEnclosingFunction())) and
+ not v.getADeclarationEntry().getFile() instanceof HeaderFile // intended to be accessed elsewhere
select v, "The variable " + v.getName() + " is only accessed in $@ and should be scoped accordingly.", f, f.getName()
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql
index 4d0b4184e1d..9671508449a 100644
--- a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql
@@ -18,4 +18,12 @@ from ComparisonOperation cmp
where pointlessSelfComparison(cmp)
and not nanTest(cmp)
and not overflowTest(cmp)
+ and not exists(MacroInvocation mi |
+ // cmp is in mi
+ mi.getAnExpandedElement() = cmp and
+
+ // and cmp was apparently not passed in as a macro parameter
+ cmp.getLocation().getStartLine() = mi.getLocation().getStartLine() and
+ cmp.getLocation().getStartColumn() = mi.getLocation().getStartColumn()
+ )
select cmp, "Self comparison."
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Padding/More64BitWaste.ql b/cpp/ql/src/Likely Bugs/Memory Management/Padding/More64BitWaste.ql
index c82d86aadfd..da5be6e494f 100644
--- a/cpp/ql/src/Likely Bugs/Memory Management/Padding/More64BitWaste.ql
+++ b/cpp/ql/src/Likely Bugs/Memory Management/Padding/More64BitWaste.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/more-64-bit-waste
* @problem.severity warning
+ * @tags maintainability
+ * portability
*/
import semmle.code.cpp.padding.Padding
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Padding/NonPortablePrintf.ql b/cpp/ql/src/Likely Bugs/Memory Management/Padding/NonPortablePrintf.ql
index 95383e86fa5..1c1bce79457 100644
--- a/cpp/ql/src/Likely Bugs/Memory Management/Padding/NonPortablePrintf.ql
+++ b/cpp/ql/src/Likely Bugs/Memory Management/Padding/NonPortablePrintf.ql
@@ -5,6 +5,8 @@
* @kind problem
* @id cpp/non-portable-printf
* @problem.severity warning
+ * @tags maintainability
+ * portability
*/
import cpp
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Padding/Suboptimal64BitType.ql b/cpp/ql/src/Likely Bugs/Memory Management/Padding/Suboptimal64BitType.ql
index 8578324883a..1f52a265d0a 100644
--- a/cpp/ql/src/Likely Bugs/Memory Management/Padding/Suboptimal64BitType.ql
+++ b/cpp/ql/src/Likely Bugs/Memory Management/Padding/Suboptimal64BitType.ql
@@ -4,7 +4,8 @@
* that by reordering them one could reduce the amount of internal padding on a 64-bit architecture.
* @kind problem
* @id cpp/suboptimal-64-bit-type
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags efficiency
*/
import semmle.code.cpp.padding.Padding
diff --git a/cpp/ql/src/Metrics/History/HChurn.ql b/cpp/ql/src/Metrics/History/HChurn.ql
index 40b4459caca..dc1f89b0e69 100644
--- a/cpp/ql/src/Metrics/History/HChurn.ql
+++ b/cpp/ql/src/Metrics/History/HChurn.ql
@@ -7,6 +7,7 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg sum max
+ * @deprecated
*/
import cpp
import external.VCS
diff --git a/cpp/ql/src/Metrics/History/HLinesAdded.ql b/cpp/ql/src/Metrics/History/HLinesAdded.ql
index 1a9fcc301e3..88d8565a4a3 100644
--- a/cpp/ql/src/Metrics/History/HLinesAdded.ql
+++ b/cpp/ql/src/Metrics/History/HLinesAdded.ql
@@ -7,6 +7,7 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg sum max
+ * @deprecated
*/
import cpp
import external.VCS
diff --git a/cpp/ql/src/Metrics/History/HLinesDeleted.ql b/cpp/ql/src/Metrics/History/HLinesDeleted.ql
index 72e54706056..b6851ce7e0e 100644
--- a/cpp/ql/src/Metrics/History/HLinesDeleted.ql
+++ b/cpp/ql/src/Metrics/History/HLinesDeleted.ql
@@ -7,6 +7,7 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg sum max
+ * @deprecated
*/
import cpp
import external.VCS
diff --git a/cpp/ql/src/Metrics/History/HNumberOfAuthors.ql b/cpp/ql/src/Metrics/History/HNumberOfAuthors.ql
index 1da244ff31a..cce61f855f0 100644
--- a/cpp/ql/src/Metrics/History/HNumberOfAuthors.ql
+++ b/cpp/ql/src/Metrics/History/HNumberOfAuthors.ql
@@ -6,6 +6,7 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg min max
+ * @deprecated
*/
import cpp
import external.VCS
diff --git a/cpp/ql/src/Metrics/History/HNumberOfChanges.ql b/cpp/ql/src/Metrics/History/HNumberOfChanges.ql
index e3b2396662c..adb553c0d39 100644
--- a/cpp/ql/src/Metrics/History/HNumberOfChanges.ql
+++ b/cpp/ql/src/Metrics/History/HNumberOfChanges.ql
@@ -7,6 +7,7 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg min max sum
+ * @deprecated
*/
import cpp
import external.VCS
diff --git a/cpp/ql/src/Metrics/History/HNumberOfCoCommits.ql b/cpp/ql/src/Metrics/History/HNumberOfCoCommits.ql
index 66dd1607163..e9547a58eab 100644
--- a/cpp/ql/src/Metrics/History/HNumberOfCoCommits.ql
+++ b/cpp/ql/src/Metrics/History/HNumberOfCoCommits.ql
@@ -7,6 +7,7 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg min max
+ * @deprecated
*/
import cpp
import external.VCS
diff --git a/cpp/ql/src/Metrics/History/HNumberOfReCommits.ql b/cpp/ql/src/Metrics/History/HNumberOfReCommits.ql
index de958ad32b5..31edabbaad2 100644
--- a/cpp/ql/src/Metrics/History/HNumberOfReCommits.ql
+++ b/cpp/ql/src/Metrics/History/HNumberOfReCommits.ql
@@ -7,6 +7,7 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg min max
+ * @deprecated
*/
import cpp
import external.VCS
diff --git a/cpp/ql/src/Metrics/History/HNumberOfRecentAuthors.ql b/cpp/ql/src/Metrics/History/HNumberOfRecentAuthors.ql
index c912897f404..5237b9e63aa 100644
--- a/cpp/ql/src/Metrics/History/HNumberOfRecentAuthors.ql
+++ b/cpp/ql/src/Metrics/History/HNumberOfRecentAuthors.ql
@@ -7,6 +7,7 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg min max
+ * @deprecated
*/
import cpp
import external.VCS
diff --git a/cpp/ql/src/Metrics/History/HNumberOfRecentChangedFiles.ql b/cpp/ql/src/Metrics/History/HNumberOfRecentChangedFiles.ql
index 8009356cde9..ecf2ee48581 100644
--- a/cpp/ql/src/Metrics/History/HNumberOfRecentChangedFiles.ql
+++ b/cpp/ql/src/Metrics/History/HNumberOfRecentChangedFiles.ql
@@ -6,6 +6,7 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg min max sum
+ * @deprecated
*/
import cpp
import external.VCS
diff --git a/cpp/ql/src/Metrics/History/HNumberOfRecentChanges.ql b/cpp/ql/src/Metrics/History/HNumberOfRecentChanges.ql
index 2ce984f40a1..e8f64e4f0a4 100644
--- a/cpp/ql/src/Metrics/History/HNumberOfRecentChanges.ql
+++ b/cpp/ql/src/Metrics/History/HNumberOfRecentChanges.ql
@@ -6,6 +6,7 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg min max sum
+ * @deprecated
*/
import cpp
import external.VCS
diff --git a/cpp/ql/src/Power of 10/Rule 6/GlobalCouldBeStatic.ql b/cpp/ql/src/Power of 10/Rule 6/GlobalCouldBeStatic.ql
index ea3f09d1161..4335bf18cc4 100644
--- a/cpp/ql/src/Power of 10/Rule 6/GlobalCouldBeStatic.ql
+++ b/cpp/ql/src/Power of 10/Rule 6/GlobalCouldBeStatic.ql
@@ -12,5 +12,6 @@ from GlobalVariable v
where forex(VariableAccess va | va.getTarget() = v | va.getFile() = v.getDefinitionLocation().getFile())
and not v.hasSpecifier("static")
and strictcount(v.getAnAccess().getEnclosingFunction()) > 1 // If = 1, variable should be function-scope.
+ and not v.getADeclarationEntry().getFile() instanceof HeaderFile // intended to be accessed elsewhere
select v, "The global variable " + v.getName() + " is not accessed outside of " + v.getFile().getBaseName() +
" and could be made static."
diff --git a/cpp/ql/src/Power of 10/Rule 6/VariableScopeTooLarge.ql b/cpp/ql/src/Power of 10/Rule 6/VariableScopeTooLarge.ql
index b6358d41c82..87c0e20e92c 100644
--- a/cpp/ql/src/Power of 10/Rule 6/VariableScopeTooLarge.ql
+++ b/cpp/ql/src/Power of 10/Rule 6/VariableScopeTooLarge.ql
@@ -10,5 +10,7 @@ import cpp
from GlobalVariable v, Function f
where v.getAnAccess().getEnclosingFunction() = f and
- strictcount(v.getAnAccess().getEnclosingFunction()) = 1
+ strictcount(v.getAnAccess().getEnclosingFunction()) = 1 and
+ forall(VariableAccess a | a = v.getAnAccess() | exists(a.getEnclosingFunction())) and
+ not v.getADeclarationEntry().getFile() instanceof HeaderFile // intended to be accessed elsewhere
select v, "The variable " + v.getName() + " is only accessed in $@ and should be scoped accordingly.", f, f.getName()
diff --git a/cpp/ql/src/external/tests/DefectFilter.ql b/cpp/ql/src/external/tests/DefectFilter.ql
index 7c9459f64ce..de372930845 100644
--- a/cpp/ql/src/external/tests/DefectFilter.ql
+++ b/cpp/ql/src/external/tests/DefectFilter.ql
@@ -4,7 +4,6 @@
*/
import cpp
import external.DefectFilter
-import external.VCS
from DefectResult res
where res.getFile().getMetrics().getNumberOfLinesOfCode() > 200
diff --git a/cpp/ql/src/external/tests/DefectFromSVN.ql b/cpp/ql/src/external/tests/DefectFromSVN.ql
index f58a6482ebc..863205834a2 100644
--- a/cpp/ql/src/external/tests/DefectFromSVN.ql
+++ b/cpp/ql/src/external/tests/DefectFromSVN.ql
@@ -3,6 +3,7 @@
* @description A test case for creating a defect from SVN data.
* @kind problem
* @problem.severity warning
+ * @deprecated
*/
import cpp
diff --git a/cpp/ql/src/external/tests/MetricFromSVN.ql b/cpp/ql/src/external/tests/MetricFromSVN.ql
index 32d27c7deaf..86d26323056 100644
--- a/cpp/ql/src/external/tests/MetricFromSVN.ql
+++ b/cpp/ql/src/external/tests/MetricFromSVN.ql
@@ -3,6 +3,7 @@
* @description Find number of commits for a file
* @treemap.warnOn lowValues
* @metricType file
+ * @deprecated
*/
import cpp
diff --git a/cpp/ql/src/filters/RecentDefects.ql b/cpp/ql/src/filters/RecentDefects.ql
index cf904d602ad..04c7afd0487 100644
--- a/cpp/ql/src/filters/RecentDefects.ql
+++ b/cpp/ql/src/filters/RecentDefects.ql
@@ -6,6 +6,7 @@
* before the date of the snapshot.
* @kind problem
* @id cpp/recent-defects-filter
+ * @deprecated
*/
import cpp
import external.DefectFilter
diff --git a/cpp/ql/src/filters/RecentDefectsForMetric.ql b/cpp/ql/src/filters/RecentDefectsForMetric.ql
index 29515538388..00317d41750 100644
--- a/cpp/ql/src/filters/RecentDefectsForMetric.ql
+++ b/cpp/ql/src/filters/RecentDefectsForMetric.ql
@@ -6,6 +6,7 @@
* before the snapshot.
* @kind treemap
* @id cpp/recent-defects-for-metric-filter
+ * @deprecated
*/
import cpp
import external.MetricFilter
diff --git a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql
index 5d7c1324319..e4f6524ae5f 100644
--- a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql
+++ b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 1.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-1
* @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql
index 81441a548fc..cf1b952e17c 100644
--- a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql
+++ b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 2.ql
@@ -4,6 +4,10 @@
* @kind problem
* @id cpp/jsf/av-rule-2
* @problem.severity error
+ * @tags maintainability
+ * readability
+ * testability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql
index 41aea8836d7..60f8cf8616f 100644
--- a/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql
+++ b/cpp/ql/src/jsf/3.02 Code Size and Complexity/AV Rule 3.ql
@@ -3,7 +3,9 @@
* @description All functions shall have a cyclomatic complexity number of 20 or less.
* @kind problem
* @id cpp/jsf/av-rule-3
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql
index c7ff2e29cd5..ac46a454101 100644
--- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql
+++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 11.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-11
* @problem.severity warning
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
import external.ExternalArtifact
diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql
index 704a605f7ad..b3460c5bc5f 100644
--- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql
+++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 12.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-12
* @problem.severity warning
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql
index 1eeb9f0ef3e..6d03cd712aa 100644
--- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql
+++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 13.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-13
* @problem.severity error
+ * @tags maintainability
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql
index f9da62380f6..792383baf77 100644
--- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql
+++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 14.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-14
* @problem.severity error
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql b/cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql
index 5ac20cfc5a6..9df1b72a736 100644
--- a/cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql
+++ b/cpp/ql/src/jsf/4.04 Environment/AV Rule 9.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-9
* @problem.severity warning
+ * @tags maintainability
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql
index 30a36d0ad96..520cb67a622 100644
--- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql
+++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 17.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-17
* @problem.severity error
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql
index 8045b2bb604..a9eeb2e6639 100644
--- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql
+++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 18.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-18
* @problem.severity error
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql
index ea4885b13a3..414ba2e969f 100644
--- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql
+++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 19.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-19
* @problem.severity error
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql
index f5658511c13..fed2482a56c 100644
--- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql
+++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 20.ql
@@ -4,6 +4,10 @@
* @kind problem
* @id cpp/jsf/av-rule-20
* @problem.severity error
+ * @tags correctness
+ * portability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql
index 388a717eebb..8d3ed394737 100644
--- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql
+++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 21.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-21
* @problem.severity error
+ * @tags correctness
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql
index 4a8f075a7bd..8a1cb164e93 100644
--- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql
+++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 22.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-22
* @problem.severity error
+ * @tags maintainability
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql
index 62b3b4c6539..1c0c84c7cdd 100644
--- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql
+++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 23.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-23
* @problem.severity error
+ * @tags correctness
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql
index 1cec97180f7..42e456e3dd6 100644
--- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql
+++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 24.ql
@@ -4,7 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-24
* @problem.severity warning
- * @tags portability
+ * @tags correctness
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql
index 659afa17cf4..09df5fa8b56 100644
--- a/cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql
+++ b/cpp/ql/src/jsf/4.05 Libraries/AV Rule 25.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-25
* @problem.severity error
+ * @tags correctness
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql
index 095b7ecb80a..9561f452cd3 100644
--- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql
+++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 26.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-26
* @problem.severity error
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql
index 43b483caa48..1aed7ddab59 100644
--- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql
+++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 27.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-27
* @problem.severity warning
+ * @tags maintainability
+ * portability
+ * external/jsf
*/
import cpp
import semmle.code.cpp.headers.MultipleInclusion
diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql
index 8b044fdfc0e..9d22ab3c340 100644
--- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql
+++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 28.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-28
* @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
import semmle.code.cpp.headers.MultipleInclusion
diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql
index c6229e118b6..f3dc2a2e87f 100644
--- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql
+++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 29.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-29
* @problem.severity error
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql
index dff8e58367b..ceedac6112f 100644
--- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql
+++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 30.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-30
* @problem.severity error
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql
index 74b5eb9697b..9c8f389cf3f 100644
--- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql
+++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 31.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-31
* @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
import semmle.code.cpp.headers.MultipleInclusion
diff --git a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql
index 9dd2e5bfc22..59fef7909e0 100644
--- a/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql
+++ b/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql
@@ -7,6 +7,8 @@
* @id cpp/include-non-header
* @tags maintainability
* modularity
+ * readability
+ * external/jsf
*/
import cpp
import semmle.code.cpp.AutogeneratedFile
diff --git a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql
index bdf802a85f7..2b416c4ce21 100644
--- a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql
+++ b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 33.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-33
* @problem.severity error
+ * @tags maintainability
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql
index 1f1ddef6a9c..b3b9dc19a95 100644
--- a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql
+++ b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql
@@ -10,6 +10,7 @@
* @tags efficiency
* maintainability
* modularity
+ * external/jsf
*/
import cpp
import semmle.code.cpp.headers.MultipleInclusion
diff --git a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql
index 4a38b3807b6..0bf35a35f17 100644
--- a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql
+++ b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 39.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-39
* @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql b/cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql
index fbc24554547..9ca933383df 100644
--- a/cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql
+++ b/cpp/ql/src/jsf/4.08 Implementation Files/AV Rule 40.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-40
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql
index e3f6ce995c1..7167bb59cd5 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 41.ql
@@ -3,7 +3,10 @@
* @description Source lines will be kept to a length of 120 characters or less.
* @kind problem
* @id cpp/jsf/av-rule-41
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql
index 170ed0a4458..e7058321347 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 42.ql
@@ -3,7 +3,10 @@
* @description Each expression-statement will be on a separate line.
* @kind problem
* @id cpp/jsf/av-rule-42
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql
index c2094226871..ef9d5fbd748 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 43.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-43
* @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql
index 7b842e4edd7..540434cb718 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 44.ql
@@ -3,7 +3,10 @@
* @description All indentations will be at least two spaces and be consistent within the same source file.
* @kind problem
* @id cpp/jsf/av-rule-44
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql
index 79bdad085b8..b022760d806 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 45.ql
@@ -3,7 +3,10 @@
* @description All words in an identifier will be separated by the underscore character.
* @kind problem
* @id cpp/jsf/av-rule-45
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql
index 4511cbfe1f0..841b32df310 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 46.ql
@@ -3,7 +3,10 @@
* @description User-specified identifiers (internal and external) will not rely on significance of more than 64 characters.
* @kind problem
* @id cpp/jsf/av-rule-46
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql
index 49255f8347f..fb36adf66a9 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 47.ql
@@ -3,7 +3,9 @@
* @description Identifiers will not begin with the underscore character.
* @kind problem
* @id cpp/jsf/av-rule-47
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql
index 890245aafcd..1a900733330 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 48.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-48
* @problem.severity warning
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql
index 68301d12c27..e422ee217fe 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 49.ql
@@ -3,7 +3,10 @@
* @description All acronyms in an identifier will be composed of uppercase letters.
* @kind problem
* @id cpp/jsf/av-rule-49
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
import Naming
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql
index 5ead6fe0236..ca45954eeb6 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 50.ql
@@ -3,7 +3,10 @@
* @description The first word of the name of a class, structure, namespace, enumeration, or type created with typedef will begin with an uppercase letter. All other letters will be lowercase.
* @kind problem
* @id cpp/jsf/av-rule-50
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
import Naming
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql
index 346e9c3ee4c..e6fe9828e88 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 51.ql
@@ -3,7 +3,10 @@
* @description All letters contained in function and variable names will be lowercase.
* @kind problem
* @id cpp/jsf/av-rule-51
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
import Naming
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql
index 93218392e92..3c1d3631843 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 52.ql
@@ -3,7 +3,10 @@
* @description Identifiers for constant and enumerator values shall be lowercase.
* @kind problem
* @id cpp/jsf/av-rule-52
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
import Naming
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql
index 77953c40c6d..d70e7ff48bc 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql
@@ -3,7 +3,10 @@
* @description The following character sequences shall not appear in header file names: ', \, /*, //, or ".
* @kind problem
* @id cpp/jsf/av-rule-53-1
- * @problem.severity error
+ * @problem.severity warning
+ * @tags maintainability
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql
index 862d9028de3..b5f2d223951 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.ql
@@ -3,7 +3,10 @@
* @description Header files will always have a file name extension of .h.
* @kind problem
* @id cpp/jsf/av-rule-53
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql
index cb40d30d51d..d7f10a88e57 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 54.ql
@@ -3,7 +3,10 @@
* @description Implementation files will always have a file name extension of .cpp.
* @kind problem
* @id cpp/jsf/av-rule-54
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql
index 2c205cc009f..fe629ce5a4c 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 57.ql
@@ -3,7 +3,10 @@
* @description The public, protected, and private sections of a class will be declared in that order.
* @kind problem
* @id cpp/jsf/av-rule-57
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql
index 08a6e2c81b3..80b6ec08004 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 58.ql
@@ -3,7 +3,10 @@
* @description When declaring and defining functions with more than two parameters, the leading parenthesis and the first argument will be written on the same line as the function name. Each additional argument will be written on a separate line (with the closing parenthesis directly after the last argument).
* @kind problem
* @id cpp/jsf/av-rule-58
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql
index ca598d20b2e..6baf82e3b32 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql
@@ -3,7 +3,10 @@
* @description The statements forming the body of an if, else if, else, while, do-while or for statement shall always be enclosed in braces, even if the braces form an empty block.
* @kind problem
* @id cpp/jsf/av-rule-59
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql
index 206eb7c5d99..c1b2729aec2 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 60.ql
@@ -3,7 +3,10 @@
* @description Braces which enclose a block will be placed in the same column, on separate lines directly before and after the block.
* @kind problem
* @id cpp/jsf/av-rule-60
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql
index e31e844a3a5..feee51df3de 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 61.ql
@@ -3,7 +3,10 @@
* @description Braces which enclose a block will have nothing else on the line except comments (if necessary).
* @kind problem
* @id cpp/jsf/av-rule-61
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql
index 2f65ce9ec83..4fa3ac5b8f0 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 63.ql
@@ -3,7 +3,10 @@
* @description Spaces will not be used around '.' or '->', nor between unary operators and operands.
* @kind problem
* @id cpp/jsf/av-rule-63
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql
index 1ef9a49bb23..bfe52e65a65 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 68.ql
@@ -3,7 +3,9 @@
* @description Unneeded implicitly generated member functions shall be explicitly disallowed.
* @kind problem
* @id cpp/jsf/av-rule-68
- * @problem.severity error
+ * @problem.severity warning
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql
index 1daec9c9cec..3f9b23311aa 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 69.ql
@@ -5,6 +5,8 @@
* @kind problem
* @id cpp/jsf/av-rule-69
* @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql
index af544ae4610..1e08577217d 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 70.ql
@@ -5,7 +5,9 @@
* for logical or efficiency reasons.
* @kind problem
* @id cpp/jsf/av-rule-70
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql
index 354c165a5e9..01a6195c88e 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql
@@ -8,6 +8,7 @@
* @tags reliability
* readability
* language-features
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql
index 8a1cc05eb72..2b0159e6452 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-71
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql
index 2cce8b26646..4d7025d38a5 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 73.ql
@@ -3,8 +3,10 @@
* @description Unnecessary default constructors shall not be defined.
* @kind problem
* @id cpp/jsf/av-rule-73
- * @problem.severity error
+ * @problem.severity recommendation
* @precision low
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql
index 7828fc02849..d0ec52033c1 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 74.ql
@@ -6,6 +6,8 @@
* @kind problem
* @id cpp/jsf/av-rule-74
* @problem.severity warning
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql
index ba78dec6486..c16f09dbb93 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 75.ql
@@ -3,7 +3,10 @@
* @description Members of the initialization list shall be listed in the order in which they are declared in the class.
* @kind problem
* @id cpp/jsf/av-rule-75
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql
index 9ab2a892b65..b065b75aed3 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 76.ql
@@ -3,7 +3,9 @@
* @description A copy constructor and an assignment operator shall be declared for classes that contain pointers to data items or nontrivial destructors. If the copy constructor and assignment operators are not required, they should be explicitly disallowed.
* @kind problem
* @id cpp/jsf/av-rule-76
- * @problem.severity error
+ * @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 77.1.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 77.1.ql
index c268d3c4f7f..0b847e795c6 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 77.1.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 77.1.ql
@@ -8,6 +8,7 @@
* @tags reliability
* readability
* language-features
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql
index 04a69db8ddd..5c05abec0cd 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 78.ql
@@ -3,11 +3,11 @@
* @description All base classes with a virtual function should define a virtual destructor. If an application attempts to delete a derived class object through a base class pointer, the result is undefined if the base class destructor is non-virtual.
* @kind problem
* @problem.severity warning
- * @precision high
* @id cpp/jsf/av-rule-78
* @tags reliability
* readability
* language-features
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
index 6ad499a8337..1b2f4080992 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
@@ -8,6 +8,7 @@
* @tags efficiency
* readability
* external/cwe/cwe-404
+ * external/jsf
*/
import cpp
import Critical.NewDelete
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql
index a6bba73ebd4..c16da4309a5 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 81.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-81
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 82.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 82.ql
index 47d95e14eca..4624cd29931 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 82.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 82.ql
@@ -8,6 +8,7 @@
* @tags reliability
* readability
* language-features
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql
index 6ea435afe94..4f81c6518c1 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql
@@ -4,7 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-85
* @problem.severity warning
- * @tags reliability
+ * @tags maintainability
+ * reliability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql
index a96697f1e5c..90efc3cba0f 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.1.ql
@@ -3,7 +3,9 @@
* @description A stateful virtual base shall be explicitly declared in each derived class that accesses it. Explicitly declaring a stateful virtual base at each level in a hierarchy (where that base is used), documents that fact that no assumptions can be made with respect to the exclusive use of the data contained within the virtual base.
* @kind problem
* @id cpp/jsf/av-rule-88-1
- * @problem.severity error
+ * @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql
index 0bc3b17177b..bbd39779744 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 88.ql
@@ -5,7 +5,9 @@
* @problem.severity recommendation
* @precision high
* @id cpp/undisciplined-multiple-inheritance
- * @tags readability
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 89.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 89.ql
index 7e39363e838..53d6b95b011 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 89.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 89.ql
@@ -7,6 +7,7 @@
* @id cpp/inconsistent-virtual-inheritance
* @tags maintainability
* readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql
index 1bf0465486a..68b6c7fd506 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 94.ql
@@ -3,7 +3,9 @@
* @description An inherited nonvirtual function shall not be redefined in a derived class. Such definitions would hide the function in the base class.
* @kind problem
* @id cpp/jsf/av-rule-94
- * @problem.severity error
+ * @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 95.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 95.ql
index a43c7b56a3b..f32fe58f0be 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 95.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 95.ql
@@ -7,6 +7,7 @@
* @id cpp/redefined-default-parameter
* @tags maintainability
* readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql
index d577b649df8..839625f4d2c 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 96.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-96
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql
index 455add085d5..02d0f169245 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.1.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-97-1
* @problem.severity error
+ * @tags correctness
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql
index 256b1174ccb..781e3c922d3 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql
@@ -8,6 +8,7 @@
* @tags reliability
* readability
* language-features
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql b/cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql
index 920853145fc..4d4713026f1 100644
--- a/cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql
+++ b/cpp/ql/src/jsf/4.11 Namespaces/AV Rule 99.ql
@@ -3,7 +3,10 @@
* @description Namespaces will not be nested more than two levels deep
* @kind problem
* @id cpp/jsf/av-rule-99
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql b/cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql
index 2c4037770ba..a88a8f165e9 100644
--- a/cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql
+++ b/cpp/ql/src/jsf/4.12 Templates/AV Rule 104.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-104
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 107.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 107.ql
index 22341330150..a92a3d268f8 100644
--- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 107.ql
+++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 107.ql
@@ -7,6 +7,7 @@
* @id cpp/function-in-block
* @tags maintainability
* readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql
index 1ece9be6fe8..b463e51afa7 100644
--- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql
+++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 108.ql
@@ -3,7 +3,9 @@
* @description Functions with variable number of arguments shall not be used.
* @kind problem
* @id cpp/jsf/av-rule-108
- * @problem.severity error
+ * @problem.severity warning
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql
index 16e24b9697b..9afa55ee4ca 100644
--- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql
+++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 110.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-110
* @problem.severity warning
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql
index edc3f8c646d..6e6d8004a1c 100644
--- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql
+++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql
@@ -4,7 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-111
* @problem.severity error
- * @tags reliability
+ * @tags correctness
+ * reliability
+ * external/jsf
*/
import semmle.code.cpp.pointsto.PointsTo
diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql
index 938e8b3a81e..ca934aa84e1 100644
--- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql
+++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 113.ql
@@ -3,7 +3,9 @@
* @description Functions will have a single exit point.
* @kind problem
* @id cpp/jsf/av-rule-113
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql
index 600d4a6abf0..e4a79d378f5 100644
--- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql
+++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql
@@ -8,6 +8,7 @@
* @tags reliability
* readability
* language-features
+ * external/jsf
*/
import cpp
@@ -38,6 +39,8 @@ predicate functionImperfectlyExtracted(Function f) {
exists(CompilerError e | f.getBlock().getLocation().subsumes(e.getLocation()))
or
exists(ErrorExpr ee | ee.getEnclosingFunction() = f)
+ or
+ count(f.getType()) > 1
}
from Stmt stmt, string msg, Function f, ControlFlowNode blame
diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql
index af81266e1d8..2cec08f027b 100644
--- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql
+++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 115.ql
@@ -5,6 +5,8 @@
* @kind problem
* @id cpp/jsf/av-rule-115
* @problem.severity warning
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql
index e45afd24880..3e365d28ddf 100644
--- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql
+++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 119.ql
@@ -3,7 +3,9 @@
* @description Functions shall not call themselves, either directly or indirectly (i.e. recursion shall not be allowed).
* @kind problem
* @id cpp/jsf/av-rule-119
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags resources
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql b/cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql
index 975489f30f2..bc0a6a4be1d 100644
--- a/cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql
+++ b/cpp/ql/src/jsf/4.14 Comments/AV Rule 126.ql
@@ -3,7 +3,10 @@
* @description Only valid C++ style comments shall be used.
* @kind problem
* @id cpp/jsf/av-rule-126
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * documentation
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql b/cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql
index e8dfa01e54d..663efcc5bcd 100644
--- a/cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql
+++ b/cpp/ql/src/jsf/4.14 Comments/AV Rule 127.ql
@@ -3,7 +3,9 @@
* @description Code that is not used (commented out) shall be deleted.
* @kind problem
* @id cpp/jsf/av-rule-127
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql b/cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql
index 6de8e990e3e..94026501130 100644
--- a/cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql
+++ b/cpp/ql/src/jsf/4.14 Comments/AV Rule 133.ql
@@ -3,7 +3,10 @@
* @description Every source file will be documented with an introductory comment that provides information on the file name, its contents, and any program-required information (eg. legal statements, copyright information, etc)
* @kind problem
* @id cpp/jsf/av-rule-133
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * documentation
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql
index d5fb20d4883..b7561398468 100644
--- a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql
+++ b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql
@@ -5,6 +5,7 @@
* @id cpp/jsf/av-rule-135
* @problem.severity recommendation
* @tags maintainability
+ * external/jsf
*/
import cpp
import Best_Practices.Hiding.Shadowing
diff --git a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql
index 0a6744aed2c..b1863aad849 100644
--- a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql
+++ b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 138.ql
@@ -3,7 +3,9 @@
* @description Identifiers shall not simultaneously have both internal and external linkage in the same translation unit.
* @kind problem
* @id cpp/jsf/av-rule-138
- * @problem.severity error
+ * @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql
index 1d8a8849ac1..83de729ba60 100644
--- a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql
+++ b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 139.ql
@@ -1,9 +1,11 @@
/**
* @name AV Rule 139
- * @description External objects will not be declared in more than one file
+ * @description External objects will not be declared in more than one file.
* @kind problem
* @id cpp/jsf/av-rule-139
* @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql
index 7a0e6f58661..0088664dcd8 100644
--- a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql
+++ b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 140.ql
@@ -4,7 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-140
* @problem.severity warning
- * @tags portability
+ * @tags maintainability
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql
index 570a3566d4a..4b8cd81eb63 100644
--- a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql
+++ b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 142.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-142
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql
index 595b414ee9b..9bac57b913a 100644
--- a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql
+++ b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql
@@ -5,6 +5,8 @@
* @kind problem
* @id cpp/jsf/av-rule-143
* @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 145.ql b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 145.ql
index 858fbf9e123..0388e533650 100644
--- a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 145.ql
+++ b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 145.ql
@@ -8,6 +8,7 @@
* @tags reliability
* readability
* language-features
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.17 Types/AV Rule 147.ql b/cpp/ql/src/jsf/4.17 Types/AV Rule 147.ql
index 072076080b1..c60c924460b 100644
--- a/cpp/ql/src/jsf/4.17 Types/AV Rule 147.ql
+++ b/cpp/ql/src/jsf/4.17 Types/AV Rule 147.ql
@@ -5,6 +5,7 @@
* @id cpp/jsf/av-rule-147
* @problem.severity error
* @tags reliability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.17 Types/AV Rule 148.ql b/cpp/ql/src/jsf/4.17 Types/AV Rule 148.ql
index e76a52ce3cd..11a2e09ba96 100644
--- a/cpp/ql/src/jsf/4.17 Types/AV Rule 148.ql
+++ b/cpp/ql/src/jsf/4.17 Types/AV Rule 148.ql
@@ -8,6 +8,7 @@
* @tags maintainability
* readability
* language-features
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql b/cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql
index d09fd2de3dc..1485bb67573 100644
--- a/cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql
+++ b/cpp/ql/src/jsf/4.18 Constants/AV Rule 149.ql
@@ -3,7 +3,9 @@
* @description Octal constants (other than zero) shall not be used.
* @kind problem
* @id cpp/jsf/av-rule-149
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql b/cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql
index 542d241721a..eaa41fc002f 100644
--- a/cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql
+++ b/cpp/ql/src/jsf/4.18 Constants/AV Rule 150.ql
@@ -3,7 +3,9 @@
* @description Hexadecimal constants will be represented using all uppercase letters.
* @kind problem
* @id cpp/jsf/av-rule-150
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.1.ql b/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.1.ql
index 8411c8ebf3f..b541121139b 100644
--- a/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.1.ql
+++ b/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.1.ql
@@ -5,6 +5,7 @@
* @id cpp/jsf/av-rule-151-1
* @problem.severity error
* @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql b/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql
index e4dad7e2e00..5cd0052b455 100644
--- a/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql
+++ b/cpp/ql/src/jsf/4.18 Constants/AV Rule 151.ql
@@ -3,7 +3,9 @@
* @description Numeric values in code will not be used; symbolic values will be used instead.
* @kind problem
* @id cpp/jsf/av-rule-151
- * @problem.severity warning
+ * @problem.severity recommendation
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql b/cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql
index d57a9eb79b0..c83d96102a5 100644
--- a/cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql
+++ b/cpp/ql/src/jsf/4.19 Variables/AV Rule 152.ql
@@ -3,7 +3,10 @@
* @description Multiple variable declarations shall not be allowed on the same line.
* @kind problem
* @id cpp/jsf/av-rule-152
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql
index 7f0298c3558..237ce784cd5 100644
--- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql
+++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 153.ql
@@ -3,7 +3,9 @@
* @description Unions shall not be used.
* @kind problem
* @id cpp/jsf/av-rule-153
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql
index 247a38130b5..1fe2b836f2d 100644
--- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql
+++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql
@@ -6,9 +6,11 @@
* @problem.severity warning
* @precision low
* @id cpp/signed-bit-field
- * @tags reliability
- * readability
+ * @tags correctness
+ * portability
+ * reliability
* language-features
+ * external/jsf
* external/cwe/cwe-190
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql
index ba48fe3539a..784cc19d109 100644
--- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql
+++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 155.ql
@@ -5,6 +5,8 @@
* @kind problem
* @id cpp/jsf/av-rule-155
* @problem.severity warning
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql
index 2dcabc93098..223ba5877d4 100644
--- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql
+++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 156.ql
@@ -4,7 +4,10 @@
* and shall only be accessed via their names.
* @kind problem
* @id cpp/jsf/av-rule-156
- * @problem.severity error
+ * @problem.severity warning
+ * @precision low
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql
index 18cbc5118a1..7f99a96fb78 100644
--- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql
+++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 157.ql
@@ -4,7 +4,10 @@
* contain side effects.
* @kind problem
* @id cpp/jsf/av-rule-157
- * @problem.severity error
+ * @problem.severity warning
+ * @tags correctness
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql
index 6063f45073d..aea14943088 100644
--- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql
+++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 158.ql
@@ -4,7 +4,10 @@
* if the operands contain binary operators.
* @kind problem
* @id cpp/jsf/av-rule-158
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql
index ae3350aeece..eeccef02f38 100644
--- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql
+++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 159.ql
@@ -3,7 +3,9 @@
* @description Operators ||, &&, and unary & shall not be overloaded
* @kind problem
* @id cpp/jsf/av-rule-159
- * @problem.severity error
+ * @problem.severity warning
+ * @tags correctness
+ * external/jsf
*/
// See More Effective C++ item 7
// Note: Meyers allows unary & to be overloaded but not comma
diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql
index e34673b9070..f339291976c 100644
--- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql
+++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 160.ql
@@ -3,7 +3,10 @@
* @description An assignment expression shall be used only as the expression in an expression statement.
* @kind problem
* @id cpp/jsf/av-rule-160
- * @problem.severity error
+ * @problem.severity warning
+ * @tags correctness
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql
index e9f1fa4f08f..757eb78292e 100644
--- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql
+++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 162.ql
@@ -3,7 +3,9 @@
* @description Signed and unsigned values shall not be mixed in arithmetic or comparison operations. Mixing signed and unsigned values is error prone as it subjects operations to numerous arithmetic conversion and integral promotion rules.
* @kind problem
* @id cpp/jsf/av-rule-162
- * @problem.severity error
+ * @problem.severity warning
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql
index d8a5a8930a9..51f970c912e 100644
--- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql
+++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 163.ql
@@ -3,7 +3,9 @@
* @description Unsigned arithmetic shall not be used.
* @kind problem
* @id cpp/jsf/av-rule-163
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql
index 5531028f466..d10ddfc61d4 100644
--- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql
+++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 164.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-164
* @problem.severity error
+ * @precision low
+ * @tags correctness
+ * external/jsf
*/
import cpp
@@ -35,7 +38,7 @@ predicate constantValue(Expr e, int value) {
predicate violation(BinaryBitwiseOperation op, int lhsBytes, int value) {
(op instanceof LShiftExpr or op instanceof RShiftExpr) and
constantValue(op.getRightOperand(), value) and
- lhsBytes = op.getLeftOperand().getType().getSize() and
+ lhsBytes = op.getLeftOperand().getExplicitlyConverted().getType().getSize() and
(value < 0 or value >= lhsBytes * 8)
}
diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql
index ba2e452eade..4edae501c8a 100644
--- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql
+++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 165.ql
@@ -4,13 +4,16 @@
* @kind problem
* @id cpp/jsf/av-rule-165
* @problem.severity warning
- * @tags reliability
+ * @precision low
+ * @tags correctness
+ * reliability
+ * external/jsf
*/
import cpp
// see MISRA Rule 5-3-2
from UnaryMinusExpr ume
-where ume.getOperand().getUnderlyingType().(IntegralType).isUnsigned()
+where ume.getOperand().getExplicitlyConverted().getUnderlyingType().(IntegralType).isUnsigned()
and not ume.getOperand() instanceof Literal
select ume, "The unary minus operator should not be applied to an unsigned expression."
diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 166.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 166.ql
index 019e52e0e9f..9eea44cf016 100644
--- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 166.ql
+++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 166.ql
@@ -7,6 +7,7 @@
* @id cpp/sizeof-side-effect
* @tags reliability
* correctness
+ * external/jsf
*/
import cpp
import jsf.lib.section_4_21_Operators.AV_Rule_166
diff --git a/cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql b/cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql
index 6a47217fd1a..d8b0edf0bf8 100644
--- a/cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql
+++ b/cpp/ql/src/jsf/4.21 Operators/AV Rule 168.ql
@@ -3,7 +3,10 @@
* @description The comma operator shall not be used.
* @kind problem
* @id cpp/jsf/av-rule-168
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql
index 1cd0a5a5a68..3dbc992773c 100644
--- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql
+++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 170.ql
@@ -3,7 +3,10 @@
* @description More than two levels of pointer indirection shall not be used.
* @kind problem
* @id cpp/jsf/av-rule-170
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql
index a5a282bd280..2ff8d5464c5 100644
--- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql
+++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 171.ql
@@ -5,6 +5,8 @@
* @kind problem
* @id cpp/jsf/av-rule-171
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
import semmle.code.cpp.pointsto.PointsTo
diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql
index 9bbc4f56388..5f615755478 100644
--- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql
+++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 173.ql
@@ -6,6 +6,8 @@
* @kind problem
* @id cpp/jsf/av-rule-173
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql
index b9b19ca1236..3662d050c3d 100644
--- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql
+++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 175.ql
@@ -3,7 +3,9 @@
* @description A pointer shall not be compared to NULL or be assigned NULL; use plain 0 instead.
* @kind problem
* @id cpp/jsf/av-rule-175
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql
index 3b3369dff21..1ddce11dc2b 100644
--- a/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql
+++ b/cpp/ql/src/jsf/4.22 Pointers and References/AV Rule 176.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-176
* @problem.severity warning
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql
index 62bb5ac7207..d8738ccc158 100644
--- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql
+++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 178.ql
@@ -5,6 +5,8 @@
* @kind problem
* @id cpp/jsf/av-rule-178
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql
index 007f6c9c80a..ea16c751592 100644
--- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql
+++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 179.ql
@@ -5,6 +5,8 @@
* @kind problem
* @id cpp/jsf/av-rule-179
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql
index 7f3ecd38c99..a190874796e 100644
--- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql
+++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql
@@ -4,7 +4,9 @@
* shall not be used.
* @kind problem
* @id cpp/jsf/av-rule-180
- * @problem.severity error
+ * @problem.severity warning
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql
index cd32f6f4208..bad480ef016 100644
--- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql
+++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 181.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-181
* @problem.severity warning
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql
index 0e5a345c198..cf2844519dd 100644
--- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql
+++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 182.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-182
* @problem.severity error
+ * @tags correctness
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql
index b72c3803f06..828d655cd3d 100644
--- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql
+++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 184.ql
@@ -5,7 +5,9 @@
* requirement or is necessary for a hardware interface.
* @kind problem
* @id cpp/jsf/av-rule-184
- * @problem.severity error
+ * @problem.severity warning
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql
index 5a276d498c7..ad7aef37eb9 100644
--- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql
+++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 185.ql
@@ -4,7 +4,9 @@
* instead of the traditional C-style cast.
* @kind problem
* @id cpp/jsf/av-rule-185
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql
index 2ee5c35140a..9f56a1ab564 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 186.ql
@@ -3,7 +3,10 @@
* @description There shall be no unreachable code.
* @kind problem
* @id cpp/jsf/av-rule-186
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * useless-code
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql
index 6033c421a4f..f0435485ce7 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-187
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql
index f01c15a9a0e..1c13ac90ef4 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 188.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-188
* @problem.severity warning
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql
index fbf0a1b0b11..79c68166ae3 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 189.ql
@@ -3,8 +3,10 @@
* @description The goto statement shall not be used.
* @kind problem
* @id cpp/jsf/av-rule-189
- * @problem.severity error
+ * @problem.severity warning
* @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql
index 8e794081c2e..19a60dbc8f5 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 190.ql
@@ -3,7 +3,9 @@
* @description The continue statement shall not be used.
* @kind problem
* @id cpp/jsf/av-rule-190
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql
index 866dbcd2a22..4201256e09c 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql
@@ -3,7 +3,9 @@
* @description The break statement shall not be used.
* @kind problem
* @id cpp/jsf/av-rule-191
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql
index 8553d0a005a..b20f82241cc 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 192.ql
@@ -5,6 +5,8 @@
* @kind problem
* @id cpp/jsf/av-rule-192
* @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql
index 6e589bb0fab..32754f6d20b 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 193.ql
@@ -4,7 +4,10 @@
* shall be terminated with a break statement.
* @kind problem
* @id cpp/jsf/av-rule-193
- * @problem.severity error
+ * @problem.severity warning
+ * @tags correctness
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql
index 4aa98eb85e6..82713fa58ea 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 194.ql
@@ -3,7 +3,9 @@
* @description All switch statements that do not intend to test for every enumeration value shall contain a final default clause.
* @kind problem
* @id cpp/jsf/av-rule-194
- * @problem.severity error
+ * @problem.severity warning
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql
index 8a8fa4b58e5..318a5879a4d 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 195.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-195
* @problem.severity warning
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 196.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 196.ql
index b0f2627e655..33eaacee040 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 196.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 196.ql
@@ -7,6 +7,7 @@
* @id cpp/trivial-switch
* @tags maintainability
* readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql
index 37fc05b5833..9230255a9a0 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql
@@ -5,8 +5,9 @@
* @problem.severity recommendation
* @precision high
* @id cpp/loop-variable-float
- * @tags reliability
- * readability
+ * @tags correctness
+ * reliability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql
index 9b973d40264..5b1058b42d7 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 198.ql
@@ -5,6 +5,9 @@
* @kind problem
* @id cpp/jsf/av-rule-198
* @problem.severity warning
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql
index 258a6c1e2bf..2cb5e918c44 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 199.ql
@@ -5,6 +5,9 @@
* @kind problem
* @id cpp/jsf/av-rule-199
* @problem.severity warning
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql
index cbabf485265..159074279ea 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 200.ql
@@ -5,6 +5,8 @@
* @kind problem
* @id cpp/jsf/av-rule-200
* @problem.severity warning
+ * @tags maintainability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 201.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 201.ql
index 060734ab0ec..fa9510681d5 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 201.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 201.ql
@@ -7,6 +7,7 @@
* @id cpp/loop-variable-changed
* @tags reliability
* readability
+ * external/jsf
*/
import cpp
import Likely_Bugs.NestedLoopSameVar
diff --git a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql
index 352993f2c17..ea19a9c4eb2 100644
--- a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql
+++ b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 202.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-202
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql
index d1c53d781ed..132084c0488 100644
--- a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql
+++ b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.1.ql
@@ -4,6 +4,8 @@
* @kind problem
* @id cpp/jsf/av-rule-204-1
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql
index d2bf1728a76..676e4789244 100644
--- a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql
+++ b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 204.ql
@@ -6,7 +6,10 @@
* condition, or as a part of a chained operation.
* @kind problem
* @id cpp/jsf/av-rule-204
- * @problem.severity error
+ * @problem.severity warning
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql
index a269959daa2..e468e38a980 100644
--- a/cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql
+++ b/cpp/ql/src/jsf/4.25 Expressions/AV Rule 205.ql
@@ -3,7 +3,9 @@
* @description The volatile keyword shall not be used unless directly interfacing with hardware.
* @kind problem
* @id cpp/jsf/av-rule-205
- * @problem.severity error
+ * @problem.severity warning
+ * @tags efficiency
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql b/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql
index 30254488556..da5c599615a 100644
--- a/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql
+++ b/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 206.ql
@@ -4,7 +4,9 @@
* occur after initialization.
* @kind problem
* @id cpp/jsf/av-rule-206
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags resources
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql b/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql
index 6628234ff0c..c9d4015cb40 100644
--- a/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql
+++ b/cpp/ql/src/jsf/4.26 Memory Allocation/AV Rule 207.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-207
* @problem.severity warning
+ * @tags maintainability
+ * modularity
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql b/cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql
index 172f8db58a8..26c2d25b784 100644
--- a/cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql
+++ b/cpp/ql/src/jsf/4.27 Fault Handling/AV Rule 208.ql
@@ -3,7 +3,9 @@
* @description C++ exceptions shall not be used.
* @kind problem
* @id cpp/jsf/av-rule-208
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags language-features
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql
index 991026f4fa6..964eec6bbe4 100644
--- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql
+++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql
@@ -5,7 +5,10 @@
* each compiler, and these type names used in the code.
* @kind problem
* @id cpp/jsf/av-rule-209
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql
index c8fb016284d..113c039baec 100644
--- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql
+++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 210.ql
@@ -6,6 +6,9 @@
* @id cpp/jsf/av-rule-210
* @problem.severity error
* @precision low
+ * @tags correctness
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql
index 5a05826fa19..5ab7e3598a1 100644
--- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql
+++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 212.ql
@@ -5,6 +5,9 @@
* @kind problem
* @id cpp/jsf/av-rule-212
* @problem.severity error
+ * @tags correctness
+ * portability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql
index 7cdcc1e9e24..45672d33397 100644
--- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql
+++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 213.ql
@@ -4,7 +4,10 @@
* below arithmetic operators, in expressions.
* @kind problem
* @id cpp/jsf/av-rule-213
- * @problem.severity error
+ * @problem.severity recommendation
+ * @tags maintainability
+ * readability
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql
index 9b873f8e716..fb267186095 100644
--- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql
+++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 214.ql
@@ -5,6 +5,8 @@
* @kind problem
* @id cpp/jsf/av-rule-214
* @problem.severity error
+ * @tags correctness
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql
index 201ea073fd9..642feb697a7 100644
--- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql
+++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 215.ql
@@ -4,6 +4,9 @@
* @kind problem
* @id cpp/jsf/av-rule-215
* @problem.severity warning
+ * @tags correctness
+ * language-features
+ * external/jsf
*/
import cpp
diff --git a/cpp/ql/src/semmle/code/cpp/PrintAST.qll b/cpp/ql/src/semmle/code/cpp/PrintAST.qll
index 3956ac428c1..803758f986c 100644
--- a/cpp/ql/src/semmle/code/cpp/PrintAST.qll
+++ b/cpp/ql/src/semmle/code/cpp/PrintAST.qll
@@ -59,18 +59,36 @@ private predicate locationSortKeys(Locatable ast, string file, int line,
)
}
+private Function getEnclosingFunction(Locatable ast) {
+ result = ast.(Expr).getEnclosingFunction() or
+ result = ast.(Stmt).getEnclosingFunction() or
+ result = ast.(Initializer).getExpr().getEnclosingFunction() or
+ result = ast.(Parameter).getFunction() or
+ exists(DeclStmt stmt |
+ stmt.getADeclarationEntry() = ast and
+ result = stmt.getEnclosingFunction()
+ ) or
+ result = ast
+}
+
/**
* Most nodes are just a wrapper around `Locatable`, but we do synthesize new
* nodes for things like parameter lists and constructor init lists.
*/
private newtype TPrintASTNode =
- TASTNode(Locatable ast) or
- TParametersNode(Function func) or
+ TASTNode(Locatable ast) {
+ shouldPrintFunction(getEnclosingFunction(ast))
+ } or
+ TParametersNode(Function func) {
+ shouldPrintFunction(func)
+ } or
TConstructorInitializersNode(Constructor ctor) {
- ctor.hasEntryPoint()
+ ctor.hasEntryPoint() and
+ shouldPrintFunction(ctor)
} or
TDestructorDestructionsNode(Destructor dtor) {
- dtor.hasEntryPoint()
+ dtor.hasEntryPoint() and
+ shouldPrintFunction(dtor)
}
/**
diff --git a/cpp/ql/src/semmle/code/cpp/Variable.qll b/cpp/ql/src/semmle/code/cpp/Variable.qll
index 958a50ebfc8..c93652f4d8a 100644
--- a/cpp/ql/src/semmle/code/cpp/Variable.qll
+++ b/cpp/ql/src/semmle/code/cpp/Variable.qll
@@ -291,7 +291,8 @@ class LocalVariable extends LocalScopeVariable, @localvariable {
override Type getType() { localvariables(underlyingElement(this),unresolveElement(result),_) }
override Function getFunction() {
- exists(DeclStmt s | s.getADeclaration() = this and s.getEnclosingFunction() = result)
+ exists(DeclStmt s | s.getADeclaration() = this and s.getEnclosingFunction() = result) or
+ exists(ConditionDeclExpr e | e.getVariable() = this and e.getEnclosingFunction() = result)
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll b/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll
index e0a3f542731..0901f74ccd3 100644
--- a/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll
+++ b/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll
@@ -78,8 +78,8 @@ predicate isStdLibAllocationExpr(Expr e)
*/
predicate isAllocationExpr(Expr e) {
allocationCall(e)
- or e instanceof NewExpr
- or e instanceof NewArrayExpr
+ or
+ e = any(NewOrNewArrayExpr new | not exists(new.getPlacementPointer()))
}
/**
diff --git a/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll
index ccad37645cb..3d3d3c5cd3f 100644
--- a/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll
+++ b/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll
@@ -28,7 +28,8 @@ class Expr extends StmtParent, @expr {
result = this.getParent().(Expr).getEnclosingStmt() or
result = this.getParent().(Stmt) or
exists(Expr other | result = other.getEnclosingStmt() and other.getConversion() = this) or
- exists(DeclStmt d, LocalVariable v | d.getADeclaration() = v and v.getInitializer().getExpr() = this and result = d)
+ exists(DeclStmt d, LocalVariable v | d.getADeclaration() = v and v.getInitializer().getExpr() = this and result = d) or
+ exists(ConditionDeclExpr cde, LocalVariable v | cde.getVariable() = v and v.getInitializer().getExpr() = this and result = cde.getEnclosingStmt())
}
/** Gets the enclosing variable of this expression, if any. */
@@ -663,6 +664,16 @@ class NewOrNewArrayExpr extends Expr, @any_new_expr {
* For `new int[5]` the result is `int[5]`.
*/
abstract Type getAllocatedType();
+
+ /**
+ * Gets the pointer `p` if this expression is of the form `new(p) T...`.
+ * Invocations of this form are non-allocating `new` expressions that may
+ * call the constructor of `T` but will not allocate memory.
+ */
+ Expr getPlacementPointer() {
+ isStandardPlacementNewAllocator(this.getAllocator()) and
+ result = this.getAllocatorCall().getArgument(1)
+ }
}
/**
@@ -960,3 +971,9 @@ private predicate convparents(Expr child, int idx, Element parent) {
child = astChild.getFullyConverted()
)
}
+
+private predicate isStandardPlacementNewAllocator(Function operatorNew) {
+ operatorNew.getName().matches("operator new%") and
+ operatorNew.getNumberOfParameters() = 2 and
+ operatorNew.getParameter(1).getType() instanceof VoidPointerType
+}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/IRConfiguration.qll b/cpp/ql/src/semmle/code/cpp/ir/IRConfiguration.qll
new file mode 100644
index 00000000000..feb510b2ab8
--- /dev/null
+++ b/cpp/ql/src/semmle/code/cpp/ir/IRConfiguration.qll
@@ -0,0 +1,19 @@
+import cpp
+
+private newtype TIRConfiguration = MkIRConfiguration()
+
+/**
+ * The query can extend this class to control which functions have IR generated for them.
+ */
+class IRConfiguration extends TIRConfiguration {
+ string toString() {
+ result = "IRConfiguration"
+ }
+
+ /**
+ * Holds if IR should be created for function `func`. By default, holds for all functions.
+ */
+ predicate shouldCreateIRForFunction(Function func) {
+ any()
+ }
+}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll
index 478e92fac5c..8fb77621426 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll
@@ -1,5 +1,40 @@
private import IR
import cpp
+import semmle.code.cpp.ir.IRConfiguration
+
+private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
+
+/**
+ * The query can extend this class to control which functions are printed.
+ */
+class PrintIRConfiguration extends TPrintIRConfiguration {
+ string toString() {
+ result = "PrintIRConfiguration"
+ }
+
+ /**
+ * Holds if the IR for `func` should be printed. By default, holds for all
+ * functions.
+ */
+ predicate shouldPrintFunction(Function func) {
+ any()
+ }
+}
+
+private predicate shouldPrintFunction(Function func) {
+ exists(PrintIRConfiguration config |
+ config.shouldPrintFunction(func)
+ )
+}
+
+/**
+ * Override of `IRConfiguration` to only create IR for the functions that are to be dumped.
+ */
+private class FilteredIRConfiguration extends IRConfiguration {
+ override predicate shouldCreateIRForFunction(Function func) {
+ shouldPrintFunction(func)
+ }
+}
private string getAdditionalInstructionProperty(Instruction instr, string key) {
exists(IRPropertyProvider provider |
@@ -14,9 +49,15 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
}
private newtype TPrintableIRNode =
- TPrintableFunctionIR(FunctionIR funcIR) or
- TPrintableIRBlock(IRBlock block) or
- TPrintableInstruction(Instruction instr)
+ TPrintableFunctionIR(FunctionIR funcIR) {
+ shouldPrintFunction(funcIR.getFunction())
+ } or
+ TPrintableIRBlock(IRBlock block) {
+ shouldPrintFunction(block.getFunction())
+ } or
+ TPrintableInstruction(Instruction instr) {
+ shouldPrintFunction(instr.getFunction())
+ }
/**
* A node to be emitted in the IR graph.
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll
index 478e92fac5c..8fb77621426 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/PrintIR.qll
@@ -1,5 +1,40 @@
private import IR
import cpp
+import semmle.code.cpp.ir.IRConfiguration
+
+private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
+
+/**
+ * The query can extend this class to control which functions are printed.
+ */
+class PrintIRConfiguration extends TPrintIRConfiguration {
+ string toString() {
+ result = "PrintIRConfiguration"
+ }
+
+ /**
+ * Holds if the IR for `func` should be printed. By default, holds for all
+ * functions.
+ */
+ predicate shouldPrintFunction(Function func) {
+ any()
+ }
+}
+
+private predicate shouldPrintFunction(Function func) {
+ exists(PrintIRConfiguration config |
+ config.shouldPrintFunction(func)
+ )
+}
+
+/**
+ * Override of `IRConfiguration` to only create IR for the functions that are to be dumped.
+ */
+private class FilteredIRConfiguration extends IRConfiguration {
+ override predicate shouldCreateIRForFunction(Function func) {
+ shouldPrintFunction(func)
+ }
+}
private string getAdditionalInstructionProperty(Instruction instr, string key) {
exists(IRPropertyProvider provider |
@@ -14,9 +49,15 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
}
private newtype TPrintableIRNode =
- TPrintableFunctionIR(FunctionIR funcIR) or
- TPrintableIRBlock(IRBlock block) or
- TPrintableInstruction(Instruction instr)
+ TPrintableFunctionIR(FunctionIR funcIR) {
+ shouldPrintFunction(funcIR.getFunction())
+ } or
+ TPrintableIRBlock(IRBlock block) {
+ shouldPrintFunction(block.getFunction())
+ } or
+ TPrintableInstruction(Instruction instr) {
+ shouldPrintFunction(instr.getFunction())
+ }
/**
* A node to be emitted in the IR graph.
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll
index cbddf84c890..da9a3f1c2dd 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll
@@ -10,8 +10,7 @@ private import TranslatedInitialization
* Gets the `TranslatedDeclarationEntry` that represents the declaration
* `entry`.
*/
-TranslatedDeclarationEntry getTranslatedDeclarationEntry(
- DeclarationEntry entry) {
+TranslatedDeclarationEntry getTranslatedDeclarationEntry(DeclarationEntry entry) {
result.getAST() = entry
}
@@ -21,8 +20,7 @@ TranslatedDeclarationEntry getTranslatedDeclarationEntry(
* it can also be the declaration of a static local variable, an extern
* variable, or an extern function.
*/
-abstract class TranslatedDeclarationEntry extends TranslatedElement,
- TTranslatedDeclarationEntry {
+abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslatedDeclarationEntry {
DeclarationEntry entry;
TranslatedDeclarationEntry() {
@@ -50,14 +48,13 @@ abstract class TranslatedDeclarationEntry extends TranslatedElement,
* for declarations other than local variables. Since these have no semantic
* effect, they are translated as `NoOp`.
*/
-class TranslatedNonVariableDeclaration extends
- TranslatedDeclarationEntry {
- TranslatedNonVariableDeclaration() {
+class TranslatedNonVariableDeclarationEntry extends TranslatedDeclarationEntry {
+ TranslatedNonVariableDeclarationEntry() {
not entry.getDeclaration() instanceof LocalVariable
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
- Type resultType, boolean isGLValue) {
+ Type resultType, boolean isGLValue) {
opcode instanceof Opcode::NoOp and
tag = OnlyInstructionTag() and
resultType instanceof VoidType and
@@ -88,98 +85,11 @@ class TranslatedNonVariableDeclaration extends
* Represents the IR translation of the declaration of a local variable,
* including its initialization, if any.
*/
-abstract class TranslatedVariableDeclaration extends
- TranslatedDeclarationEntry {
- LocalVariable var;
-
- TranslatedVariableDeclaration() {
- entry.getDeclaration() = var
- }
-}
-
-/**
- * Represents the IR translation of a local variable with no initializer. The
- * generated IR stores into the variable using an `Uninitialized` instruction,
- * rather than a `Store`.
- */
-class TranslatedUninitializedVariable extends
- TranslatedVariableDeclaration {
- TranslatedUninitializedVariable() {
- not exists(Initializer init |
- init.getDeclaration() = var
- )
- }
-
- override TranslatedElement getChild(int id) {
- none()
- }
-
- override Instruction getFirstInstruction() {
- result = getInstruction(InitializerVariableAddressTag())
- }
-
- override predicate hasInstruction(Opcode opcode, InstructionTag tag,
- Type resultType, boolean isGLValue) {
- (
- tag = InitializerVariableAddressTag() and
- opcode instanceof Opcode::VariableAddress and
- resultType = var.getType().getUnspecifiedType() and
- isGLValue = true
- ) or
- (
- tag = InitializerStoreTag() and
- opcode instanceof Opcode::Uninitialized and
- resultType = var.getType().getUnspecifiedType() and
- isGLValue = false
- )
- }
-
- override Instruction getInstructionSuccessor(InstructionTag tag,
- EdgeKind kind) {
- kind instanceof GotoEdge and
- (
- (
- tag = InitializerVariableAddressTag() and
- result = getInstruction(InitializerStoreTag())
- ) or
- (
- tag = InitializerStoreTag() and
- result = getParent().getChildSuccessor(this)
- )
- )
- }
-
- override Instruction getChildSuccessor(TranslatedElement child) {
- none()
- }
-
- override Instruction getInstructionOperand(InstructionTag tag,
- OperandTag operandTag) {
- tag = InitializerStoreTag() and
- (
- (
- operandTag instanceof AddressOperandTag and
- result = getInstruction(InitializerVariableAddressTag())
- )
- )
- }
-
- override IRVariable getInstructionVariable(InstructionTag tag) {
- tag = InitializerVariableAddressTag() and
- result = getIRUserVariable(var.getFunction(), var)
- }
-}
-
-/**
- * Represents the IR translation of a local variable with an initializer.
- */
-class TranslatedInitializedVariable extends
- TranslatedVariableDeclaration, InitializationContext {
- Initializer init;
-
- TranslatedInitializedVariable() {
- init.getDeclaration() = var
- }
+abstract class TranslatedVariableDeclaration extends TranslatedElement, InitializationContext {
+ /**
+ * Gets the local variable being declared.
+ */
+ abstract LocalVariable getVariable();
override TranslatedElement getChild(int id) {
id = 0 and result = getInitialization()
@@ -190,18 +100,41 @@ class TranslatedInitializedVariable extends
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
- Type resultType, boolean isGLValue) {
- tag = InitializerVariableAddressTag() and
- opcode instanceof Opcode::VariableAddress and
- resultType = var.getType().getUnspecifiedType() and
- isGLValue = true
+ Type resultType, boolean isGLValue) {
+ (
+ tag = InitializerVariableAddressTag() and
+ opcode instanceof Opcode::VariableAddress and
+ resultType = getVariable().getType().getUnspecifiedType() and
+ isGLValue = true
+ ) or
+ (
+ hasUninitializedInstruction() and
+ tag = InitializerStoreTag() and
+ opcode instanceof Opcode::Uninitialized and
+ resultType = getVariable().getType().getUnspecifiedType() and
+ isGLValue = false
+ )
}
override Instruction getInstructionSuccessor(InstructionTag tag,
- EdgeKind kind) {
- tag = InitializerVariableAddressTag() and
- result = getInitialization().getFirstInstruction() and
- kind instanceof GotoEdge
+ EdgeKind kind) {
+ (
+ tag = InitializerVariableAddressTag() and
+ kind instanceof GotoEdge and
+ if hasUninitializedInstruction() then
+ result = getInstruction(InitializerStoreTag())
+ else
+ result = getInitialization().getFirstInstruction()
+ ) or
+ (
+ hasUninitializedInstruction() and
+ kind instanceof GotoEdge and
+ tag = InitializerStoreTag() and
+ (
+ result = getInitialization().getFirstInstruction() or
+ not exists(getInitialization()) and result = getParent().getChildSuccessor(this)
+ )
+ )
}
override Instruction getChildSuccessor(TranslatedElement child) {
@@ -210,7 +143,14 @@ class TranslatedInitializedVariable extends
override IRVariable getInstructionVariable(InstructionTag tag) {
tag = InitializerVariableAddressTag() and
- result = getIRUserVariable(var.getFunction(), var)
+ result = getIRUserVariable(getFunction(), getVariable())
+ }
+
+ override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
+ hasUninitializedInstruction() and
+ tag = InitializerStoreTag() and
+ operandTag instanceof AddressOperandTag and
+ result = getInstruction(InitializerVariableAddressTag())
}
override Instruction getTargetAddress() {
@@ -218,10 +158,67 @@ class TranslatedInitializedVariable extends
}
override Type getTargetType() {
- result = var.getType().getUnspecifiedType()
+ result = getVariable().getType().getUnspecifiedType()
}
private TranslatedInitialization getInitialization() {
- result = getTranslatedInitialization(init.getExpr().getFullyConverted())
+ result = getTranslatedInitialization(getVariable().getInitializer().getExpr().getFullyConverted())
+ }
+
+ private predicate hasUninitializedInstruction() {
+ not exists(getInitialization()) or
+ getInitialization() instanceof TranslatedListInitialization
+ }
+}
+
+/**
+ * Represents the IR translation of a local variable declaration within a declaration statement.
+ */
+class TranslatedVariableDeclarationEntry extends TranslatedVariableDeclaration,
+ TranslatedDeclarationEntry {
+ LocalVariable var;
+
+ TranslatedVariableDeclarationEntry() {
+ var = entry.getDeclaration()
+ }
+
+ override LocalVariable getVariable() {
+ result = var
+ }
+}
+
+TranslatedConditionDecl getTranslatedConditionDecl(ConditionDeclExpr expr) {
+ result.getAST() = expr
+}
+
+/**
+ * Represents the IR translation of the declaration portion of a `ConditionDeclExpr`, which
+ * represents the variable declared in code such as:
+ * ```
+ * if (int* p = &x) {
+ * }
+ * ```
+ */
+class TranslatedConditionDecl extends TranslatedVariableDeclaration, TTranslatedConditionDecl {
+ ConditionDeclExpr conditionDeclExpr;
+
+ TranslatedConditionDecl() {
+ this = TTranslatedConditionDecl(conditionDeclExpr)
+ }
+
+ override string toString() {
+ result = "decl: " + conditionDeclExpr.toString()
+ }
+
+ override Locatable getAST() {
+ result = conditionDeclExpr
+ }
+
+ override Function getFunction() {
+ result = conditionDeclExpr.getEnclosingFunction()
+ }
+
+ override LocalVariable getVariable() {
+ result = conditionDeclExpr.getVariable()
}
}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
index 1be620d1206..b701c1a3f5d 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
@@ -1,5 +1,7 @@
import cpp
+import cpp
import semmle.code.cpp.ir.implementation.raw.IR
+private import semmle.code.cpp.ir.IRConfiguration
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.internal.TempVariableTag
@@ -83,7 +85,8 @@ private predicate ignoreExprOnly(Expr expr) {
// Ignore the allocator call, because we always synthesize it. Don't ignore
// its arguments, though, because we use them as part of the synthesis.
newExpr.getAllocatorCall() = expr
- )
+ ) or
+ not translateFunction(expr.getEnclosingFunction())
}
/**
@@ -94,6 +97,49 @@ private predicate ignoreExpr(Expr expr) {
ignoreExprAndDescendants(getRealParent*(expr))
}
+/**
+ * Holds if `func` contains an AST that cannot be translated into IR. This is mostly used to work
+ * around extractor bugs. Once the relevant extractor bugs are fixed, this predicate can be removed.
+ */
+private predicate isInvalidFunction(Function func) {
+ exists(Literal literal |
+ // Constructor field inits within a compiler-generated copy constructor have a source expression
+ // that is a `Literal` with no value.
+ literal = func.(Constructor).getAnInitializer().(ConstructorFieldInit).getExpr() and
+ not exists(literal.getValue())
+ ) or
+ exists(ThisExpr thisExpr |
+ // An instantiation of a member function template is not treated as a `MemberFunction` if it has
+ // only non-type template arguments.
+ thisExpr.getEnclosingFunction() = func and
+ not func instanceof MemberFunction
+ ) or
+ exists(Expr expr |
+ // Expression missing a type.
+ expr.getEnclosingFunction() = func and
+ not exists(expr.getType())
+ )
+}
+
+/**
+ * Holds if `func` should be translated to IR.
+ */
+private predicate translateFunction(Function func) {
+ not func.isFromUninstantiatedTemplate(_) and
+ func.hasEntryPoint() and
+ not isInvalidFunction(func) and
+ exists(IRConfiguration config |
+ config.shouldCreateIRForFunction(func)
+ )
+}
+
+/**
+ * Holds if `stmt` should be translated to IR.
+ */
+private predicate translateStmt(Stmt stmt) {
+ translateFunction(stmt.getEnclosingFunction())
+}
+
/**
* Holds if `expr` is most naturally evaluated as control flow, rather than as
* a value.
@@ -236,7 +282,7 @@ newtype TTranslatedElement =
} or
// The initialization of a field via a member of an initializer list.
TTranslatedExplicitFieldInitialization(Expr ast, Field field,
- Expr expr) {
+ Expr expr) {
exists(ClassAggregateLiteral initList |
not ignoreExpr(initList) and
ast = initList and
@@ -260,14 +306,14 @@ newtype TTranslatedElement =
} or
// The initialization of an array element via a member of an initializer list.
TTranslatedExplicitElementInitialization(
- ArrayAggregateLiteral initList, int elementIndex) {
+ ArrayAggregateLiteral initList, int elementIndex) {
not ignoreExpr(initList) and
exists(initList.getElementExpr(elementIndex))
} or
// The value initialization of a range of array elements that were omitted
// from an initializer list.
TTranslatedElementValueInitialization(ArrayAggregateLiteral initList,
- int elementIndex, int elementCount) {
+ int elementIndex, int elementCount) {
not ignoreExpr(initList) and
isFirstValueInitializedElementInRange(initList, elementIndex) and
elementCount =
@@ -287,28 +333,35 @@ newtype TTranslatedElement =
not ignoreExpr(destruction)
} or
// A statement
- TTranslatedStmt(Stmt stmt) or
+ TTranslatedStmt(Stmt stmt) {
+ translateStmt(stmt)
+ } or
// A function
TTranslatedFunction(Function func) {
- func.hasEntryPoint() and
- not func.isFromUninstantiatedTemplate(_)
+ translateFunction(func)
} or
// A constructor init list
TTranslatedConstructorInitList(Function func) {
- func.hasEntryPoint()
+ translateFunction(func)
} or
// A destructor destruction list
TTranslatedDestructorDestructionList(Function func) {
- func.hasEntryPoint()
+ translateFunction(func)
} or
// A function parameter
TTranslatedParameter(Parameter param) {
- param.getFunction().hasEntryPoint() or
- exists(param.getCatchBlock())
+ exists(Function func |
+ (
+ func = param.getFunction() or
+ func = param.getCatchBlock().getEnclosingFunction()
+ ) and
+ translateFunction(func)
+ )
} or
// A local declaration
TTranslatedDeclarationEntry(DeclarationEntry entry) {
exists(DeclStmt declStmt |
+ translateStmt(declStmt) and
declStmt.getADeclarationEntry() = entry
)
} or
@@ -319,6 +372,10 @@ newtype TTranslatedElement =
// An allocation size for a `new` or `new[]` expression
TTranslatedAllocationSize(NewOrNewArrayExpr newExpr) {
not ignoreExpr(newExpr)
+ } or
+ // The declaration/initialization part of a `ConditionDeclExpr`
+ TTranslatedConditionDecl(ConditionDeclExpr expr) {
+ not ignoreExpr(expr)
}
/**
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
index de70d44d17c..175f710f265 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
@@ -4,6 +4,7 @@ private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.internal.TempVariableTag
private import InstructionTag
private import TranslatedCondition
+private import TranslatedDeclarationEntry
private import TranslatedElement
private import TranslatedFunction
private import TranslatedInitialization
@@ -2914,3 +2915,57 @@ class TranslatedNewArrayExpr extends TranslatedNewOrNewArrayExpr {
none()
}
}
+
+/**
+ * The IR translation of a `ConditionDeclExpr`, which represents the value of the declared variable
+ * after conversion to `bool` in code such as:
+ * ```
+ * if (int* p = &x) {
+ * }
+ * ```
+ */
+class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr {
+ ConditionDeclExpr condDeclExpr;
+
+ TranslatedConditionDeclExpr() {
+ condDeclExpr = expr
+ }
+
+ override final Instruction getFirstInstruction() {
+ result = getDecl().getFirstInstruction()
+ }
+
+ override final TranslatedElement getChild(int id) {
+ id = 0 and result = getDecl() or
+ id = 1 and result = getConditionExpr()
+ }
+
+ override Instruction getResult() {
+ result = getConditionExpr().getResult()
+ }
+
+ override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
+ none()
+ }
+
+ override Instruction getChildSuccessor(TranslatedElement child) {
+ (
+ child = getDecl() and
+ result = getConditionExpr().getFirstInstruction()
+ ) or
+ child = getConditionExpr() and result = getParent().getChildSuccessor(this)
+ }
+
+ override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType,
+ boolean isGLValue) {
+ none()
+ }
+
+ private TranslatedConditionDecl getDecl() {
+ result = getTranslatedConditionDecl(condDeclExpr)
+ }
+
+ private TranslatedExpr getConditionExpr() {
+ result = getTranslatedExpr(condDeclExpr.getExpr().getFullyConverted())
+ }
+}
diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll
index 478e92fac5c..8fb77621426 100644
--- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll
+++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll
@@ -1,5 +1,40 @@
private import IR
import cpp
+import semmle.code.cpp.ir.IRConfiguration
+
+private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
+
+/**
+ * The query can extend this class to control which functions are printed.
+ */
+class PrintIRConfiguration extends TPrintIRConfiguration {
+ string toString() {
+ result = "PrintIRConfiguration"
+ }
+
+ /**
+ * Holds if the IR for `func` should be printed. By default, holds for all
+ * functions.
+ */
+ predicate shouldPrintFunction(Function func) {
+ any()
+ }
+}
+
+private predicate shouldPrintFunction(Function func) {
+ exists(PrintIRConfiguration config |
+ config.shouldPrintFunction(func)
+ )
+}
+
+/**
+ * Override of `IRConfiguration` to only create IR for the functions that are to be dumped.
+ */
+private class FilteredIRConfiguration extends IRConfiguration {
+ override predicate shouldCreateIRForFunction(Function func) {
+ shouldPrintFunction(func)
+ }
+}
private string getAdditionalInstructionProperty(Instruction instr, string key) {
exists(IRPropertyProvider provider |
@@ -14,9 +49,15 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
}
private newtype TPrintableIRNode =
- TPrintableFunctionIR(FunctionIR funcIR) or
- TPrintableIRBlock(IRBlock block) or
- TPrintableInstruction(Instruction instr)
+ TPrintableFunctionIR(FunctionIR funcIR) {
+ shouldPrintFunction(funcIR.getFunction())
+ } or
+ TPrintableIRBlock(IRBlock block) {
+ shouldPrintFunction(block.getFunction())
+ } or
+ TPrintableInstruction(Instruction instr) {
+ shouldPrintFunction(instr.getFunction())
+ }
/**
* A node to be emitted in the IR graph.
diff --git a/cpp/ql/test/library-tests/allocators/allocators.cpp b/cpp/ql/test/library-tests/allocators/allocators.cpp
index 5f0a535e7f3..4b5775ab352 100644
--- a/cpp/ql/test/library-tests/allocators/allocators.cpp
+++ b/cpp/ql/test/library-tests/allocators/allocators.cpp
@@ -109,3 +109,31 @@ void TestFailedInit(int n) {
new(1.0f) FailedInitOveraligned();
new(1.0f) FailedInitOveraligned[10];
}
+
+// --- non-allocating placement new ---
+
+namespace std {
+ typedef unsigned long size_t;
+ struct nothrow_t {};
+ extern const nothrow_t nothrow;
+}
+
+void* operator new (std::size_t size, void* ptr) noexcept;
+void* operator new[](std::size_t size, void* ptr) noexcept;
+void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
+void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
+
+int overloadedNew() {
+ char buf[sizeof(int)];
+
+ new(&buf[0]) int(5);
+ int five = *(int*)buf;
+
+ new(buf) int[1];
+ *(int*)buf = 4;
+
+ new(std::nothrow) int(3); // memory leak
+ new(std::nothrow) int[2]; // memory leak
+
+ return five;
+}
diff --git a/cpp/ql/test/library-tests/allocators/allocators.expected b/cpp/ql/test/library-tests/allocators/allocators.expected
index 586b82c8664..5802b13f4e9 100644
--- a/cpp/ql/test/library-tests/allocators/allocators.expected
+++ b/cpp/ql/test/library-tests/allocators/allocators.expected
@@ -8,6 +8,8 @@ newExprs
| allocators.cpp:55:3:55:25 | new | Overaligned | operator new(size_t, align_val_t, float) -> void * | 256 | 128 | aligned |
| allocators.cpp:107:3:107:18 | new | FailedInit | FailedInit::operator new(size_t) -> void * | 1 | 1 | |
| allocators.cpp:109:3:109:35 | new | FailedInitOveraligned | FailedInitOveraligned::operator new(size_t, align_val_t, float) -> void * | 128 | 128 | aligned |
+| allocators.cpp:129:3:129:21 | new | int | operator new(size_t, void *) -> void * | 4 | 4 | |
+| allocators.cpp:135:3:135:26 | new | int | operator new(size_t, const nothrow_t &) -> void * | 4 | 4 | |
newArrayExprs
| allocators.cpp:68:3:68:12 | new[] | int | operator new[](unsigned long) -> void * | 4 | 4 | |
| allocators.cpp:69:3:69:18 | new[] | int | operator new[](size_t, float) -> void * | 4 | 4 | |
@@ -16,6 +18,8 @@ newArrayExprs
| allocators.cpp:72:3:72:16 | new[] | String | operator new[](unsigned long) -> void * | 8 | 8 | |
| allocators.cpp:108:3:108:19 | new[] | FailedInit | FailedInit::operator new[](size_t) -> void * | 1 | 1 | |
| allocators.cpp:110:3:110:37 | new[] | FailedInitOveraligned | FailedInitOveraligned::operator new[](size_t, align_val_t, float) -> void * | 128 | 128 | aligned |
+| allocators.cpp:132:3:132:17 | new[] | int | operator new[](size_t, void *) -> void * | 4 | 4 | |
+| allocators.cpp:136:3:136:26 | new[] | int | operator new[](size_t, const nothrow_t &) -> void * | 4 | 4 | |
newExprDeallocators
| allocators.cpp:52:3:52:14 | new | String | operator delete(void *, unsigned long) -> void | 8 | 8 | sized |
| allocators.cpp:53:3:53:27 | new | String | operator delete(void *, float) -> void | 8 | 8 | |
diff --git a/cpp/ql/test/library-tests/allocators/placement.expected b/cpp/ql/test/library-tests/allocators/placement.expected
new file mode 100644
index 00000000000..5755e349eb3
--- /dev/null
+++ b/cpp/ql/test/library-tests/allocators/placement.expected
@@ -0,0 +1,2 @@
+| allocators.cpp:129:3:129:21 | new | allocators.cpp:129:7:129:13 | & ... |
+| allocators.cpp:132:3:132:17 | new[] | allocators.cpp:132:7:132:9 | buf |
diff --git a/cpp/ql/test/library-tests/allocators/placement.ql b/cpp/ql/test/library-tests/allocators/placement.ql
new file mode 100644
index 00000000000..a632c3c5afe
--- /dev/null
+++ b/cpp/ql/test/library-tests/allocators/placement.ql
@@ -0,0 +1,4 @@
+import cpp
+
+from NewOrNewArrayExpr new
+select new, new.getPlacementPointer() as placement
diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
index 8c098f79e11..b01c82d135d 100644
--- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
+++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
@@ -38,6 +38,142 @@
#-----| Type = unsigned long
#-----| 1: p#1
#-----| Type = align_val_t
+bad_asts.cpp:
+# 5| Bad::S::operator=(S &&) -> S &
+# 5| params:
+#-----| 0: p#0
+#-----| Type = S &&
+# 5| Bad::S::operator=(const S &) -> S &
+# 5| params:
+#-----| 0: p#0
+#-----| Type = const S &
+# 9| Bad::S::MemberFunction(int) -> int
+# 9| params:
+# 9| 0: y
+# 9| Type = int
+# 9| body: { ... }
+# 10| 0: return ...
+# 10| 0: ... + ...
+# 10| Type = int
+# 10| ValueCategory = prvalue
+# 10| 0: ... + ...
+# 10| Type = int
+# 10| ValueCategory = prvalue
+# 10| 0: Unknown literal
+# 10| Type = int
+# 10| ValueCategory = prvalue
+# 10| 1: x
+# 10| Type = int
+# 10| ValueCategory = prvalue(load)
+#-----| -1: this
+#-----| Type = S *
+#-----| ValueCategory = prvalue(load)
+# 10| 1: y
+# 10| Type = int
+# 10| ValueCategory = prvalue(load)
+# 9| MemberFunction(int) -> int
+# 9| params:
+# 9| 0: y
+# 9| Type = int
+# 9| body: { ... }
+# 10| 0: return ...
+# 10| 0: ... + ...
+# 10| Type = int
+# 10| ValueCategory = prvalue
+# 10| 0: ... + ...
+# 10| Type = int
+# 10| ValueCategory = prvalue
+# 10| 0: 6
+# 10| Type = int
+# 10| Value = 6
+# 10| ValueCategory = prvalue
+# 10| 1: x
+# 10| Type = int
+# 10| ValueCategory = prvalue(load)
+#-----| -1: this
+#-----| Type = S *
+#-----| ValueCategory = prvalue(load)
+# 10| 1: y
+# 10| Type = int
+# 10| ValueCategory = prvalue(load)
+# 14| Bad::CallBadMemberFunction() -> void
+# 14| params:
+# 14| body: { ... }
+# 15| 0: declaration
+# 15| 0: definition of s
+# 15| Type = S
+# 15| init: initializer for s
+# 15| expr: {...}
+# 15| Type = S
+# 15| ValueCategory = prvalue
+# 16| 1: ExprStmt
+# 16| 0: call to MemberFunction
+# 16| Type = int
+# 16| ValueCategory = prvalue
+# 16| -1: s
+# 16| Type = S
+# 16| ValueCategory = lvalue
+# 16| 0: 1
+# 16| Type = int
+# 16| Value = 1
+# 16| ValueCategory = prvalue
+# 17| 2: return ...
+# 19| Bad::Point::Point(Point &&) -> void
+# 19| params:
+#-----| 0: p#0
+#-----| Type = Point &&
+# 19| Bad::Point::Point(const Point &) -> void
+# 19| params:
+#-----| 0: p#0
+#-----| Type = const Point &
+# 19| initializations:
+# 19| 0: constructor init of field x
+# 19| Type = int
+# 19| ValueCategory = prvalue
+# 19| 0: Unknown literal
+# 19| Type = int
+# 19| ValueCategory = prvalue
+# 19| 1: constructor init of field y
+# 19| Type = int
+# 19| ValueCategory = prvalue
+# 19| 0: Unknown literal
+# 19| Type = int
+# 19| ValueCategory = prvalue
+# 19| body: { ... }
+# 19| 0: return ...
+# 19| Bad::Point::operator=(Point &&) -> Point &
+# 19| params:
+#-----| 0: p#0
+#-----| Type = Point &&
+# 19| Bad::Point::operator=(const Point &) -> Point &
+# 19| params:
+#-----| 0: p#0
+#-----| Type = const Point &
+# 22| Bad::Point::Point() -> void
+# 22| params:
+# 22| initializations:
+# 22| body: { ... }
+# 23| 0: return ...
+# 26| Bad::CallCopyConstructor(const Point &) -> void
+# 26| params:
+# 26| 0: a
+# 26| Type = const Point &
+# 26| body: { ... }
+# 27| 0: declaration
+# 27| 0: definition of b
+# 27| Type = Point
+# 27| init: initializer for b
+# 27| expr: (Point)...
+# 27| Conversion = glvalue conversion
+# 27| Type = Point
+# 27| ValueCategory = prvalue(load)
+# 27| expr: (reference dereference)
+# 27| Type = const Point
+# 27| ValueCategory = lvalue
+# 27| expr: a
+# 27| Type = const Point &
+# 27| ValueCategory = prvalue(load)
+# 28| 1: return ...
ir.cpp:
# 1| Constants() -> void
# 1| params:
@@ -6339,3 +6475,119 @@ ir.cpp:
# 963| Type = int
# 963| Value = 900
# 963| ValueCategory = prvalue
+# 966| IfStmtWithDeclaration(int, int) -> void
+# 966| params:
+# 966| 0: x
+# 966| Type = int
+# 966| 1: y
+# 966| Type = int
+# 966| body: { ... }
+# 967| 0: if (...) ...
+# 967| 0: (condition decl)
+# 967| Type = bool
+# 967| ValueCategory = prvalue
+# 967| 0: b
+# 967| Type = bool
+# 967| ValueCategory = prvalue(load)
+# 967| 1: { ... }
+# 968| 0: ExprStmt
+# 968| 0: ... = ...
+# 968| Type = int
+# 968| ValueCategory = lvalue
+# 968| 0: x
+# 968| Type = int
+# 968| ValueCategory = lvalue
+# 968| 1: 5
+# 968| Type = int
+# 968| Value = 5
+# 968| ValueCategory = prvalue
+# 970| 2: if (...) ...
+# 970| 0: (condition decl)
+# 970| Type = bool
+# 970| ValueCategory = prvalue
+# 970| 0: (bool)...
+# 970| Conversion = conversion to bool
+# 970| Type = bool
+# 970| ValueCategory = prvalue
+# 970| expr: z
+# 970| Type = int
+# 970| ValueCategory = prvalue(load)
+# 970| 1: { ... }
+# 971| 0: ExprStmt
+# 971| 0: ... = ...
+# 971| Type = int
+# 971| ValueCategory = lvalue
+# 971| 0: y
+# 971| Type = int
+# 971| ValueCategory = lvalue
+# 971| 1: 7
+# 971| Type = int
+# 971| Value = 7
+# 971| ValueCategory = prvalue
+# 973| 2: if (...) ...
+# 973| 0: (condition decl)
+# 973| Type = bool
+# 973| ValueCategory = prvalue
+# 973| 0: (bool)...
+# 973| Conversion = conversion to bool
+# 973| Type = bool
+# 973| ValueCategory = prvalue
+# 973| expr: p
+# 973| Type = int *
+# 973| ValueCategory = prvalue(load)
+# 973| 1: { ... }
+# 974| 0: ExprStmt
+# 974| 0: ... = ...
+# 974| Type = int
+# 974| ValueCategory = lvalue
+# 974| 0: * ...
+# 974| Type = int
+# 974| ValueCategory = lvalue
+# 974| 0: p
+# 974| Type = int *
+# 974| ValueCategory = prvalue(load)
+# 974| 1: 2
+# 974| Type = int
+# 974| Value = 2
+# 974| ValueCategory = prvalue
+# 976| 1: return ...
+# 978| WhileStmtWithDeclaration(int, int) -> void
+# 978| params:
+# 978| 0: x
+# 978| Type = int
+# 978| 1: y
+# 978| Type = int
+# 978| body: { ... }
+# 979| 0: while (...) ...
+# 979| 0: (condition decl)
+# 979| Type = bool
+# 979| ValueCategory = prvalue
+# 979| 0: b
+# 979| Type = bool
+# 979| ValueCategory = prvalue(load)
+# 979| 1: { ... }
+# 981| 1: while (...) ...
+# 981| 0: (condition decl)
+# 981| Type = bool
+# 981| ValueCategory = prvalue
+# 981| 0: (bool)...
+# 981| Conversion = conversion to bool
+# 981| Type = bool
+# 981| ValueCategory = prvalue
+# 981| expr: z
+# 981| Type = int
+# 981| ValueCategory = prvalue(load)
+# 981| 1: { ... }
+# 983| 2: while (...) ...
+# 983| 0: (condition decl)
+# 983| Type = bool
+# 983| ValueCategory = prvalue
+# 983| 0: (bool)...
+# 983| Conversion = conversion to bool
+# 983| Type = bool
+# 983| ValueCategory = prvalue
+# 983| expr: p
+# 983| Type = int *
+# 983| ValueCategory = prvalue(load)
+# 983| 1: { ... }
+# 985| 3: return ...
diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected
index 5fbbec2afb7..ab7f7ae43cb 100644
--- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected
+++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected
@@ -1,3 +1,49 @@
+bad_asts.cpp:
+# 14| Bad::CallBadMemberFunction() -> void
+# 14| Block 0
+# 14| v0_0(void) = EnterFunction :
+# 14| mu0_1(unknown) = UnmodeledDefinition :
+# 15| r0_2(glval) = VariableAddress[s] :
+# 15| mu0_3(S) = Uninitialized : r0_2
+# 15| r0_4(glval) = FieldAddress[x] : r0_2
+# 15| r0_5(int) = Constant[0] :
+# 15| mu0_6(int) = Store : r0_4, r0_5
+# 16| r0_7(glval) = VariableAddress[s] :
+# 16| r0_8(glval) = FunctionAddress[MemberFunction] :
+# 16| r0_9(int) = Constant[1] :
+# 16| r0_10(int) = Call : r0_8, this:r0_7, r0_9
+# 17| v0_11(void) = NoOp :
+# 14| v0_12(void) = ReturnVoid :
+# 14| v0_13(void) = UnmodeledUse : mu*
+# 14| v0_14(void) = ExitFunction :
+
+# 22| Bad::Point::Point() -> void
+# 22| Block 0
+# 22| v0_0(void) = EnterFunction :
+# 22| mu0_1(unknown) = UnmodeledDefinition :
+# 22| r0_2(glval) = InitializeThis :
+# 23| v0_3(void) = NoOp :
+# 22| v0_4(void) = ReturnVoid :
+# 22| v0_5(void) = UnmodeledUse : mu*
+# 22| v0_6(void) = ExitFunction :
+
+# 26| Bad::CallCopyConstructor(const Point &) -> void
+# 26| Block 0
+# 26| v0_0(void) = EnterFunction :
+# 26| mu0_1(unknown) = UnmodeledDefinition :
+# 26| r0_2(glval) = VariableAddress[a] :
+# 26| m0_3(Point &) = InitializeParameter[a] : r0_2
+# 27| r0_4(glval) = VariableAddress[b] :
+# 27| r0_5(glval) = VariableAddress[a] :
+# 27| r0_6(Point &) = Load : r0_5, m0_3
+# 27| r0_7(glval) = Convert : r0_6
+# 27| r0_8(Point) = Load : r0_7, mu0_1
+# 27| m0_9(Point) = Store : r0_4, r0_8
+# 28| v0_10(void) = NoOp :
+# 26| v0_11(void) = ReturnVoid :
+# 26| v0_12(void) = UnmodeledUse : mu*
+# 26| v0_13(void) = ExitFunction :
+
ir.cpp:
# 1| Constants() -> void
# 1| Block 0
@@ -2152,40 +2198,43 @@ ir.cpp:
# 503| r0_4(glval) = VariableAddress[f] :
# 503| m0_5(float) = InitializeParameter[f] : r0_4
# 504| r0_6(glval) = VariableAddress[pt1] :
-# 504| r0_7(glval) = FieldAddress[x] : r0_6
-# 504| r0_8(glval) = VariableAddress[x] :
-# 504| r0_9(int) = Load : r0_8, m0_3
-# 504| m0_10(int) = Store : r0_7, r0_9
-# 504| r0_11(glval) = FieldAddress[y] : r0_6
-# 504| r0_12(glval) = VariableAddress[f] :
-# 504| r0_13(float) = Load : r0_12, m0_5
-# 504| r0_14(int) = Convert : r0_13
-# 504| mu0_15(int) = Store : r0_11, r0_14
-# 505| r0_16(glval) = VariableAddress[pt2] :
-# 505| r0_17(glval) = FieldAddress[x] : r0_16
-# 505| r0_18(glval) = VariableAddress[x] :
-# 505| r0_19(int) = Load : r0_18, m0_3
-# 505| m0_20(int) = Store : r0_17, r0_19
-# 505| r0_21(glval) = FieldAddress[y] : r0_16
-# 505| r0_22(int) = Constant[0] :
-# 505| mu0_23(int) = Store : r0_21, r0_22
-# 506| r0_24(glval) = VariableAddress[pt3] :
-# 506| r0_25(glval) = FieldAddress[x] : r0_24
-# 506| r0_26(int) = Constant[0] :
-# 506| m0_27(int) = Store : r0_25, r0_26
-# 506| r0_28(glval) = FieldAddress[y] : r0_24
+# 504| m0_7(Point) = Uninitialized : r0_6
+# 504| r0_8(glval) = FieldAddress[x] : r0_6
+# 504| r0_9(glval) = VariableAddress[x] :
+# 504| r0_10(int) = Load : r0_9, m0_3
+# 504| m0_11(int) = Store : r0_8, r0_10
+# 504| r0_12(glval) = FieldAddress[y] : r0_6
+# 504| r0_13(glval) = VariableAddress[f] :
+# 504| r0_14(float) = Load : r0_13, m0_5
+# 504| r0_15(int) = Convert : r0_14
+# 504| mu0_16(int) = Store : r0_12, r0_15
+# 505| r0_17(glval) = VariableAddress[pt2] :
+# 505| m0_18(Point) = Uninitialized : r0_17
+# 505| r0_19(glval) = FieldAddress[x] : r0_17
+# 505| r0_20(glval) = VariableAddress[x] :
+# 505| r0_21(int) = Load : r0_20, m0_3
+# 505| m0_22(int) = Store : r0_19, r0_21
+# 505| r0_23(glval) = FieldAddress[y] : r0_17
+# 505| r0_24(int) = Constant[0] :
+# 505| mu0_25(int) = Store : r0_23, r0_24
+# 506| r0_26(glval) = VariableAddress[pt3] :
+# 506| m0_27(Point) = Uninitialized : r0_26
+# 506| r0_28(glval) = FieldAddress[x] : r0_26
# 506| r0_29(int) = Constant[0] :
-# 506| mu0_30(int) = Store : r0_28, r0_29
-# 508| r0_31(glval) = VariableAddress[x1] :
-# 508| r0_32(int) = Constant[1] :
-# 508| m0_33(int) = Store : r0_31, r0_32
-# 509| r0_34(glval) = VariableAddress[x2] :
-# 509| r0_35(int) = Constant[0] :
-# 509| m0_36(int) = Store : r0_34, r0_35
-# 510| v0_37(void) = NoOp :
-# 503| v0_38(void) = ReturnVoid :
-# 503| v0_39(void) = UnmodeledUse : mu*
-# 503| v0_40(void) = ExitFunction :
+# 506| m0_30(int) = Store : r0_28, r0_29
+# 506| r0_31(glval) = FieldAddress[y] : r0_26
+# 506| r0_32(int) = Constant[0] :
+# 506| mu0_33(int) = Store : r0_31, r0_32
+# 508| r0_34(glval) = VariableAddress[x1] :
+# 508| r0_35(int) = Constant[1] :
+# 508| m0_36(int) = Store : r0_34, r0_35
+# 509| r0_37(glval) = VariableAddress[x2] :
+# 509| r0_38(int) = Constant[0] :
+# 509| m0_39(int) = Store : r0_37, r0_38
+# 510| v0_40(void) = NoOp :
+# 503| v0_41(void) = ReturnVoid :
+# 503| v0_42(void) = UnmodeledUse : mu*
+# 503| v0_43(void) = ExitFunction :
# 512| NestedInitList(int, float) -> void
# 512| Block 0
@@ -2196,68 +2245,72 @@ ir.cpp:
# 512| r0_4(glval) = VariableAddress[f] :
# 512| m0_5(float) = InitializeParameter[f] : r0_4
# 513| r0_6(glval) = VariableAddress[r1] :
-# 513| r0_7(glval) = FieldAddress[topLeft] : r0_6
-# 513| r0_8(Point) = Constant[0] :
-# 513| m0_9(Point) = Store : r0_7, r0_8
-# 513| r0_10(glval) = FieldAddress[bottomRight] : r0_6
-# 513| r0_11(Point) = Constant[0] :
-# 513| mu0_12(Point) = Store : r0_10, r0_11
-# 514| r0_13(glval) = VariableAddress[r2] :
-# 514| r0_14(glval) = FieldAddress[topLeft] : r0_13
-# 514| r0_15(glval) = FieldAddress[x] : r0_14
-# 514| r0_16(glval) = VariableAddress[x] :
-# 514| r0_17(int) = Load : r0_16, m0_3
-# 514| m0_18(int) = Store : r0_15, r0_17
-# 514| r0_19(glval) = FieldAddress[y] : r0_14
-# 514| r0_20(glval) = VariableAddress[f] :
-# 514| r0_21(float) = Load : r0_20, m0_5
-# 514| r0_22(int) = Convert : r0_21
-# 514| mu0_23(int) = Store : r0_19, r0_22
-# 514| r0_24(glval) = FieldAddress[bottomRight] : r0_13
-# 514| r0_25(Point) = Constant[0] :
-# 514| mu0_26(Point) = Store : r0_24, r0_25
-# 515| r0_27(glval) = VariableAddress[r3] :
-# 515| r0_28(glval) = FieldAddress[topLeft] : r0_27
-# 515| r0_29(glval) = FieldAddress[x] : r0_28
-# 515| r0_30(glval) = VariableAddress[x] :
-# 515| r0_31(int) = Load : r0_30, m0_3
-# 515| m0_32(int) = Store : r0_29, r0_31
-# 515| r0_33(glval) = FieldAddress[y] : r0_28
-# 515| r0_34(glval) = VariableAddress[f] :
-# 515| r0_35(float) = Load : r0_34, m0_5
-# 515| r0_36(int) = Convert : r0_35
-# 515| mu0_37(int) = Store : r0_33, r0_36
-# 515| r0_38(glval) = FieldAddress[bottomRight] : r0_27
-# 515| r0_39(glval) = FieldAddress[x] : r0_38
-# 515| r0_40(glval) = VariableAddress[x] :
-# 515| r0_41(int) = Load : r0_40, m0_3
-# 515| mu0_42(int) = Store : r0_39, r0_41
-# 515| r0_43(glval) = FieldAddress[y] : r0_38
-# 515| r0_44(glval) = VariableAddress[f] :
-# 515| r0_45(float) = Load : r0_44, m0_5
-# 515| r0_46(int) = Convert : r0_45
-# 515| mu0_47(int) = Store : r0_43, r0_46
-# 516| r0_48(glval) = VariableAddress[r4] :
-# 516| r0_49(glval) = FieldAddress[topLeft] : r0_48
-# 516| r0_50(glval) = FieldAddress[x] : r0_49
-# 516| r0_51(glval) = VariableAddress[x] :
-# 516| r0_52(int) = Load : r0_51, m0_3
-# 516| m0_53(int) = Store : r0_50, r0_52
-# 516| r0_54(glval) = FieldAddress[y] : r0_49
-# 516| r0_55(int) = Constant[0] :
-# 516| mu0_56(int) = Store : r0_54, r0_55
-# 516| r0_57(glval) = FieldAddress[bottomRight] : r0_48
-# 516| r0_58(glval) = FieldAddress[x] : r0_57
-# 516| r0_59(glval) = VariableAddress[x] :
-# 516| r0_60(int) = Load : r0_59, m0_3
-# 516| mu0_61(int) = Store : r0_58, r0_60
-# 516| r0_62(glval) = FieldAddress[y] : r0_57
-# 516| r0_63(int) = Constant[0] :
-# 516| mu0_64(int) = Store : r0_62, r0_63
-# 517| v0_65(void) = NoOp :
-# 512| v0_66(void) = ReturnVoid :
-# 512| v0_67(void) = UnmodeledUse : mu*
-# 512| v0_68(void) = ExitFunction :
+# 513| m0_7(Rect) = Uninitialized : r0_6
+# 513| r0_8(glval) = FieldAddress[topLeft] : r0_6
+# 513| r0_9(Point) = Constant[0] :
+# 513| m0_10(Point) = Store : r0_8, r0_9
+# 513| r0_11(glval) = FieldAddress[bottomRight] : r0_6
+# 513| r0_12(Point) = Constant[0] :
+# 513| mu0_13(Point) = Store : r0_11, r0_12
+# 514| r0_14(glval) = VariableAddress[r2] :
+# 514| m0_15(Rect) = Uninitialized : r0_14
+# 514| r0_16(glval) = FieldAddress[topLeft] : r0_14
+# 514| r0_17(glval) = FieldAddress[x] : r0_16
+# 514| r0_18(glval) = VariableAddress[x] :
+# 514| r0_19(int) = Load : r0_18, m0_3
+# 514| m0_20(int) = Store : r0_17, r0_19
+# 514| r0_21(glval) = FieldAddress[y] : r0_16
+# 514| r0_22(glval) = VariableAddress[f] :
+# 514| r0_23(float) = Load : r0_22, m0_5
+# 514| r0_24(int) = Convert : r0_23
+# 514| mu0_25(int) = Store : r0_21, r0_24
+# 514| r0_26(glval) = FieldAddress[bottomRight] : r0_14
+# 514| r0_27(Point) = Constant[0] :
+# 514| mu0_28(Point) = Store : r0_26, r0_27
+# 515| r0_29(glval) = VariableAddress[r3] :
+# 515| m0_30(Rect) = Uninitialized : r0_29
+# 515| r0_31(glval) = FieldAddress[topLeft] : r0_29
+# 515| r0_32(glval) = FieldAddress[x] : r0_31
+# 515| r0_33(glval) = VariableAddress[x] :
+# 515| r0_34(int) = Load : r0_33, m0_3
+# 515| m0_35(int) = Store : r0_32, r0_34
+# 515| r0_36(glval) = FieldAddress[y] : r0_31
+# 515| r0_37(glval) = VariableAddress[f] :
+# 515| r0_38(float) = Load : r0_37, m0_5
+# 515| r0_39(int) = Convert : r0_38
+# 515| mu0_40(int) = Store : r0_36, r0_39
+# 515| r0_41(glval) = FieldAddress[bottomRight] : r0_29
+# 515| r0_42(glval) = FieldAddress[x] : r0_41
+# 515| r0_43(glval) = VariableAddress[x] :
+# 515| r0_44(int) = Load : r0_43, m0_3
+# 515| mu0_45(int) = Store : r0_42, r0_44
+# 515| r0_46(glval) = FieldAddress[y] : r0_41
+# 515| r0_47(glval) = VariableAddress[f] :
+# 515| r0_48(float) = Load : r0_47, m0_5
+# 515| r0_49(int) = Convert : r0_48
+# 515| mu0_50(int) = Store : r0_46, r0_49
+# 516| r0_51(glval) = VariableAddress[r4] :
+# 516| m0_52(Rect) = Uninitialized : r0_51
+# 516| r0_53(glval) = FieldAddress[topLeft] : r0_51
+# 516| r0_54(glval) = FieldAddress[x] : r0_53
+# 516| r0_55(glval) = VariableAddress[x] :
+# 516| r0_56(int) = Load : r0_55, m0_3
+# 516| m0_57(int) = Store : r0_54, r0_56
+# 516| r0_58(glval) = FieldAddress[y] : r0_53
+# 516| r0_59(int) = Constant[0] :
+# 516| mu0_60(int) = Store : r0_58, r0_59
+# 516| r0_61(glval) = FieldAddress[bottomRight] : r0_51
+# 516| r0_62(glval) = FieldAddress[x] : r0_61
+# 516| r0_63(glval) = VariableAddress[x] :
+# 516| r0_64(int) = Load : r0_63, m0_3
+# 516| mu0_65(int) = Store : r0_62, r0_64
+# 516| r0_66(glval) = FieldAddress[y] : r0_61
+# 516| r0_67(int) = Constant[0] :
+# 516| mu0_68(int) = Store : r0_66, r0_67
+# 517| v0_69(void) = NoOp :
+# 512| v0_70(void) = ReturnVoid :
+# 512| v0_71(void) = UnmodeledUse : mu*
+# 512| v0_72(void) = ExitFunction :
# 519| ArrayInit(int, float) -> void
# 519| Block 0
@@ -2268,40 +2321,43 @@ ir.cpp:
# 519| r0_4(glval) = VariableAddress[f] :
# 519| m0_5(float) = InitializeParameter[f] : r0_4
# 520| r0_6(glval) = VariableAddress[a1] :
-# 520| r0_7(int) = Constant[0] :
-# 520| r0_8(glval) = PointerAdd : r0_6, r0_7
-# 520| r0_9(unknown[12]) = Constant[0] :
-# 520| mu0_10(unknown[12]) = Store : r0_8, r0_9
-# 521| r0_11(glval) = VariableAddress[a2] :
-# 521| r0_12(int) = Constant[0] :
-# 521| r0_13(glval) = PointerAdd : r0_11, r0_12
-# 521| r0_14(glval) = VariableAddress[x] :
-# 521| r0_15(int) = Load : r0_14, m0_3
-# 521| mu0_16(int) = Store : r0_13, r0_15
-# 521| r0_17(int) = Constant[1] :
-# 521| r0_18(glval) = PointerAdd : r0_11, r0_17
-# 521| r0_19(glval) = VariableAddress[f] :
-# 521| r0_20(float) = Load : r0_19, m0_5
-# 521| r0_21(int) = Convert : r0_20
-# 521| mu0_22(int) = Store : r0_18, r0_21
-# 521| r0_23(int) = Constant[2] :
-# 521| r0_24(glval) = PointerAdd : r0_11, r0_23
-# 521| r0_25(int) = Constant[0] :
-# 521| mu0_26(int) = Store : r0_24, r0_25
-# 522| r0_27(glval) = VariableAddress[a3] :
-# 522| r0_28(int) = Constant[0] :
-# 522| r0_29(glval) = PointerAdd : r0_27, r0_28
-# 522| r0_30(glval) = VariableAddress[x] :
-# 522| r0_31(int) = Load : r0_30, m0_3
-# 522| mu0_32(int) = Store : r0_29, r0_31
-# 522| r0_33(int) = Constant[1] :
-# 522| r0_34(glval) = PointerAdd : r0_27, r0_33
-# 522| r0_35(unknown[8]) = Constant[0] :
-# 522| mu0_36(unknown[8]) = Store : r0_34, r0_35
-# 523| v0_37(void) = NoOp :
-# 519| v0_38(void) = ReturnVoid :
-# 519| v0_39(void) = UnmodeledUse : mu*
-# 519| v0_40(void) = ExitFunction :
+# 520| mu0_7(int[3]) = Uninitialized : r0_6
+# 520| r0_8(int) = Constant[0] :
+# 520| r0_9(glval) = PointerAdd : r0_6, r0_8
+# 520| r0_10(unknown[12]) = Constant[0] :
+# 520| mu0_11(unknown[12]) = Store : r0_9, r0_10
+# 521| r0_12(glval) = VariableAddress[a2] :
+# 521| mu0_13(int[3]) = Uninitialized : r0_12
+# 521| r0_14(int) = Constant[0] :
+# 521| r0_15(glval) = PointerAdd : r0_12, r0_14
+# 521| r0_16(glval) = VariableAddress[x] :
+# 521| r0_17(int) = Load : r0_16, m0_3
+# 521| mu0_18(int) = Store : r0_15, r0_17
+# 521| r0_19(int) = Constant[1] :
+# 521| r0_20(glval) = PointerAdd : r0_12, r0_19
+# 521| r0_21(glval) = VariableAddress[f] :
+# 521| r0_22(float) = Load : r0_21, m0_5
+# 521| r0_23(int) = Convert : r0_22
+# 521| mu0_24(int) = Store : r0_20, r0_23
+# 521| r0_25(int) = Constant[2] :
+# 521| r0_26(glval) = PointerAdd : r0_12, r0_25
+# 521| r0_27(int) = Constant[0] :
+# 521| mu0_28(int) = Store : r0_26, r0_27
+# 522| r0_29(glval) = VariableAddress[a3] :
+# 522| mu0_30(int[3]) = Uninitialized : r0_29
+# 522| r0_31(int) = Constant[0] :
+# 522| r0_32(glval) = PointerAdd : r0_29, r0_31
+# 522| r0_33(glval) = VariableAddress[x] :
+# 522| r0_34(int) = Load : r0_33, m0_3
+# 522| mu0_35(int) = Store : r0_32, r0_34
+# 522| r0_36(int) = Constant[1] :
+# 522| r0_37(glval) = PointerAdd : r0_29, r0_36
+# 522| r0_38(unknown[8]) = Constant[0] :
+# 522| mu0_39(unknown[8]) = Store : r0_37, r0_38
+# 523| v0_40(void) = NoOp :
+# 519| v0_41(void) = ReturnVoid :
+# 519| v0_42(void) = UnmodeledUse : mu*
+# 519| v0_43(void) = ExitFunction :
# 530| UnionInit(int, float) -> void
# 530| Block 0
@@ -2312,15 +2368,16 @@ ir.cpp:
# 530| r0_4(glval) = VariableAddress[f] :
# 530| m0_5(float) = InitializeParameter[f] : r0_4
# 531| r0_6(glval) = VariableAddress[u1] :
-# 531| r0_7(glval) = FieldAddress[d] : r0_6
-# 531| r0_8(glval) = VariableAddress[f] :
-# 531| r0_9(float) = Load : r0_8, m0_5
-# 531| r0_10(double) = Convert : r0_9
-# 531| m0_11(double) = Store : r0_7, r0_10
-# 533| v0_12(void) = NoOp :
-# 530| v0_13(void) = ReturnVoid :
-# 530| v0_14(void) = UnmodeledUse : mu*
-# 530| v0_15(void) = ExitFunction :
+# 531| m0_7(U) = Uninitialized : r0_6
+# 531| r0_8(glval) = FieldAddress[d] : r0_6
+# 531| r0_9(glval) = VariableAddress[f] :
+# 531| r0_10(float) = Load : r0_9, m0_5
+# 531| r0_11(double) = Convert : r0_10
+# 531| m0_12(double) = Store : r0_8, r0_11
+# 533| v0_13(void) = NoOp :
+# 530| v0_14(void) = ReturnVoid :
+# 530| v0_15(void) = UnmodeledUse : mu*
+# 530| v0_16(void) = ExitFunction :
# 535| EarlyReturn(int, int) -> void
# 535| Block 0
@@ -2479,41 +2536,45 @@ ir.cpp:
# 575| r0_18(glval) = VariableAddress[b] :
# 575| m0_19(char[2]) = Uninitialized : r0_18
# 576| r0_20(glval) = VariableAddress[c] :
-# 576| r0_21(int) = Constant[0] :
-# 576| r0_22(glval) = PointerAdd : r0_20, r0_21
-# 576| r0_23(unknown[2]) = Constant[0] :
-# 576| mu0_24(unknown[2]) = Store : r0_22, r0_23
-# 577| r0_25(glval) = VariableAddress[d] :
-# 577| r0_26(int) = Constant[0] :
-# 577| r0_27(glval) = PointerAdd : r0_25, r0_26
-# 577| r0_28(char) = Constant[0] :
-# 577| mu0_29(char) = Store : r0_27, r0_28
-# 577| r0_30(int) = Constant[1] :
-# 577| r0_31(glval) = PointerAdd : r0_25, r0_30
-# 577| r0_32(char) = Constant[0] :
-# 577| mu0_33(char) = Store : r0_31, r0_32
-# 578| r0_34(glval) = VariableAddress[e] :
-# 578| r0_35(int) = Constant[0] :
-# 578| r0_36(glval) = PointerAdd : r0_34, r0_35
-# 578| r0_37(char) = Constant[0] :
-# 578| mu0_38(char) = Store : r0_36, r0_37
-# 578| r0_39(int) = Constant[1] :
-# 578| r0_40(glval) = PointerAdd : r0_34, r0_39
-# 578| r0_41(char) = Constant[1] :
-# 578| mu0_42(char) = Store : r0_40, r0_41
-# 579| r0_43(glval) = VariableAddress[f] :
-# 579| r0_44(int) = Constant[0] :
-# 579| r0_45(glval) = PointerAdd : r0_43, r0_44
-# 579| r0_46(char) = Constant[0] :
-# 579| mu0_47(char) = Store : r0_45, r0_46
-# 579| r0_48(int) = Constant[1] :
-# 579| r0_49(glval) = PointerAdd : r0_43, r0_48
-# 579| r0_50(unknown[2]) = Constant[0] :
-# 579| mu0_51(unknown[2]) = Store : r0_49, r0_50
-# 580| v0_52(void) = NoOp :
-# 571| v0_53(void) = ReturnVoid :
-# 571| v0_54(void) = UnmodeledUse : mu*
-# 571| v0_55(void) = ExitFunction :
+# 576| mu0_21(char[2]) = Uninitialized : r0_20
+# 576| r0_22(int) = Constant[0] :
+# 576| r0_23(glval) = PointerAdd : r0_20, r0_22
+# 576| r0_24(unknown[2]) = Constant[0] :
+# 576| mu0_25(unknown[2]) = Store : r0_23, r0_24
+# 577| r0_26(glval) = VariableAddress[d] :
+# 577| mu0_27(char[2]) = Uninitialized : r0_26
+# 577| r0_28(int) = Constant[0] :
+# 577| r0_29(glval) = PointerAdd : r0_26, r0_28
+# 577| r0_30(char) = Constant[0] :
+# 577| mu0_31(char) = Store : r0_29, r0_30
+# 577| r0_32(int) = Constant[1] :
+# 577| r0_33(glval) = PointerAdd : r0_26, r0_32
+# 577| r0_34(char) = Constant[0] :
+# 577| mu0_35(char) = Store : r0_33, r0_34
+# 578| r0_36(glval) = VariableAddress[e] :
+# 578| mu0_37(char[2]) = Uninitialized : r0_36
+# 578| r0_38(int) = Constant[0] :
+# 578| r0_39(glval) = PointerAdd : r0_36, r0_38
+# 578| r0_40(char) = Constant[0] :
+# 578| mu0_41(char) = Store : r0_39, r0_40
+# 578| r0_42(int) = Constant[1] :
+# 578| r0_43(glval) = PointerAdd : r0_36, r0_42
+# 578| r0_44(char) = Constant[1] :
+# 578| mu0_45(char) = Store : r0_43, r0_44
+# 579| r0_46(glval) = VariableAddress[f] :
+# 579| mu0_47(char[3]) = Uninitialized : r0_46
+# 579| r0_48(int) = Constant[0] :
+# 579| r0_49(glval) = PointerAdd : r0_46, r0_48
+# 579| r0_50(char) = Constant[0] :
+# 579| mu0_51(char) = Store : r0_49, r0_50
+# 579| r0_52(int) = Constant[1] :
+# 579| r0_53(glval) = PointerAdd : r0_46, r0_52
+# 579| r0_54(unknown[2]) = Constant[0] :
+# 579| mu0_55(unknown[2]) = Store : r0_53, r0_54
+# 580| v0_56(void) = NoOp :
+# 571| v0_57(void) = ReturnVoid :
+# 571| v0_58(void) = UnmodeledUse : mu*
+# 571| v0_59(void) = ExitFunction :
# 584| VarArgs() -> void
# 584| Block 0
@@ -3912,10 +3973,11 @@ ir.cpp:
# 961| v0_0(void) = EnterFunction :
# 961| mu0_1(unknown) = UnmodeledDefinition :
# 962| r0_2(glval) = VariableAddress[a1] :
-# 962| r0_3(int) = Constant[0] :
-# 962| r0_4(glval) = PointerAdd : r0_2, r0_3
-# 962| r0_5(unknown[8]) = Constant[0] :
-# 962| mu0_6(unknown[8]) = Store : r0_4, r0_5
+# 962| mu0_3(int[1000]) = Uninitialized : r0_2
+# 962| r0_4(int) = Constant[0] :
+# 962| r0_5(glval) = PointerAdd : r0_2, r0_4
+# 962| r0_6(unknown[8]) = Constant[0] :
+# 962| mu0_7(unknown[8]) = Store : r0_5, r0_6
#-----| Goto -> Block 2
# 962| Block 1
@@ -3952,3 +4014,147 @@ ir.cpp:
# 962| r3_6(unknown[3588]) = Constant[0] :
# 962| mu3_7(unknown[3588]) = Store : r3_5, r3_6
#-----| Goto -> Block 2
+
+# 966| IfStmtWithDeclaration(int, int) -> void
+# 966| Block 0
+# 966| v0_0(void) = EnterFunction :
+# 966| mu0_1(unknown) = UnmodeledDefinition :
+# 966| r0_2(glval) = VariableAddress[x] :
+# 966| m0_3(int) = InitializeParameter[x] : r0_2
+# 966| r0_4(glval) = VariableAddress[y] :
+# 966| m0_5(int) = InitializeParameter[y] : r0_4
+# 967| r0_6(glval) = VariableAddress[b] :
+# 967| r0_7(glval) = VariableAddress[x] :
+# 967| r0_8(int) = Load : r0_7, m0_3
+# 967| r0_9(glval) = VariableAddress[y] :
+# 967| r0_10(int) = Load : r0_9, m0_5
+# 967| r0_11(bool) = CompareLT : r0_8, r0_10
+# 967| m0_12(bool) = Store : r0_6, r0_11
+# 967| r0_13(glval) = VariableAddress[b] :
+# 967| r0_14(bool) = Load : r0_13, m0_12
+# 967| v0_15(void) = ConditionalBranch : r0_14
+#-----| False -> Block 2
+#-----| True -> Block 1
+
+# 968| Block 1
+# 968| r1_0(int) = Constant[5] :
+# 968| r1_1(glval) = VariableAddress[x] :
+# 968| m1_2(int) = Store : r1_1, r1_0
+#-----| Goto -> Block 6
+
+# 970| Block 2
+# 970| r2_0(glval) = VariableAddress[z] :
+# 970| r2_1(glval) = VariableAddress[x] :
+# 970| r2_2(int) = Load : r2_1, m0_3
+# 970| r2_3(glval) = VariableAddress[y] :
+# 970| r2_4(int) = Load : r2_3, m0_5
+# 970| r2_5(int) = Add : r2_2, r2_4
+# 970| m2_6(int) = Store : r2_0, r2_5
+# 970| r2_7(glval) = VariableAddress[z] :
+# 970| r2_8(int) = Load : r2_7, m2_6
+# 970| r2_9(int) = Constant[0] :
+# 970| r2_10(bool) = CompareNE : r2_8, r2_9
+# 970| v2_11(void) = ConditionalBranch : r2_10
+#-----| False -> Block 4
+#-----| True -> Block 3
+
+# 971| Block 3
+# 971| r3_0(int) = Constant[7] :
+# 971| r3_1(glval) = VariableAddress[y] :
+# 971| m3_2(int) = Store : r3_1, r3_0
+#-----| Goto -> Block 6
+
+# 973| Block 4
+# 973| r4_0(glval) = VariableAddress[p] :
+# 973| r4_1(glval) = VariableAddress[x] :
+# 973| m4_2(int *) = Store : r4_0, r4_1
+# 973| r4_3(glval) = VariableAddress[p] :
+# 973| r4_4(int *) = Load : r4_3, m4_2
+# 973| r4_5(int *) = Constant[0] :
+# 973| r4_6(bool) = CompareNE : r4_4, r4_5
+# 973| v4_7(void) = ConditionalBranch : r4_6
+#-----| False -> Block 6
+#-----| True -> Block 5
+
+# 974| Block 5
+# 974| r5_0(int) = Constant[2] :
+# 974| r5_1(glval) = VariableAddress[p] :
+# 974| r5_2(int *) = Load : r5_1, m4_2
+# 974| m5_3(int) = Store : r5_2, r5_0
+#-----| Goto -> Block 6
+
+# 976| Block 6
+# 976| v6_0(void) = NoOp :
+# 966| v6_1(void) = ReturnVoid :
+# 966| v6_2(void) = UnmodeledUse : mu*
+# 966| v6_3(void) = ExitFunction :
+
+# 978| WhileStmtWithDeclaration(int, int) -> void
+# 978| Block 0
+# 978| v0_0(void) = EnterFunction :
+# 978| mu0_1(unknown) = UnmodeledDefinition :
+# 978| r0_2(glval) = VariableAddress[x] :
+# 978| m0_3(int) = InitializeParameter[x] : r0_2
+# 978| r0_4(glval) = VariableAddress[y] :
+# 978| m0_5(int) = InitializeParameter[y] : r0_4
+#-----| Goto -> Block 7
+
+# 979| Block 1
+# 979| v1_0(void) = NoOp :
+#-----| Goto -> Block 7
+
+# 981| Block 2
+# 981| r2_0(glval) = VariableAddress[z] :
+# 981| r2_1(glval) = VariableAddress[x] :
+# 981| r2_2(int) = Load : r2_1, m0_3
+# 981| r2_3(glval) = VariableAddress[y] :
+# 981| r2_4(int) = Load : r2_3, m0_5
+# 981| r2_5(int) = Add : r2_2, r2_4
+# 981| m2_6(int) = Store : r2_0, r2_5
+# 981| r2_7(glval) = VariableAddress[z] :
+# 981| r2_8(int) = Load : r2_7, m2_6
+# 981| r2_9(int) = Constant[0] :
+# 981| r2_10(bool) = CompareNE : r2_8, r2_9
+# 981| v2_11(void) = ConditionalBranch : r2_10
+#-----| False -> Block 4
+#-----| True -> Block 3
+
+# 981| Block 3
+# 981| v3_0(void) = NoOp :
+#-----| Goto -> Block 2
+
+# 983| Block 4
+# 983| r4_0(glval) = VariableAddress[p] :
+# 983| r4_1(glval) = VariableAddress[x] :
+# 983| m4_2(int *) = Store : r4_0, r4_1
+# 983| r4_3(glval) = VariableAddress[p] :
+# 983| r4_4(int *) = Load : r4_3, m4_2
+# 983| r4_5(int *) = Constant[0] :
+# 983| r4_6(bool) = CompareNE : r4_4, r4_5
+# 983| v4_7(void) = ConditionalBranch : r4_6
+#-----| False -> Block 6
+#-----| True -> Block 5
+
+# 983| Block 5
+# 983| v5_0(void) = NoOp :
+#-----| Goto -> Block 4
+
+# 985| Block 6
+# 985| v6_0(void) = NoOp :
+# 978| v6_1(void) = ReturnVoid :
+# 978| v6_2(void) = UnmodeledUse : mu*
+# 978| v6_3(void) = ExitFunction :
+
+# 979| Block 7
+# 979| r7_0(glval) = VariableAddress[b] :
+# 979| r7_1(glval) = VariableAddress[x] :
+# 979| r7_2(int) = Load : r7_1, m0_3
+# 979| r7_3(glval) = VariableAddress[y] :
+# 979| r7_4(int) = Load : r7_3, m0_5
+# 979| r7_5(bool) = CompareLT : r7_2, r7_4
+# 979| m7_6(bool) = Store : r7_0, r7_5
+# 979| r7_7(glval) = VariableAddress[b] :
+# 979| r7_8(bool) = Load : r7_7, m7_6
+# 979| v7_9(void) = ConditionalBranch : r7_8
+#-----| False -> Block 2
+#-----| True -> Block 1
diff --git a/cpp/ql/test/library-tests/ir/ir/bad_asts.cpp b/cpp/ql/test/library-tests/ir/ir/bad_asts.cpp
new file mode 100644
index 00000000000..6bd726959c7
--- /dev/null
+++ b/cpp/ql/test/library-tests/ir/ir/bad_asts.cpp
@@ -0,0 +1,29 @@
+// semmle-extractor-options: -std=c++17
+
+// Test cases that illustrate known bad ASTs that we have to work around in IR generation.
+namespace Bad {
+ struct S {
+ int x;
+
+ template
+ int MemberFunction(int y) {
+ return t + x + y;
+ }
+ };
+
+ void CallBadMemberFunction() {
+ S s = {};
+ s.MemberFunction<6>(1); // Not marked as member function in AST.
+ }
+
+ struct Point {
+ int x;
+ int y;
+ Point() {
+ }
+ };
+
+ void CallCopyConstructor(const Point& a) {
+ Point b = a; // Copy constructor contains literal expressions with no values.
+ }
+}
diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp
index 3ff4c53c17e..95486aa55e1 100644
--- a/cpp/ql/test/library-tests/ir/ir/ir.cpp
+++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp
@@ -963,6 +963,27 @@ int designatedInit() {
return a1[900];
}
+void IfStmtWithDeclaration(int x, int y) {
+ if (bool b = x < y) {
+ x = 5;
+ }
+ else if (int z = x + y) {
+ y = 7;
+ }
+ else if (int* p = &x) {
+ *p = 2;
+ }
+}
+
+void WhileStmtWithDeclaration(int x, int y) {
+ while (bool b = x < y) {
+ }
+ while (int z = x + y) {
+ }
+ while (int* p = &x) {
+ }
+}
+
#if 0
void OperatorDelete() {
delete static_cast(nullptr); // No destructor
diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
index 5f5dc4d3f5d..15f3f0867ac 100644
--- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
+++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
@@ -1,3 +1,49 @@
+bad_asts.cpp:
+# 14| Bad::CallBadMemberFunction() -> void
+# 14| Block 0
+# 14| v0_0(void) = EnterFunction :
+# 14| mu0_1(unknown) = UnmodeledDefinition :
+# 15| r0_2(glval) = VariableAddress[s] :
+# 15| mu0_3(S) = Uninitialized : r0_2
+# 15| r0_4(glval) = FieldAddress[x] : r0_2
+# 15| r0_5(int) = Constant[0] :
+# 15| mu0_6(int) = Store : r0_4, r0_5
+# 16| r0_7(glval) = VariableAddress[s] :
+# 16| r0_8(glval) = FunctionAddress[MemberFunction] :
+# 16| r0_9(int) = Constant[1] :
+# 16| r0_10(int) = Call : r0_8, this:r0_7, r0_9
+# 17| v0_11(void) = NoOp :
+# 14| v0_12(void) = ReturnVoid :
+# 14| v0_13(void) = UnmodeledUse : mu*
+# 14| v0_14(void) = ExitFunction :
+
+# 22| Bad::Point::Point() -> void
+# 22| Block 0
+# 22| v0_0(void) = EnterFunction :
+# 22| mu0_1(unknown) = UnmodeledDefinition :
+# 22| r0_2(glval) = InitializeThis :
+# 23| v0_3(void) = NoOp :
+# 22| v0_4(void) = ReturnVoid :
+# 22| v0_5(void) = UnmodeledUse : mu*
+# 22| v0_6(void) = ExitFunction :
+
+# 26| Bad::CallCopyConstructor(const Point &) -> void
+# 26| Block 0
+# 26| v0_0(void) = EnterFunction :
+# 26| mu0_1(unknown) = UnmodeledDefinition :
+# 26| r0_2(glval) = VariableAddress[a] :
+# 26| mu0_3(Point &) = InitializeParameter[a] : r0_2
+# 27| r0_4(glval) = VariableAddress[b] :
+# 27| r0_5(glval) = VariableAddress[a] :
+# 27| r0_6(Point &) = Load : r0_5, mu0_1
+# 27| r0_7(glval) = Convert : r0_6
+# 27| r0_8(Point) = Load : r0_7, mu0_1
+# 27| mu0_9(Point) = Store : r0_4, r0_8
+# 28| v0_10(void) = NoOp :
+# 26| v0_11(void) = ReturnVoid :
+# 26| v0_12(void) = UnmodeledUse : mu*
+# 26| v0_13(void) = ExitFunction :
+
ir.cpp:
# 1| Constants() -> void
# 1| Block 0
@@ -2135,40 +2181,43 @@ ir.cpp:
# 503| r0_4(glval) = VariableAddress[f] :
# 503| mu0_5(float) = InitializeParameter[f] : r0_4
# 504| r0_6(glval) = VariableAddress[pt1] :
-# 504| r0_7(glval) = FieldAddress[x] : r0_6
-# 504| r0_8(glval) = VariableAddress[x] :
-# 504| r0_9(int) = Load : r0_8, mu0_1
-# 504| mu0_10(int) = Store : r0_7, r0_9
-# 504| r0_11(glval) = FieldAddress[y] : r0_6
-# 504| r0_12(glval) = VariableAddress[f] :
-# 504| r0_13(float) = Load : r0_12, mu0_1
-# 504| r0_14(int) = Convert : r0_13
-# 504| mu0_15(int) = Store : r0_11, r0_14
-# 505| r0_16(glval) = VariableAddress[pt2] :
-# 505| r0_17(glval) = FieldAddress[x] : r0_16
-# 505| r0_18(glval) = VariableAddress[x] :
-# 505| r0_19(int) = Load : r0_18, mu0_1
-# 505| mu0_20(int) = Store : r0_17, r0_19
-# 505| r0_21(glval) = FieldAddress[y] : r0_16
-# 505| r0_22(int) = Constant[0] :
-# 505| mu0_23(int) = Store : r0_21, r0_22
-# 506| r0_24(glval) = VariableAddress[pt3] :
-# 506| r0_25(glval) = FieldAddress[x] : r0_24
-# 506| r0_26(int) = Constant[0] :
-# 506| mu0_27(int) = Store : r0_25, r0_26
-# 506| r0_28(glval) = FieldAddress[y] : r0_24
+# 504| mu0_7(Point) = Uninitialized : r0_6
+# 504| r0_8(glval) = FieldAddress[x] : r0_6
+# 504| r0_9(glval) = VariableAddress[x] :
+# 504| r0_10(int) = Load : r0_9, mu0_1
+# 504| mu0_11(int) = Store : r0_8, r0_10
+# 504| r0_12(glval) = FieldAddress[y] : r0_6
+# 504| r0_13(glval) = VariableAddress[f] :
+# 504| r0_14(float) = Load : r0_13, mu0_1
+# 504| r0_15(int) = Convert : r0_14
+# 504| mu0_16(int) = Store : r0_12, r0_15
+# 505| r0_17(glval) = VariableAddress[pt2] :
+# 505| mu0_18(Point) = Uninitialized : r0_17
+# 505| r0_19(glval) = FieldAddress[x] : r0_17
+# 505| r0_20(glval) = VariableAddress[x] :
+# 505| r0_21(int) = Load : r0_20, mu0_1
+# 505| mu0_22(int) = Store : r0_19, r0_21
+# 505| r0_23(glval) = FieldAddress[y] : r0_17
+# 505| r0_24(int) = Constant[0] :
+# 505| mu0_25(int) = Store : r0_23, r0_24
+# 506| r0_26(glval) = VariableAddress[pt3] :
+# 506| mu0_27(Point) = Uninitialized : r0_26
+# 506| r0_28(glval) = FieldAddress[x] : r0_26
# 506| r0_29(int) = Constant[0] :
# 506| mu0_30(int) = Store : r0_28, r0_29
-# 508| r0_31(glval) = VariableAddress[x1] :
-# 508| r0_32(int) = Constant[1] :
-# 508| mu0_33(int) = Store : r0_31, r0_32
-# 509| r0_34(glval) = VariableAddress[x2] :
-# 509| r0_35(int) = Constant[0] :
-# 509| mu0_36(int) = Store : r0_34, r0_35
-# 510| v0_37(void) = NoOp :
-# 503| v0_38(void) = ReturnVoid :
-# 503| v0_39(void) = UnmodeledUse : mu*
-# 503| v0_40(void) = ExitFunction :
+# 506| r0_31(glval) = FieldAddress[y] : r0_26
+# 506| r0_32(int) = Constant[0] :
+# 506| mu0_33(int) = Store : r0_31, r0_32
+# 508| r0_34(glval) = VariableAddress[x1] :
+# 508| r0_35(int) = Constant[1] :
+# 508| mu0_36(int) = Store : r0_34, r0_35
+# 509| r0_37(glval) = VariableAddress[x2] :
+# 509| r0_38(int) = Constant[0] :
+# 509| mu0_39(int) = Store : r0_37, r0_38
+# 510| v0_40(void) = NoOp :
+# 503| v0_41(void) = ReturnVoid :
+# 503| v0_42(void) = UnmodeledUse : mu*
+# 503| v0_43(void) = ExitFunction :
# 512| NestedInitList(int, float) -> void
# 512| Block 0
@@ -2179,68 +2228,72 @@ ir.cpp:
# 512| r0_4(glval) = VariableAddress[f] :
# 512| mu0_5(float) = InitializeParameter[f] : r0_4
# 513| r0_6(glval) = VariableAddress[r1] :
-# 513| r0_7(glval) = FieldAddress[topLeft] : r0_6
-# 513| r0_8(Point) = Constant[0] :
-# 513| mu0_9(Point) = Store : r0_7, r0_8
-# 513| r0_10(glval) = FieldAddress[bottomRight] : r0_6
-# 513| r0_11(Point) = Constant[0] :
-# 513| mu0_12(Point) = Store : r0_10, r0_11
-# 514| r0_13(glval) = VariableAddress[r2] :
-# 514| r0_14(glval) = FieldAddress[topLeft] : r0_13
-# 514| r0_15(glval) = FieldAddress[x] : r0_14
-# 514| r0_16(glval) = VariableAddress[x] :
-# 514| r0_17(int) = Load : r0_16, mu0_1
-# 514| mu0_18(int) = Store : r0_15, r0_17
-# 514| r0_19(glval) = FieldAddress[y] : r0_14
-# 514| r0_20(glval) = VariableAddress[f] :
-# 514| r0_21(float) = Load : r0_20, mu0_1
-# 514| r0_22(int) = Convert : r0_21
-# 514| mu0_23(int) = Store : r0_19, r0_22
-# 514| r0_24(glval) = FieldAddress[bottomRight] : r0_13
-# 514| r0_25(Point) = Constant[0] :
-# 514| mu0_26(Point) = Store : r0_24, r0_25
-# 515| r0_27(glval) = VariableAddress[r3] :
-# 515| r0_28(glval) = FieldAddress[topLeft] : r0_27
-# 515| r0_29(glval) = FieldAddress[x] : r0_28
-# 515| r0_30(glval) = VariableAddress[x] :
-# 515| r0_31(int) = Load : r0_30, mu0_1
-# 515| mu0_32(int) = Store : r0_29, r0_31
-# 515| r0_33(glval) = FieldAddress[y] : r0_28
-# 515| r0_34(glval) = VariableAddress[f] :
-# 515| r0_35(float) = Load : r0_34, mu0_1
-# 515| r0_36(int) = Convert : r0_35
-# 515| mu0_37(int) = Store : r0_33, r0_36
-# 515| r0_38(glval) = FieldAddress[bottomRight] : r0_27
-# 515| r0_39(glval) = FieldAddress[x] : r0_38
-# 515| r0_40(glval) = VariableAddress[x] :
-# 515| r0_41(int) = Load : r0_40, mu0_1
-# 515| mu0_42(int) = Store : r0_39, r0_41
-# 515| r0_43(glval) = FieldAddress[y] : r0_38
-# 515| r0_44(glval) = VariableAddress[f] :
-# 515| r0_45(float) = Load : r0_44, mu0_1
-# 515| r0_46(int) = Convert : r0_45
-# 515| mu0_47(int) = Store : r0_43, r0_46
-# 516| r0_48(glval) = VariableAddress[r4] :
-# 516| r0_49(glval) = FieldAddress[topLeft] : r0_48
-# 516| r0_50(glval) = FieldAddress[x] : r0_49
-# 516| r0_51(glval) = VariableAddress[x] :
-# 516| r0_52(int) = Load : r0_51, mu0_1
-# 516| mu0_53(int) = Store : r0_50, r0_52
-# 516| r0_54(glval) = FieldAddress[y] : r0_49
-# 516| r0_55(int) = Constant[0] :
-# 516| mu0_56(int) = Store : r0_54, r0_55
-# 516| r0_57(glval) = FieldAddress[bottomRight] : r0_48
-# 516| r0_58(glval) = FieldAddress[x] : r0_57
-# 516| r0_59(glval) = VariableAddress[x] :
-# 516| r0_60(int) = Load : r0_59, mu0_1
-# 516| mu0_61(int) = Store : r0_58, r0_60
-# 516| r0_62(glval) = FieldAddress[y] : r0_57
-# 516| r0_63(int) = Constant[0] :
-# 516| mu0_64(int) = Store : r0_62, r0_63
-# 517| v0_65(void) = NoOp :
-# 512| v0_66(void) = ReturnVoid :
-# 512| v0_67(void) = UnmodeledUse : mu*
-# 512| v0_68(void) = ExitFunction :
+# 513| mu0_7(Rect) = Uninitialized : r0_6
+# 513| r0_8(glval) = FieldAddress[topLeft] : r0_6
+# 513| r0_9(Point) = Constant[0] :
+# 513| mu0_10(Point) = Store : r0_8, r0_9
+# 513| r0_11(glval) = FieldAddress[bottomRight] : r0_6
+# 513| r0_12(Point) = Constant[0] :
+# 513| mu0_13(Point) = Store : r0_11, r0_12
+# 514| r0_14(glval