Skip to content

Commit 02ac61f

Browse files
authored
Merge pull request #18483 from jketema/extractor-fixes
C++: Fix types of struct/union templates and fix assumptions on proxy classes
2 parents f62a3ac + a3cd668 commit 02ac61f

File tree

22 files changed

+9724
-37
lines changed

22 files changed

+9724
-37
lines changed

cpp/downgrades/a01d8f91b8d49259e509b574962dec90719f69a6/old.dbscheme

Lines changed: 2415 additions & 0 deletions
Large diffs are not rendered by default.

cpp/downgrades/a01d8f91b8d49259e509b574962dec90719f69a6/semmlecode.cpp.dbscheme

Lines changed: 2409 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
description: Improve user types and proxy classes
2+
compatibility: full
3+
usertypes.rel: run usertypes.qlo
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class UserType extends @usertype {
2+
string toString() { none() }
3+
}
4+
5+
bindingset[kind]
6+
int getKind(int kind) { if kind in [15, 16, 17] then result = 6 else result = kind }
7+
8+
from UserType usertype, string name, int kind
9+
where usertypes(usertype, name, kind)
10+
select usertype, name, getKind(kind)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
category: feature
3+
---
4+
* A new predicate `getDecltype`was added to the `ProxyClass` class, which yields the decltype for the proxy class.
5+
* Template classes that are of `struct` type are now also instances of the `Struct` class.
6+
* Template classes that are of `union` type are now also instances of the `Union` class.

cpp/ql/lib/semmle/code/cpp/Class.qll

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ class AbstractClass extends Class {
869869
* `FullClassTemplateSpecialization`.
870870
*/
871871
class TemplateClass extends Class {
872-
TemplateClass() { usertypes(underlyingElement(this), _, 6) }
872+
TemplateClass() { usertypes(underlyingElement(this), _, [15, 16, 17]) }
873873

874874
/**
875875
* Gets a class instantiated from this template.
@@ -1076,13 +1076,19 @@ class VirtualBaseClass extends Class {
10761076
}
10771077

10781078
/**
1079-
* The proxy class (where needed) associated with a template parameter, as
1080-
* in the following code:
1081-
* ```
1079+
* The proxy class (where needed) associated with a template parameter or a
1080+
* decltype, as in the following code:
1081+
* ```cpp
10821082
* template <typename T>
10831083
* struct S : T { // the type of this T is a proxy class
10841084
* ...
10851085
* };
1086+
*
1087+
* template <typename T>
1088+
* concept C =
1089+
* decltype(std::span{std::declval<T&>()})::extent
1090+
* != std::dynamic_extent;
1091+
* // the type of decltype(std::span{std::declval<T&>()}) is a proxy class
10861092
* ```
10871093
*/
10881094
class ProxyClass extends UserType {
@@ -1093,10 +1099,13 @@ class ProxyClass extends UserType {
10931099
/** Gets the location of the proxy class. */
10941100
override Location getLocation() { result = this.getTemplateParameter().getDefinitionLocation() }
10951101

1096-
/** Gets the template parameter for which this is the proxy class. */
1102+
/** Gets the template parameter for which this is the proxy class, if any. */
10971103
TypeTemplateParameter getTemplateParameter() {
10981104
is_proxy_class_for(underlyingElement(this), unresolveElement(result))
10991105
}
1106+
1107+
/** Gets the decltype for which this is the proxy class, if any. */
1108+
Decltype getDecltype() { is_proxy_class_for(underlyingElement(this), unresolveElement(result)) }
11001109
}
11011110

11021111
// Unpacks "array of ... of array of t" into t.

cpp/ql/lib/semmle/code/cpp/Struct.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import semmle.code.cpp.Class
2020
* ```
2121
*/
2222
class Struct extends Class {
23-
Struct() { usertypes(underlyingElement(this), _, 1) or usertypes(underlyingElement(this), _, 3) }
23+
Struct() { usertypes(underlyingElement(this), _, [1, 3, 15, 17]) }
2424

2525
override string getAPrimaryQlClass() { result = "Struct" }
2626

cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ deprecated class TemplateParameter = TypeTemplateParameter;
5252
* ```
5353
*/
5454
class TypeTemplateParameter extends UserType, TemplateParameterImpl {
55-
TypeTemplateParameter() {
56-
usertypes(underlyingElement(this), _, 7) or usertypes(underlyingElement(this), _, 8)
57-
}
55+
TypeTemplateParameter() { usertypes(underlyingElement(this), _, [7, 8]) }
5856

5957
override string getAPrimaryQlClass() { result = "TypeTemplateParameter" }
6058

cpp/ql/lib/semmle/code/cpp/Type.qll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,10 +406,7 @@ class IntegralOrEnumType extends Type {
406406
isIntegralType(underlyingElement(this), _)
407407
or
408408
// Enum type
409-
(
410-
usertypes(underlyingElement(this), _, 4) or
411-
usertypes(underlyingElement(this), _, 13)
412-
)
409+
usertypes(underlyingElement(this), _, [4, 13])
413410
}
414411
}
415412

cpp/ql/lib/semmle/code/cpp/TypedefType.qll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ private import semmle.code.cpp.internal.ResolveClass
1313
* ```
1414
*/
1515
class TypedefType extends UserType {
16-
TypedefType() {
17-
usertypes(underlyingElement(this), _, 5) or
18-
usertypes(underlyingElement(this), _, 14)
19-
}
16+
TypedefType() { usertypes(underlyingElement(this), _, [5, 14]) }
2017

2118
/**
2219
* Gets the base type of this typedef type.

0 commit comments

Comments
 (0)