Skip to content

Swift: fix synthesized wrapper decls #11231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions swift/codegen/generators/qlgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class NoClasses(Error):
"repr": "representation",
"param": "parameter",
"int": "integer",
"var": "variable",
}

abbreviations.update({f"{k}s": f"{v}s" for k, v in abbreviations.items()})
Expand Down
16 changes: 16 additions & 0 deletions swift/extractor/translators/DeclTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <swift/AST/GenericParamList.h>
#include <swift/AST/ParameterList.h>
#include "swift/extractor/infra/SwiftDiagnosticKind.h"
#include "swift/AST/PropertyWrappers.h"

namespace codeql {
namespace {
Expand Down Expand Up @@ -85,6 +86,11 @@ std::optional<codeql::ParamDecl> DeclTranslator::translateParamDecl(const swift:
}
fillVarDecl(decl, *entry);
entry->is_inout = decl.isInOut();
if (auto wrapped = decl.getPropertyWrapperWrappedValueVar()) {
entry->property_wrapper_local_wrapped_var = dispatcher.fetchLabel(wrapped);
entry->property_wrapper_local_wrapped_var_binding =
dispatcher.fetchLabel(wrapped->getParentPatternBinding());
}
return entry;
}

Expand Down Expand Up @@ -355,6 +361,16 @@ void DeclTranslator::fillVarDecl(const swift::VarDecl& decl, codeql::VarDecl& en
dispatcher.fetchOptionalLabel(decl.getPropertyWrapperBackingPropertyType());
}
fillAbstractStorageDecl(decl, entry);
if (auto backing = decl.getPropertyWrapperBackingProperty()) {
entry.property_wrapper_backing_var = dispatcher.fetchLabel(backing);
entry.property_wrapper_backing_var_binding =
dispatcher.fetchLabel(backing->getParentPatternBinding());
}
if (auto projection = decl.getPropertyWrapperProjectionVar()) {
entry.property_wrapper_projection_var = dispatcher.fetchLabel(projection);
entry.property_wrapper_projection_var_binding =
dispatcher.fetchLabel(projection->getParentPatternBinding());
}
}

void DeclTranslator::fillNominalTypeDecl(const swift::NominalTypeDecl& decl,
Expand Down
41 changes: 39 additions & 2 deletions swift/ql/lib/codeql/swift/generated/ParentChild.qll
Original file line number Diff line number Diff line change
Expand Up @@ -680,15 +680,39 @@ private module Impl {
}

private Element getImmediateChildOfVarDecl(VarDecl e, int index, string partialPredicateCall) {
exists(int b, int bAbstractStorageDecl, int n |
exists(
int b, int bAbstractStorageDecl, int n, int nPropertyWrapperBackingVarBinding,
int nPropertyWrapperBackingVar, int nPropertyWrapperProjectionVarBinding,
int nPropertyWrapperProjectionVar
|
b = 0 and
bAbstractStorageDecl =
b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAbstractStorageDecl(e, i, _)) | i) and
n = bAbstractStorageDecl and
nPropertyWrapperBackingVarBinding = n + 1 and
nPropertyWrapperBackingVar = nPropertyWrapperBackingVarBinding + 1 and
nPropertyWrapperProjectionVarBinding = nPropertyWrapperBackingVar + 1 and
nPropertyWrapperProjectionVar = nPropertyWrapperProjectionVarBinding + 1 and
(
none()
or
result = getImmediateChildOfAbstractStorageDecl(e, index - b, partialPredicateCall)
or
index = n and
result = e.getImmediatePropertyWrapperBackingVarBinding() and
partialPredicateCall = "PropertyWrapperBackingVarBinding()"
or
index = nPropertyWrapperBackingVarBinding and
result = e.getImmediatePropertyWrapperBackingVar() and
partialPredicateCall = "PropertyWrapperBackingVar()"
or
index = nPropertyWrapperBackingVar and
result = e.getImmediatePropertyWrapperProjectionVarBinding() and
partialPredicateCall = "PropertyWrapperProjectionVarBinding()"
or
index = nPropertyWrapperProjectionVarBinding and
result = e.getImmediatePropertyWrapperProjectionVar() and
partialPredicateCall = "PropertyWrapperProjectionVar()"
)
)
}
Expand Down Expand Up @@ -809,14 +833,27 @@ private module Impl {
}

private Element getImmediateChildOfParamDecl(ParamDecl e, int index, string partialPredicateCall) {
exists(int b, int bVarDecl, int n |
exists(
int b, int bVarDecl, int n, int nPropertyWrapperLocalWrappedVarBinding,
int nPropertyWrapperLocalWrappedVar
|
b = 0 and
bVarDecl = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfVarDecl(e, i, _)) | i) and
n = bVarDecl and
nPropertyWrapperLocalWrappedVarBinding = n + 1 and
nPropertyWrapperLocalWrappedVar = nPropertyWrapperLocalWrappedVarBinding + 1 and
(
none()
or
result = getImmediateChildOfVarDecl(e, index - b, partialPredicateCall)
or
index = n and
result = e.getImmediatePropertyWrapperLocalWrappedVarBinding() and
partialPredicateCall = "PropertyWrapperLocalWrappedVarBinding()"
or
index = nPropertyWrapperLocalWrappedVarBinding and
result = e.getImmediatePropertyWrapperLocalWrappedVar() and
partialPredicateCall = "PropertyWrapperLocalWrappedVar()"
)
)
}
Expand Down
22 changes: 22 additions & 0 deletions swift/ql/lib/codeql/swift/generated/Raw.qll
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,20 @@ module Raw {
Pattern getParentPattern() { var_decl_parent_patterns(this, result) }

Expr getParentInitializer() { var_decl_parent_initializers(this, result) }

PatternBindingDecl getPropertyWrapperBackingVarBinding() {
var_decl_property_wrapper_backing_var_bindings(this, result)
}

VarDecl getPropertyWrapperBackingVar() { var_decl_property_wrapper_backing_vars(this, result) }

PatternBindingDecl getPropertyWrapperProjectionVarBinding() {
var_decl_property_wrapper_projection_var_bindings(this, result)
}

VarDecl getPropertyWrapperProjectionVar() {
var_decl_property_wrapper_projection_vars(this, result)
}
}

class AccessorDecl extends @accessor_decl, FuncDecl {
Expand Down Expand Up @@ -285,6 +299,14 @@ module Raw {
override string toString() { result = "ParamDecl" }

predicate isInout() { param_decl_is_inout(this) }

PatternBindingDecl getPropertyWrapperLocalWrappedVarBinding() {
param_decl_property_wrapper_local_wrapped_var_bindings(this, result)
}

VarDecl getPropertyWrapperLocalWrappedVar() {
param_decl_property_wrapper_local_wrapped_vars(this, result)
}
}

class TypeAliasDecl extends @type_alias_decl, GenericTypeDecl {
Expand Down
61 changes: 61 additions & 0 deletions swift/ql/lib/codeql/swift/generated/decl/ParamDecl.qll
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// generated by codegen/codegen.py
private import codeql.swift.generated.Synth
private import codeql.swift.generated.Raw
import codeql.swift.elements.decl.PatternBindingDecl
import codeql.swift.elements.decl.VarDecl

module Generated {
Expand All @@ -11,5 +12,65 @@ module Generated {
* Holds if this is an `inout` parameter.
*/
predicate isInout() { Synth::convertParamDeclToRaw(this).(Raw::ParamDecl).isInout() }

/**
* Gets the property wrapper local wrapped variable binding of this parameter declaration, if it exists.
*
* This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the
* behavior of both the `Immediate` and non-`Immediate` versions.
*/
PatternBindingDecl getImmediatePropertyWrapperLocalWrappedVarBinding() {
result =
Synth::convertPatternBindingDeclFromRaw(Synth::convertParamDeclToRaw(this)
.(Raw::ParamDecl)
.getPropertyWrapperLocalWrappedVarBinding())
}

/**
* Gets the property wrapper local wrapped variable binding of this parameter declaration, if it exists.
*
* This is the synthesized binding introducing the property wrapper local wrapped projection
* variable for this variable, if any.
*/
final PatternBindingDecl getPropertyWrapperLocalWrappedVarBinding() {
result = getImmediatePropertyWrapperLocalWrappedVarBinding().resolve()
}

/**
* Holds if `getPropertyWrapperLocalWrappedVarBinding()` exists.
*/
final predicate hasPropertyWrapperLocalWrappedVarBinding() {
exists(getPropertyWrapperLocalWrappedVarBinding())
}

/**
* Gets the property wrapper local wrapped variable of this parameter declaration, if it exists.
*
* This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the
* behavior of both the `Immediate` and non-`Immediate` versions.
*/
VarDecl getImmediatePropertyWrapperLocalWrappedVar() {
result =
Synth::convertVarDeclFromRaw(Synth::convertParamDeclToRaw(this)
.(Raw::ParamDecl)
.getPropertyWrapperLocalWrappedVar())
}

/**
* Gets the property wrapper local wrapped variable of this parameter declaration, if it exists.
*
* This is the synthesized local wrapped value, shadowing this parameter declaration in case it
* has a property wrapper.
*/
final VarDecl getPropertyWrapperLocalWrappedVar() {
result = getImmediatePropertyWrapperLocalWrappedVar().resolve()
}

/**
* Holds if `getPropertyWrapperLocalWrappedVar()` exists.
*/
final predicate hasPropertyWrapperLocalWrappedVar() {
exists(getPropertyWrapperLocalWrappedVar())
}
}
}
Loading