From 9058065634000297ab2afde61b59eccfc318e84c Mon Sep 17 00:00:00 2001 From: d367wang Date: Tue, 28 Jul 2020 21:15:14 -0400 Subject: [PATCH 1/3] fix issue 3281 by add auxilary assignment for expression statment followed by if statement --- checker/tests/regex/Issue3281.java | 16 +++++++++++ .../dataflow/cfg/CFGBuilder.java | 28 ++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 checker/tests/regex/Issue3281.java diff --git a/checker/tests/regex/Issue3281.java b/checker/tests/regex/Issue3281.java new file mode 100644 index 00000000000..a4bcd420beb --- /dev/null +++ b/checker/tests/regex/Issue3281.java @@ -0,0 +1,16 @@ +// Test case for Issue 3281: +// https://github.com/typetools/checker-framework/issues/3281 + +import java.util.regex.Pattern; +import org.checkerframework.checker.regex.RegexUtil; + +public class Issue3281 { + + void bar(String s) { + RegexUtil.isRegex(s); + if (true) { + // :: error: (argument.type.incompatible) + Pattern.compile(s); + } + } +} diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java index f42d5a1d463..676caaa13af 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java @@ -1613,6 +1613,9 @@ protected static class CFGTranslationPhaseOne extends TreePathScanner declaredLambdas; + /** Statements in a method that are followed by if-statement. */ + protected final HashSet statementBeforeIf; + /** * @param treeBuilder builder for new AST nodes * @param annotationProvider extracts annotations from AST nodes @@ -1655,6 +1658,7 @@ public CFGTranslationPhaseOne( returnNodes = new ArrayList<>(); declaredClasses = new ArrayList<>(); declaredLambdas = new ArrayList<>(); + statementBeforeIf = new HashSet<>(); } /** @@ -3360,6 +3364,14 @@ public Node visitBinary(BinaryTree tree, Void p) { @Override public Node visitBlock(BlockTree tree, Void p) { + List statements = tree.getStatements(); + // Collect all expression satatments that are followed by a if statment + for (int i = 0; i < statements.size() - 1; i++) { + if (statements.get(i).getKind() == Kind.EXPRESSION_STATEMENT + && statements.get(i + 1).getKind() == Kind.IF) { + statementBeforeIf.add(statements.get(i)); + } + } for (StatementTree n : tree.getStatements()) { scan(n, null); } @@ -3616,7 +3628,21 @@ public Node visitErroneous(ErroneousTree tree, Void p) { @Override public Node visitExpressionStatement(ExpressionStatementTree tree, Void p) { - return scan(tree.getExpression(), p); + if (statementBeforeIf.contains(tree)) { + // For an expression statment followed by an if-statment, create a local variable + // and assign the expression to that local variable, which would lead merging of the + // two store branches during dataflow analysis. + String name = uniqueName("mergeStoreBeforeIf"); + Element owner = findOwner(); + ExpressionTree initializer = tree.getExpression(); + VariableTree auxillaryVariable = + treeBuilder.buildVariableDecl( + TreeUtils.typeOf(initializer), name, owner, initializer); + return scan(auxillaryVariable, p); + + } else { + return scan(tree.getExpression(), p); + } } @Override From 35250f3ab212cea2f2c4fba62e659b4e19839216 Mon Sep 17 00:00:00 2001 From: d367wang Date: Thu, 3 Sep 2020 04:04:23 +0000 Subject: [PATCH 2/3] add merge store after every expression statement --- .../dataflow/cfg/CFGBuilder.java | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java index 676caaa13af..39968a4cbf1 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java @@ -3364,14 +3364,16 @@ public Node visitBinary(BinaryTree tree, Void p) { @Override public Node visitBlock(BlockTree tree, Void p) { - List statements = tree.getStatements(); - // Collect all expression satatments that are followed by a if statment - for (int i = 0; i < statements.size() - 1; i++) { - if (statements.get(i).getKind() == Kind.EXPRESSION_STATEMENT - && statements.get(i + 1).getKind() == Kind.IF) { - statementBeforeIf.add(statements.get(i)); - } - } + /* + List statements = tree.getStatements(); + // Collect all expression satatments that are followed by a if statment + for (int i = 0; i < statements.size() - 1; i++) { + if (statements.get(i).getKind() == Kind.EXPRESSION_STATEMENT + && statements.get(i + 1).getKind() == Kind.IF) { + statementBeforeIf.add(statements.get(i)); + } + } + */ for (StatementTree n : tree.getStatements()) { scan(n, null); } @@ -3628,21 +3630,21 @@ public Node visitErroneous(ErroneousTree tree, Void p) { @Override public Node visitExpressionStatement(ExpressionStatementTree tree, Void p) { - if (statementBeforeIf.contains(tree)) { - // For an expression statment followed by an if-statment, create a local variable - // and assign the expression to that local variable, which would lead merging of the - // two store branches during dataflow analysis. - String name = uniqueName("mergeStoreBeforeIf"); - Element owner = findOwner(); - ExpressionTree initializer = tree.getExpression(); - VariableTree auxillaryVariable = - treeBuilder.buildVariableDecl( - TreeUtils.typeOf(initializer), name, owner, initializer); - return scan(auxillaryVariable, p); + // if (statementBeforeIf.contains(tree)) { + // For an expression statment followed by an if-statment, create a local variable + // and assign the expression to that local variable, which would lead merging of the + // two store branches during dataflow analysis. + String name = uniqueName("mergeStoreBeforeIf"); + Element owner = findOwner(); + ExpressionTree initializer = tree.getExpression(); + VariableTree auxillaryVariable = + treeBuilder.buildVariableDecl( + TreeUtils.typeOf(initializer), name, owner, initializer); + return scan(auxillaryVariable, p); - } else { - return scan(tree.getExpression(), p); - } + /* } else { + return scan(tree.getExpression(), p); + } */ } @Override From 3d2278d309badda9aa43e7c994317b57667062cd Mon Sep 17 00:00:00 2001 From: d367wang Date: Thu, 10 Sep 2020 00:54:56 -0400 Subject: [PATCH 3/3] delete commented code --- .../dataflow/cfg/CFGBuilder.java | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java index 39968a4cbf1..96faaf70850 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java @@ -3364,16 +3364,6 @@ public Node visitBinary(BinaryTree tree, Void p) { @Override public Node visitBlock(BlockTree tree, Void p) { - /* - List statements = tree.getStatements(); - // Collect all expression satatments that are followed by a if statment - for (int i = 0; i < statements.size() - 1; i++) { - if (statements.get(i).getKind() == Kind.EXPRESSION_STATEMENT - && statements.get(i + 1).getKind() == Kind.IF) { - statementBeforeIf.add(statements.get(i)); - } - } - */ for (StatementTree n : tree.getStatements()) { scan(n, null); } @@ -3630,10 +3620,9 @@ public Node visitErroneous(ErroneousTree tree, Void p) { @Override public Node visitExpressionStatement(ExpressionStatementTree tree, Void p) { - // if (statementBeforeIf.contains(tree)) { - // For an expression statment followed by an if-statment, create a local variable - // and assign the expression to that local variable, which would lead merging of the - // two store branches during dataflow analysis. + // For every expression statement, create a local variable and assign the expression to + // that local variable, which would lead to merging of the two stores during dataflow + // analysis. String name = uniqueName("mergeStoreBeforeIf"); Element owner = findOwner(); ExpressionTree initializer = tree.getExpression(); @@ -3641,10 +3630,6 @@ public Node visitExpressionStatement(ExpressionStatementTree tree, Void p) { treeBuilder.buildVariableDecl( TreeUtils.typeOf(initializer), name, owner, initializer); return scan(auxillaryVariable, p); - - /* } else { - return scan(tree.getExpression(), p); - } */ } @Override