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

+2,415
Large diffs are not rendered by default.

cpp/downgrades/a01d8f91b8d49259e509b574962dec90719f69a6/semmlecode.cpp.dbscheme

+2,409
Large diffs are not rendered by default.
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
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)
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

+14-5
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

+1-1
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

+1-3
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

+1-4
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

+1-4
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.

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import semmle.code.cpp.Struct
1515
* ```
1616
*/
1717
class Union extends Struct {
18-
Union() { usertypes(underlyingElement(this), _, 3) }
18+
Union() { usertypes(underlyingElement(this), _, [3, 17]) }
1919

2020
override string getAPrimaryQlClass() { result = "Union" }
2121

cpp/ql/lib/semmle/code/cpp/internal/QualifiedName.qll

+2-2
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,11 @@ class ProxyClass extends UserType {
227227
}
228228

229229
class TypeTemplateParameter extends UserType {
230-
TypeTemplateParameter() { usertypes(this, _, 7) or usertypes(this, _, 8) }
230+
TypeTemplateParameter() { usertypes(this, _, [7, 8]) }
231231
}
232232

233233
class TemplateClass extends UserType {
234-
TemplateClass() { usertypes(this, _, 6) }
234+
TemplateClass() { usertypes(this, _, [15, 16, 17]) }
235235

236236
UserType getAnInstantiation() {
237237
class_instantiation(result, this) and

cpp/ql/lib/semmle/code/cpp/internal/ResolveClass.qll

+1-9
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,7 @@ private module Cached {
114114
* Holds if `t` is a struct, class, union, or template.
115115
*/
116116
cached
117-
predicate isClass(@usertype t) {
118-
usertypes(t, _, 1) or
119-
usertypes(t, _, 2) or
120-
usertypes(t, _, 3) or
121-
usertypes(t, _, 6) or
122-
usertypes(t, _, 10) or
123-
usertypes(t, _, 11) or
124-
usertypes(t, _, 12)
125-
}
117+
predicate isClass(@usertype t) { usertypes(t, _, [1, 2, 3, 15, 16, 17]) }
126118

127119
cached
128120
predicate isType(@type t) {

cpp/ql/lib/semmlecode.cpp.dbscheme

+9-3
Original file line numberDiff line numberDiff line change
@@ -771,12 +771,13 @@ decltypes(
771771

772772
/*
773773
case @usertype.kind of
774-
1 = @struct
774+
| 0 = @unknown_usertype
775+
| 1 = @struct
775776
| 2 = @class
776777
| 3 = @union
777778
| 4 = @enum
778779
| 5 = @typedef // classic C: typedef typedef type name
779-
| 6 = @template
780+
// ... 6 = @template deprecated
780781
| 7 = @template_parameter
781782
| 8 = @template_template_parameter
782783
| 9 = @proxy_class // a proxy class associated with a template parameter
@@ -785,6 +786,9 @@ case @usertype.kind of
785786
// ... 12 objc_category deprecated
786787
| 13 = @scoped_enum
787788
| 14 = @using_alias // a using name = type style typedef
789+
| 15 = @template_struct
790+
| 16 = @template_class
791+
| 17 = @template_union
788792
;
789793
*/
790794

@@ -843,9 +847,11 @@ class_template_argument_value(
843847
int arg_value: @expr ref
844848
);
845849

850+
@user_or_decltype = @usertype | @decltype;
851+
846852
is_proxy_class_for(
847853
unique int id: @usertype ref,
848-
unique int templ_param_id: @usertype ref
854+
int templ_param_id: @user_or_decltype ref
849855
);
850856

851857
type_mentions(

0 commit comments

Comments
 (0)