Skip to content

Commit

Permalink
Merge pull request #18483 from jketema/extractor-fixes
Browse files Browse the repository at this point in the history
C++: Fix types of struct/union templates and fix assumptions on proxy classes
  • Loading branch information
jketema authored Jan 15, 2025
2 parents f62a3ac + a3cd668 commit 02ac61f
Show file tree
Hide file tree
Showing 22 changed files with 9,724 additions and 37 deletions.
2,415 changes: 2,415 additions & 0 deletions cpp/downgrades/a01d8f91b8d49259e509b574962dec90719f69a6/old.dbscheme

Large diffs are not rendered by default.

2,409 changes: 2,409 additions & 0 deletions cpp/downgrades/a01d8f91b8d49259e509b574962dec90719f69a6/semmlecode.cpp.dbscheme

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
description: Improve user types and proxy classes
compatibility: full
usertypes.rel: run usertypes.qlo
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class UserType extends @usertype {
string toString() { none() }
}

bindingset[kind]
int getKind(int kind) { if kind in [15, 16, 17] then result = 6 else result = kind }

from UserType usertype, string name, int kind
where usertypes(usertype, name, kind)
select usertype, name, getKind(kind)
6 changes: 6 additions & 0 deletions cpp/ql/lib/change-notes/2025-01-13-struct-proxy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: feature
---
* A new predicate `getDecltype`was added to the `ProxyClass` class, which yields the decltype for the proxy class.
* Template classes that are of `struct` type are now also instances of the `Struct` class.
* Template classes that are of `union` type are now also instances of the `Union` class.
19 changes: 14 additions & 5 deletions cpp/ql/lib/semmle/code/cpp/Class.qll
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ class AbstractClass extends Class {
* `FullClassTemplateSpecialization`.
*/
class TemplateClass extends Class {
TemplateClass() { usertypes(underlyingElement(this), _, 6) }
TemplateClass() { usertypes(underlyingElement(this), _, [15, 16, 17]) }

/**
* Gets a class instantiated from this template.
Expand Down Expand Up @@ -1076,13 +1076,19 @@ class VirtualBaseClass extends Class {
}

/**
* The proxy class (where needed) associated with a template parameter, as
* in the following code:
* ```
* The proxy class (where needed) associated with a template parameter or a
* decltype, as in the following code:
* ```cpp
* template <typename T>
* struct S : T { // the type of this T is a proxy class
* ...
* };
*
* template <typename T>
* concept C =
* decltype(std::span{std::declval<T&>()})::extent
* != std::dynamic_extent;
* // the type of decltype(std::span{std::declval<T&>()}) is a proxy class
* ```
*/
class ProxyClass extends UserType {
Expand All @@ -1093,10 +1099,13 @@ class ProxyClass extends UserType {
/** Gets the location of the proxy class. */
override Location getLocation() { result = this.getTemplateParameter().getDefinitionLocation() }

/** Gets the template parameter for which this is the proxy class. */
/** Gets the template parameter for which this is the proxy class, if any. */
TypeTemplateParameter getTemplateParameter() {
is_proxy_class_for(underlyingElement(this), unresolveElement(result))
}

/** Gets the decltype for which this is the proxy class, if any. */
Decltype getDecltype() { is_proxy_class_for(underlyingElement(this), unresolveElement(result)) }
}

// Unpacks "array of ... of array of t" into t.
Expand Down
2 changes: 1 addition & 1 deletion cpp/ql/lib/semmle/code/cpp/Struct.qll
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import semmle.code.cpp.Class
* ```
*/
class Struct extends Class {
Struct() { usertypes(underlyingElement(this), _, 1) or usertypes(underlyingElement(this), _, 3) }
Struct() { usertypes(underlyingElement(this), _, [1, 3, 15, 17]) }

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

Expand Down
4 changes: 1 addition & 3 deletions cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ deprecated class TemplateParameter = TypeTemplateParameter;
* ```
*/
class TypeTemplateParameter extends UserType, TemplateParameterImpl {
TypeTemplateParameter() {
usertypes(underlyingElement(this), _, 7) or usertypes(underlyingElement(this), _, 8)
}
TypeTemplateParameter() { usertypes(underlyingElement(this), _, [7, 8]) }

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

Expand Down
5 changes: 1 addition & 4 deletions cpp/ql/lib/semmle/code/cpp/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -406,10 +406,7 @@ class IntegralOrEnumType extends Type {
isIntegralType(underlyingElement(this), _)
or
// Enum type
(
usertypes(underlyingElement(this), _, 4) or
usertypes(underlyingElement(this), _, 13)
)
usertypes(underlyingElement(this), _, [4, 13])
}
}

Expand Down
5 changes: 1 addition & 4 deletions cpp/ql/lib/semmle/code/cpp/TypedefType.qll
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ private import semmle.code.cpp.internal.ResolveClass
* ```
*/
class TypedefType extends UserType {
TypedefType() {
usertypes(underlyingElement(this), _, 5) or
usertypes(underlyingElement(this), _, 14)
}
TypedefType() { usertypes(underlyingElement(this), _, [5, 14]) }

/**
* Gets the base type of this typedef type.
Expand Down
2 changes: 1 addition & 1 deletion cpp/ql/lib/semmle/code/cpp/Union.qll
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import semmle.code.cpp.Struct
* ```
*/
class Union extends Struct {
Union() { usertypes(underlyingElement(this), _, 3) }
Union() { usertypes(underlyingElement(this), _, [3, 17]) }

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

Expand Down
4 changes: 2 additions & 2 deletions cpp/ql/lib/semmle/code/cpp/internal/QualifiedName.qll
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,11 @@ class ProxyClass extends UserType {
}

class TypeTemplateParameter extends UserType {
TypeTemplateParameter() { usertypes(this, _, 7) or usertypes(this, _, 8) }
TypeTemplateParameter() { usertypes(this, _, [7, 8]) }
}

class TemplateClass extends UserType {
TemplateClass() { usertypes(this, _, 6) }
TemplateClass() { usertypes(this, _, [15, 16, 17]) }

UserType getAnInstantiation() {
class_instantiation(result, this) and
Expand Down
10 changes: 1 addition & 9 deletions cpp/ql/lib/semmle/code/cpp/internal/ResolveClass.qll
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,7 @@ private module Cached {
* Holds if `t` is a struct, class, union, or template.
*/
cached
predicate isClass(@usertype t) {
usertypes(t, _, 1) or
usertypes(t, _, 2) or
usertypes(t, _, 3) or
usertypes(t, _, 6) or
usertypes(t, _, 10) or
usertypes(t, _, 11) or
usertypes(t, _, 12)
}
predicate isClass(@usertype t) { usertypes(t, _, [1, 2, 3, 15, 16, 17]) }

cached
predicate isType(@type t) {
Expand Down
12 changes: 9 additions & 3 deletions cpp/ql/lib/semmlecode.cpp.dbscheme
Original file line number Diff line number Diff line change
Expand Up @@ -771,12 +771,13 @@ decltypes(

/*
case @usertype.kind of
1 = @struct
| 0 = @unknown_usertype
| 1 = @struct
| 2 = @class
| 3 = @union
| 4 = @enum
| 5 = @typedef // classic C: typedef typedef type name
| 6 = @template
// ... 6 = @template deprecated
| 7 = @template_parameter
| 8 = @template_template_parameter
| 9 = @proxy_class // a proxy class associated with a template parameter
Expand All @@ -785,6 +786,9 @@ case @usertype.kind of
// ... 12 objc_category deprecated
| 13 = @scoped_enum
| 14 = @using_alias // a using name = type style typedef
| 15 = @template_struct
| 16 = @template_class
| 17 = @template_union
;
*/

Expand Down Expand Up @@ -843,9 +847,11 @@ class_template_argument_value(
int arg_value: @expr ref
);

@user_or_decltype = @usertype | @decltype;

is_proxy_class_for(
unique int id: @usertype ref,
unique int templ_param_id: @usertype ref
int templ_param_id: @user_or_decltype ref
);

type_mentions(
Expand Down
Loading

0 comments on commit 02ac61f

Please sign in to comment.