[vala/0.48] Force usage of temporary variables for "tainted" member accesses
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/0.48] Force usage of temporary variables for "tainted" member accesses
- Date: Sat, 29 Aug 2020 18:47:25 +0000 (UTC)
commit fe6370e8185b21945a657fd67c3cf888510355e6
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Thu Aug 13 19:05:49 2020 +0200
Force usage of temporary variables for "tainted" member accesses
This is required to handle the side effect of postfix- and unary-
increment/decrement expressions.
Regression of 32ffc862417be39d42a1b8eeb3d0748b3e138aff
and b9035aaf17a9a97a070812a8ee83251fd3893b1e
Fixes https://gitlab.gnome.org/GNOME/vala/issues/1061
codegen/valaccodebasemodule.vala | 2 +-
codegen/valaccodememberaccessmodule.vala | 25 +++++++++++--------
vala/valacodegenerator.vala | 6 ++---
vala/valamemberaccess.vala | 42 ++++++++++++++++++++++++++++++++
4 files changed, 61 insertions(+), 14 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index b70a7d81e..11eb34714 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -4386,7 +4386,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
public abstract TargetValue get_field_cvalue (Field field, TargetValue? instance);
- public abstract TargetValue load_variable (Variable variable, TargetValue value);
+ public abstract TargetValue load_variable (Variable variable, TargetValue value, Expression? expr =
null);
public abstract TargetValue load_this_parameter (TypeSymbol sym);
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index 1cec90ac6..f46ea9dfd 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -134,7 +134,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
if (expr.lvalue) {
expr.target_value = get_field_cvalue (field, expr.inner != null ?
expr.inner.target_value : null);
} else {
- expr.target_value = load_field (field, expr.inner != null ?
expr.inner.target_value : null);
+ expr.target_value = load_field (field, expr.inner != null ?
expr.inner.target_value : null, expr);
}
} else if (expr.symbol_reference is EnumValue) {
var ev = (EnumValue) expr.symbol_reference;
@@ -389,7 +389,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
if (expr.lvalue) {
expr.target_value = get_local_cvalue (local);
} else {
- expr.target_value = load_local (local);
+ expr.target_value = load_local (local, expr);
}
}
} else if (expr.symbol_reference is Parameter) {
@@ -397,7 +397,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
if (expr.lvalue) {
expr.target_value = get_parameter_cvalue (param);
} else {
- expr.target_value = load_parameter (param);
+ expr.target_value = load_parameter (param, expr);
}
}
}
@@ -732,7 +732,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
return result;
}
- public override TargetValue load_variable (Variable variable, TargetValue value) {
+ public override TargetValue load_variable (Variable variable, TargetValue value, Expression? expr =
null) {
var result = (GLibValue) value;
var array_type = result.value_type as ArrayType;
var delegate_type = result.value_type as DelegateType;
@@ -804,6 +804,11 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
// no need to an extra copy of variables that are stack allocated simple types
use_temp = false;
}
+ // our implementation of postfix-expressions require temporary variables
+ if (expr is MemberAccess && ((MemberAccess) expr).tainted_access) {
+ use_temp = true;
+ }
+
var local = variable as LocalVariable;
if (local != null && local.name[0] == '.') {
// already a temporary variable generated internally
@@ -819,13 +824,13 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
}
/* Returns unowned access to the given local variable */
- public override TargetValue load_local (LocalVariable local) {
- return load_variable (local, get_local_cvalue (local));
+ public override TargetValue load_local (LocalVariable local, Expression? expr = null) {
+ return load_variable (local, get_local_cvalue (local), expr);
}
/* Returns unowned access to the given parameter */
- public override TargetValue load_parameter (Parameter param) {
- return load_variable (param, get_parameter_cvalue (param));
+ public override TargetValue load_parameter (Parameter param, Expression? expr = null) {
+ return load_variable (param, get_parameter_cvalue (param), expr);
}
/* Convenience method returning access to "this" */
@@ -835,7 +840,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
}
/* Returns unowned access to the given field */
- public override TargetValue load_field (Field field, TargetValue? instance) {
- return load_variable (field, get_field_cvalue (field, instance));
+ public override TargetValue load_field (Field field, TargetValue? instance, Expression? expr = null) {
+ return load_variable (field, get_field_cvalue (field, instance), expr);
}
}
diff --git a/vala/valacodegenerator.vala b/vala/valacodegenerator.vala
index cea0db8f6..9452b49a3 100644
--- a/vala/valacodegenerator.vala
+++ b/vala/valacodegenerator.vala
@@ -32,15 +32,15 @@ public abstract class Vala.CodeGenerator : CodeVisitor {
public virtual void emit (CodeContext context) {
}
- public abstract TargetValue load_local (LocalVariable local);
+ public abstract TargetValue load_local (LocalVariable local, Expression? expr = null);
public abstract void store_local (LocalVariable local, TargetValue value, bool initializer,
SourceReference? source_reference = null);
- public abstract TargetValue load_parameter (Parameter param);
+ public abstract TargetValue load_parameter (Parameter param, Expression? expr = null);
public abstract void store_parameter (Parameter param, TargetValue value, bool capturing_parameter =
false, SourceReference? source_reference = null);
- public abstract TargetValue load_field (Field field, TargetValue? instance);
+ public abstract TargetValue load_field (Field field, TargetValue? instance, Expression? expr = null);
public abstract void store_field (Field field, TargetValue? instance, TargetValue value,
SourceReference? source_reference = null);
}
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index 6891306ec..55c951930 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -57,6 +57,11 @@ public class Vala.MemberAccess : Expression {
*/
public bool prototype_access { get; set; }
+ /**
+ * Requires indirect access due to possible side-effects of parent expression.
+ */
+ public bool tainted_access { get; set; }
+
/**
* Specifies whether the member is used for object creation.
*/
@@ -961,6 +966,11 @@ public class Vala.MemberAccess : Expression {
value_type.check (context);
}
+ // Provide some extra information for the code generator
+ if (!tainted_access) {
+ tainted_access = is_tainted ();
+ }
+
return !error;
}
@@ -1044,4 +1054,36 @@ public class Vala.MemberAccess : Expression {
collection.add (param);
}
}
+
+ bool is_tainted () {
+ unowned CodeNode node = this;
+ if (node.parent_node is MemberAccess) {
+ return false;
+ }
+
+ while (node.parent_node is Expression) {
+ node = node.parent_node;
+ if (node is Assignment || node is MethodCall) {
+ break;
+ }
+ }
+
+ bool found = false;
+ var traverse = new TraverseVisitor ((n) => {
+ if (n is PostfixExpression) {
+ found = true;
+ return TraverseStatus.STOP;
+ } else if (n is UnaryExpression) {
+ unowned UnaryExpression e = (UnaryExpression) n;
+ if (e.operator == UnaryOperator.INCREMENT || e.operator ==
UnaryOperator.DECREMENT) {
+ found = true;
+ return TraverseStatus.STOP;
+ }
+ }
+ return TraverseStatus.CONTINUE;
+ });
+ node.accept (traverse);
+
+ return found;
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]