[vala/wip/baedert/nullable: 4/25] basicblock: Save per-block null/non-null symbols



commit d1141f2a740a5ce032647330aa447102945a6715
Author: Timm Bäder <mail baedert org>
Date:   Sat Nov 5 18:31:55 2016 +0100

    basicblock: Save per-block null/non-null symbols

 vala/valabasicblock.vala   |    2 ++
 vala/valaflowanalyzer.vala |   43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 0 deletions(-)
---
diff --git a/vala/valabasicblock.vala b/vala/valabasicblock.vala
index 0bb0195..1cdb5a6 100644
--- a/vala/valabasicblock.vala
+++ b/vala/valabasicblock.vala
@@ -43,6 +43,8 @@ public class Vala.BasicBlock {
        public bool postorder_visited { get; set; }
        public int postorder_number { get; set; }
 
+       public ArrayList<weak Symbol> null_vars = new ArrayList<weak Symbol> ();
+       public ArrayList<weak Symbol> non_null_vars = new ArrayList<weak Symbol> ();
 
 
        public string name;
diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala
index c248948..416144a 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -596,6 +596,35 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                return (literal != null && !literal.value);
        }
 
+       // TODO: We should merge this into BinaryExpression just like def/use so
+       //       we can support nested expressions instead of just the very simple case
+       private Symbol? get_nullable_symbol (BinaryExpression expr, out bool? is_null) {
+               if (expr.operator == BinaryOperator.EQUALITY) {
+                       if (expr.left is NullLiteral && expr.right is MemberAccess) {
+                               // foo == NULL
+                               is_null = true;
+                               return ((MemberAccess)expr.right).symbol_reference;
+                       } else if (expr.left is MemberAccess && expr.right is NullLiteral) {
+                               // NULL == foo
+                               is_null = true;
+                               return ((MemberAccess)expr.left).symbol_reference;
+                       }
+               } else if (expr.operator == BinaryOperator.INEQUALITY) {
+                       if (expr.left is NullLiteral && expr.right is MemberAccess) {
+                               // NULL != foo
+                               is_null = false;
+                               return ((MemberAccess)expr.right).symbol_reference;
+                       } else if (expr.left is MemberAccess && expr.right is NullLiteral) {
+                               // foo != NULL
+                               is_null = false;
+                               return ((MemberAccess)expr.left).symbol_reference;
+                       }
+               }
+
+               is_null = false;
+               return null;
+       }
+
        public override void visit_if_statement (IfStatement stmt) {
                if (unreachable (stmt)) {
                        return;
@@ -613,6 +642,20 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                } else {
                        current_block = new BasicBlock ("if");
                        last_block.connect (current_block);
+
+                       if (stmt.condition is BinaryExpression) {
+                               var bin_expr = stmt.condition as BinaryExpression;
+                               bool is_null;
+                               Symbol? nullable_symbol = get_nullable_symbol (bin_expr, out is_null);
+
+                               if (nullable_symbol != null) {
+                                       if (is_null) {
+                                         current_block.null_vars.add (nullable_symbol);
+                                       } else {
+                                         current_block.non_null_vars.add (nullable_symbol);
+                                       }
+                               }
+                       }
                }
                stmt.true_statement.accept (this);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]