diff --git a/settings.gradle b/settings.gradle index 3b6fb9063340d94a7336c03aaea5d4a90cba2297..9b97d85de4f46c19ba77a48e2c77948d0e3c01b6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,7 +17,6 @@ include 'deps4j' include 'scope' include 'scope4j' include 'scope4m' -include 'simplecfg' include 'extendj:java4' include 'extendj:java5' include 'extendj:java6' diff --git a/simplecfg/.gitignore b/simplecfg/.gitignore deleted file mode 100644 index e6c14cd07d2acf3256143cb39267fee74d2265c3..0000000000000000000000000000000000000000 --- a/simplecfg/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -# gradle build -/build/ -/.gradle/ - -# generated files -/*.jar -/src/gen/ - -# generated graphs -/testdata/*.png - -# vim -*.swp - -# eclipse -/.project -/.classpath -/.settings/ -/bin/ - diff --git a/simplecfg/CONTRIBUTING.md b/simplecfg/CONTRIBUTING.md deleted file mode 100644 index 1ba853922fb804fd5265e877f3e8a4e1d6615448..0000000000000000000000000000000000000000 --- a/simplecfg/CONTRIBUTING.md +++ /dev/null @@ -1,24 +0,0 @@ -Want to contribute? Great! First, read this page (including the small print at the end). - -### Before you contribute -Before we can use your code, you must sign the -[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1) -(CLA), which you can do online. The CLA is necessary mainly because you own the -copyright to your changes, even after your contribution becomes part of our -codebase, so we need your permission to use and distribute your code. We also -need to be sure of various other things—for instance that you'll tell us if you -know that your code infringes on other people's patents. You don't have to sign -the CLA until after you've submitted your code for review and a member has -approved it, but you must do it before we can put your code into our codebase. -Before you start working on a larger contribution, you should get in touch with -us first through the issue tracker with your idea so that we can help out and -possibly guide you. Coordinating up front makes it much easier to avoid -frustration later on. - -### Code reviews -All submissions, including submissions by project members, require review. We -use Github pull requests for this purpose. - -### The small print -Contributions made by corporations are covered by a different agreement than -the one above, the Software Grant and Corporate Contributor License Agreement. diff --git a/simplecfg/LICENSE b/simplecfg/LICENSE deleted file mode 100644 index d645695673349e3947e8e5ae42332d0ac3164cd7..0000000000000000000000000000000000000000 --- a/simplecfg/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/simplecfg/README.md b/simplecfg/README.md deleted file mode 100644 index bb0a66bcccf5b897fe276bbe28e7cb99814c06cd..0000000000000000000000000000000000000000 --- a/simplecfg/README.md +++ /dev/null @@ -1,70 +0,0 @@ -Simple CFG module for ExtendJ -============================= - -This is a Control Flow Graph (CFG) module for the ExtendJ compiler for building -simplified CFGs. This module builds CFGs for Java methods where only branches -and method calls have are included. These simple CFGs provide enough -information to perform intraprocedural static analyses on Java code. - -This repository also includes two sample Java static analyzers based on the this -CFG module. One analyzer checks for additional calls to a -java.io.Reader/java.io.Writer after `close()` was called on the same instance. -The other analyzer checks for potential `null` dereferences on paramters -annotated with javax.annotation.Nullable. - -Disclaimer ----------- - -This is not an official Google product (experimental or otherwise), it is just -code that happens to be owned by Google. - -Shipshape Module ----------------- - -The demo analyzers can be plugged into the [Shipshape][1] pipeline. The -Shipshape integration is currently experimental. - -Dependencies ------------- - -To build the Simplified CFG generator you need the following dependencies: - -* Git -* Gradle 2.4 -* ExtendJ - -This repository has a submodule for the ExtendJ compiler. If you did not clone -this repository with the `--recursive` flag you will have to run `git submodule -init` followed by `git submodule update`, this will clone a specific commit from -the ExtendJ repository into the `third_party/extendj/` directory. - -Building --------- - -Note that you must have the Git submodule `third_party/extendj/git` in -order to build SimpleCFG. To download the submodule, use the following commands: - - git submodule init - git submodule update - - -Build the Simplified CFG generator Jar file by running the following Gradle command: - - gradle jar - - -Testing -------- - -The tests may be run by issuing the following command: - - gradle test - -Most tests check that a well-formed SimpleCFG is built for each Java file in the -testdata directory. The tests are structured so that they test the successors of -each node in the resulting CFG for the single block/method in each of the Java files. - -You can generate images for the CFGs in each test file by running the `graph.sh` -shell script. - -[1]: https://github.com/google/shipshape diff --git a/simplecfg/build.gradle b/simplecfg/build.gradle deleted file mode 100644 index 5c4e04712b48c0c00ec9f057ef26dd607b2455c3..0000000000000000000000000000000000000000 --- a/simplecfg/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -buildscript { - repositories.mavenLocal() - repositories.mavenCentral() - dependencies { - classpath 'org.jastadd:jastaddgradle:1.13.3' - } -} - -apply plugin: 'java' -apply plugin: 'application' -apply plugin: 'jastadd' -apply plugin: 'idea' - -repositories { - mavenLocal() -} - -idea { - module { - generatedSourceDirs += file('./src/gen/java') - sourceDirs += file('../extendj/src/frontend') - sourceDirs += file('../extendj/src/frontend-main') - } -} - -sourceSets.main { - java { - - srcDirs "src/gen/java" - srcDirs '../extendj/src/frontend' - srcDirs '../extendj/src/frontend-main' - } - resources { - srcDir '../extendj/src/res' - srcDir jastadd.buildInfoDir - } -} - -dependencies { - testCompile group: 'com.google.truth', name: 'truth', version: '0.27' -} - -jastadd { - configureModuleBuild() - - modules { - - include("../extendj/jastadd_modules") - - module "simplecfg", { - - imports "java8 frontend" - - jastadd { - basedir "src/main/jastadd/" - include "**/*.ast" - include "**/*.jadd" - include "**/*.jrag" - } - - java { - basedir "src/main/java/" - include "**/*.java" - } - - } - - } - - - // Target module to build: - module = 'simplecfg' - - astPackage = 'org.extendj.ast' - parser.name = 'JavaParser' - scanner.name = 'OriginalScanner' - - genDir = 'src/gen/java' - - - parser.genDir = 'src/gen/java/org/extendj/parser' - scanner.genDir = 'src/gen/java/org/extendj/scanner' -// -// if (project.hasProperty('extraJastAddOptions')) { -// extraJastAddOptions += project.extraJastAddOptions.split(',') as List -// print("options: ${extraJastAddOptions}") -// } - -} - - -test { - inputs.dir file('testdata') -} - -mainClassName = 'com.google.simplecfg.PrintCfg' -jar.manifest.attributes 'Main-Class': mainClassName -jar.destinationDir = projectDir - -sourceCompatibility = '1.8' -targetCompatibility = '1.8' diff --git a/simplecfg/gentest.sh b/simplecfg/gentest.sh deleted file mode 100755 index 388f72d85e009b96014ee3dba6a59f5824445d65..0000000000000000000000000000000000000000 --- a/simplecfg/gentest.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -# Copyright 2014 Google Inc. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -e - -if [ $# -lt "1" ]; then - echo "Error: no input program specified." - exit 1 -else - gradle jar - for src in "$@"; do - java -cp simplecfg.jar com.google.simplecfg.TestGenerator "$src" - done -fi - -echo "done" diff --git a/simplecfg/graph.sh b/simplecfg/graph.sh deleted file mode 100755 index c15fd3c9bbc80e6999f9fa8792cf5d9b885549b9..0000000000000000000000000000000000000000 --- a/simplecfg/graph.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# Copyright 2015 Google Inc. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -e - -gradle jar - -gengraph() -{ - OUT="${1%%\.javax}.png" - echo "$1 -> $OUT" - java -jar simplecfg.jar "$1" | dot -Tpng > "$OUT" -} - -if [ $# -lt "1" ]; then - for f in testdata/*.javax; do - gengraph $f - done -else - gengraph $1 -fi - -echo "done" diff --git a/simplecfg/src/main/jastadd/AlreadyClosedAnalysis.jrag b/simplecfg/src/main/jastadd/AlreadyClosedAnalysis.jrag deleted file mode 100644 index 47d49883d9f55261f2966855698bc59195d3a5cd..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/jastadd/AlreadyClosedAnalysis.jrag +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Adds an analysis checking for calls to an instance of java.io.Writer or java.io.Reader after - * {@code close()} has been called on the same instance. - * - * <p>For each method call to an effectively final variable of type java.io.Closeable, - * we do a breadth-first search on the reverse CFG from the location of that call to see if a - * call to {@code close()} was made on the same instance previously. - */ -aspect AlreadyClosedAnalysis { - - MethodAccess contributes alreadyClosedFinding() - when alreadyClosedStream() - to CompilationUnit.findings() - for compilationUnit(); - - /** Allow MethodAccess to lookup the enclosing compilation unit. */ - inh CompilationUnit MethodAccess.compilationUnit(); - - /** Generate a finding for method call after close() call. */ - syn lazy ExtendJFinding MethodAccess.alreadyClosedFinding() = - finding("AlreadyClosed", String.format( - "close() may have already been called on %s at this point", - prevExpr().prettyPrint())); - - /** Check if the reciever of this method access was already closed. */ - syn boolean MethodAccess.alreadyClosedStream() { - // The receiver must be an effectively final local variable (or parameter). - if (name().equals("close") // Don't check for repeated close() calls. - || name().equals("toString") || name().equals("toByteArray") - || !hasPrevExpr() // Does not have a variable or parameter receiver. - || prevExpr().varDecl() == null // Receiver is not a variable/parameter. - || !(prevExpr().varDecl().isFinal() - || prevExpr().varDecl().isEffectivelyFinal()) // Receiver might have changed. - || !prevExpr().type().isCloseable()) { // Receiver is not instance of java.io.Closeable. - return false; - } - final Variable receiver = prevExpr().varDecl(); - return null != call().reverseBfs(new CfgVisitor() { - @Override - public SearchAction processEdge(CfgNode pred, CfgNode succ) { - if (succ.isCloseCall(receiver)) { - if (pred.isException()) { - // This call is interrupted by an exception. Don't continue the search from this node. - return SearchAction.SKIP; - } else { - return SearchAction.SUCCESSOR_MATCH; - } - } - if (succ.isCall(receiver)) { - // Already analyzed from this point. - return SearchAction.SKIP; - } - if (succ.isDeclarationOf(receiver)) { - // Skip this node and don't reconsider any other path that encounters the node. - return SearchAction.IGNORE; - } - return SearchAction.CONTINUE; - } - }); - } - - /** Test if the CFG node is a call node with the given variable as receiver. */ - syn boolean CfgNode.isCall(Variable receiver) = false; - eq CfgMethodCall.isCall(Variable receiver) = methodAccess().hasReceiver(receiver); - - /** Test if the CFG node is a call node for receiver.close(). */ - syn boolean CfgNode.isCloseCall(Variable receiver) = false; - eq CfgMethodCall.isCloseCall(Variable receiver) = - methodAccess().hasReceiver(receiver) && methodAccess().getID().equals("close"); - - /** Check if this is a Reader or Writer. */ - syn boolean TypeDecl.isCloseable() = - !isUnknown() && instanceOf(lookupType("java.io", "Closeable")); -} diff --git a/simplecfg/src/main/jastadd/CFG.ast b/simplecfg/src/main/jastadd/CFG.ast deleted file mode 100644 index b1e7cbe5349021cc8790f4a6ee2613ee6b1eb168..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/jastadd/CFG.ast +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** A node in a Control Flow Graph (CFG). */ -abstract CfgNode; - -/** The CFG entry node. */ -CfgEntry : CfgNode ::= <Succ:CfgNode>; - -/** The CFG exit node. */ -CfgExit : CfgNode; - -/** A method call in the CFG. */ -CfgMethodCall : CfgNode; - -/** A conditional branch in the CFG. */ -CfgBranch : CfgNode; - -/** A branch in the CFG caused by potential thrown exceptions. */ -CfgException : CfgNode; - -/** A marker node used to mark try block entry points or the end of if-statement branches. */ -CfgMarker : CfgNode; diff --git a/simplecfg/src/main/jastadd/CfgSearch.jrag b/simplecfg/src/main/jastadd/CfgSearch.jrag deleted file mode 100644 index e950ffe2f24654847136b0fd7f5b8f8c90a804cd..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/jastadd/CfgSearch.jrag +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * This aspect adds an API for searching for nodes matching some property in a Control Flow Graph. - */ -aspect CfgSearch { - enum SearchAction { - /** - * The search is complete because the currently processed edge successor matches the search. - */ - SUCCESSOR_MATCH, - /** - * The search is complete because the currently processed edge predecessor matches the search. - */ - PREDECESSOR_MATCH, - /** - * The search should skip adding the successors from the successor of the current edge. - */ - SKIP, - /** - * The search continues as normal, adding successors from the target of the current edge. - */ - CONTINUE, - /** - * The search does not process additional edges to the target of the current edge, and the - * successors of the target node are not added to the work queue. - */ - IGNORE - } - - /** A CFG visitor decides which nodes to process based on the current edge (pred, succ). */ - interface CfgVisitor { - /** - * Returns the action a Breadth-First search should take for this edge. - * @param pred Edge source. - * @param succ Edge destination. - */ - public SearchAction processEdge(CfgNode pred, CfgNode succ); - } - - /** - * Performs a Breadth-First Search over the CFG successors starting from this node. - * @param visitor a visitor that decides when the search is terminated and which - * successors to process - * @return {@code null} if no match was found - */ - public CfgNode CfgNode.bfs(CfgVisitor visitor) { - Set<CfgNode> visited = Collections.newSetFromMap( - new IdentityHashMap<CfgNode, Boolean>()); - Queue<CfgNode> work = new LinkedList<CfgNode>(); - work.add(this); - while (!work.isEmpty()) { - CfgNode node = work.poll(); - for (CfgNode succ : node.successors()) { - if (!visited.contains(succ)) { - switch (visitor.processEdge(node, succ)) { - case SUCCESSOR_MATCH: - return succ; - case PREDECESSOR_MATCH: - return node; - case SKIP: - continue; - case CONTINUE: - work.add(succ); - visited.add(succ); - break; - case IGNORE: - visited.add(succ); - break; - } - } - } - } - // The search matched nothing and we exhausted all successors. - return null; - } - - inh lazy CfgEntry CfgNode.cfg(); - - /** - * Performs a Breadth-First Search over the CFG predecessors starting from this node. - * @param visitor a visitor that decides when the search is terminated and which - * predecessors to process - * @return {@code null} if no match was found - */ - public CfgNode CfgNode.reverseBfs(CfgVisitor visitor) { - Set<CfgNode> visited = Collections.newSetFromMap( - new IdentityHashMap<CfgNode, Boolean>()); - cfg().initPredecessors(); - Queue<CfgNode> work = new LinkedList<CfgNode>(); - work.add(this); - while (!work.isEmpty()) { - CfgNode node = work.poll(); - for (CfgNode pred : node.predecessors) { - if (!visited.contains(pred)) { - switch (visitor.processEdge(node, pred)) { - case SUCCESSOR_MATCH: - return pred; - case PREDECESSOR_MATCH: - return node; - case SKIP: - continue; - case CONTINUE: - work.add(pred); - visited.add(pred); - break; - case IGNORE: - visited.add(pred); - break; - } - } - } - } - // The search matched nothing and we exhausted all predecessors. - return null; - } - - /** A matcher used to search for particular nodes in a CFG. */ - interface CfgMatcher { - public boolean match(CfgNode node); - } - - /** Search for a previous node matching the matcher, starting from the current CFG node. */ - public CfgNode CfgNode.findPreviousNode(final CfgMatcher matcher) { - return reverseBfs(new CfgVisitor() { - @Override - public SearchAction processEdge(CfgNode pred, CfgNode succ) { - return matcher.match(succ) ? SearchAction.SUCCESSOR_MATCH : SearchAction.CONTINUE; - } - }); - } - - /** Check if there is a previous node matching the matcher, starting from the current CFG node. */ - syn boolean CfgNode.hasPreviousNode(CfgMatcher matcher) = null != findPreviousNode(matcher); -} diff --git a/simplecfg/src/main/jastadd/ClassPathFilter.ast b/simplecfg/src/main/jastadd/ClassPathFilter.ast deleted file mode 100644 index 0acfbecbf4c23a749f940a1d7f682e930ef939f8..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/jastadd/ClassPathFilter.ast +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * PlaceholderTypeDecl is used to avoid locating and parsing source or class files when - * analyzing a single file. - * Represents a type that is known to exist but which we don't know anything else about. - */ -PlaceholderTypeDecl : ClassDecl; diff --git a/simplecfg/src/main/jastadd/ClassPathFilter.jrag b/simplecfg/src/main/jastadd/ClassPathFilter.jrag deleted file mode 100644 index 33e9b33fd79d0e27f80816cf444966374a6998c3..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/jastadd/ClassPathFilter.jrag +++ /dev/null @@ -1,235 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Replace type lookup to avoid parsing extra sources. - * All sources other than the one that is being analyzed is replaced - * by the Unknown type, or a placeholder type - a TypeDecl with just - * a name and package. - */ -aspect ClassPathFilter { - - /** The type lookup filter to use during type lookups. */ - private TypeLookupFilter Program.typeLookupFilter = NO_TYPE_FILTER; - - /** Changes the type lookup filter. */ - public void Program.setTypeLookupFilter(TypeLookupFilter filter) { - typeLookupFilter = filter; - } - - public interface TypeLookupFilter { - /** - * This allows extra source type map initialization. It is run after the default source type map - * initialization code. - */ - void initializeSourceTypeMap(Program program); - /** - * This allows extra library type map initialization. It is run after the default library type - * map initialization code. - */ - void initializeLibraryTypeMap(Program program); - - /** - * Returns the TypeDecl for the requested type. Returns UnknownType if the type was not - * found, or if the type was filtered out by this filter. - */ - TypeDecl lookupSourceType(Program program, String packageName, String typeName); - - /** - * Returns the TypeDecl for the requested type. Returns UnknownType if the type was not - * found, or if the type was filtered out by this filter. - */ - TypeDecl lookupLibraryType(Program program, String packageName, String typeName); - } - - /** This type filter does not perform any filtering. */ - public static final TypeLookupFilter Program.NO_TYPE_FILTER = new TypeLookupFilter() { - @Override - public void initializeSourceTypeMap(Program program) { - } - - @Override - public void initializeLibraryTypeMap(Program program) { - } - - @Override - public TypeDecl lookupSourceType(Program program, String packageName, String typeName) { - return program.lookupSourceType(packageName, typeName); - } - - @Override - public TypeDecl lookupLibraryType(Program program, String packageName, String typeName) { - return program.lookupLibraryType(packageName, typeName); - } - }; - - /** This type filter filters out library types. */ - public static final TypeLookupFilter Program.BASE_LIBRARY_FILTER = new TypeLookupFilter() { - @Override - public void initializeSourceTypeMap(Program program) { - } - - @Override - public void initializeLibraryTypeMap(Program program) { - // All types that need to be distinguishable in the code being analyzed - // should be added as placeholders here. - // This list contains all types which are looked up explicitly in the - // ExtendJ frontend code with lookupType(pkg, name) All type lookups that - // don't match a placeholder type get mapped to the Unknown type. - program.addPlaceholderType("java.lang", "Object"); - program.addPlaceholderType("java.lang", "AutoCloseable"); - program.addPlaceholderType("java.lang", "Class"); - program.addPlaceholderType("java.lang", "Cloneable"); - program.addPlaceholderType("java.lang", "Error"); - program.addPlaceholderType("java.lang", "Exception"); - program.addPlaceholderType("java.lang", "FunctionalInterface"); - program.addPlaceholderType("java.lang", "NullPointerException"); - program.addPlaceholderType("java.lang", "Throwable"); - program.addPlaceholderType("java.lang", "Enum"); - program.addPlaceholderType("java.lang", "Iterable"); - program.addPlaceholderType("java.lang", "Iterator"); - program.addPlaceholderType("java.lang", "RuntimeException"); - - // Annotations and boxed primitive types are required - // to do some simple type analysis. - - // Add annotation types. - program.addPlaceholderType("java.lang.annotation", "Target"); - program.addPlaceholderType("java.lang.annotation", "Retention"); - program.addPlaceholderType("java.lang.annotation", "Inherited"); - program.addPlaceholderType("java.lang", "SuppressWarnings"); - program.addPlaceholderType("java.lang", "Override"); - program.addPlaceholderType("java.lang", "Serializable"); - - // Boxed primitive types. - program.addPlaceholderType("java.lang", "Integer"); - program.addPlaceholderType("java.lang", "Float"); - program.addPlaceholderType("java.lang", "Short"); - program.addPlaceholderType("java.lang", "Byte"); - program.addPlaceholderType("java.lang", "Character"); - program.addPlaceholderType("java.lang", "Long"); - program.addPlaceholderType("java.lang", "Double"); - program.addPlaceholderType("java.lang", "String"); - program.addPlaceholderType("java.lang", "Boolean"); - program.addPlaceholderType("java.lang", "Void"); - } - - @Override - public TypeDecl lookupSourceType(Program program, String packageName, String typeName) { - return program.lookupSourceType(packageName, typeName); - } - - @Override - public TypeDecl lookupLibraryType(Program program, String packageName, String typeName) { - String fullName = packageName.isEmpty() ? typeName : packageName + "." + typeName; - if (program.libraryTypeMap.containsKey(fullName)) { - return program.libraryTypeMap.get(fullName); - } else { - program.libraryTypeMap.put(fullName, program.unknownType()); - return program.unknownType(); - } - } - }; - - public static final TypeLookupFilter Program.ANALYZER_TYPE_FILTER = new TypeLookupFilter() { - @Override - public void initializeSourceTypeMap(Program program) { - BASE_LIBRARY_FILTER.initializeSourceTypeMap(program); - } - - @Override - public void initializeLibraryTypeMap(Program program) { - BASE_LIBRARY_FILTER.initializeLibraryTypeMap(program); - - // Types needed for read/write after close analysis. - program.addPlaceholderType("java.io", "Writer"); - program.addPlaceholderType("java.io", "Reader"); - - // Types needed for Nullable Dereference analysis. - program.addPlaceholderType("javax.annotation", "Nullable"); - } - - @Override - public TypeDecl lookupSourceType(Program program, String packageName, String typeName) { - return BASE_LIBRARY_FILTER.lookupSourceType(program, packageName, typeName); - } - - @Override - public TypeDecl lookupLibraryType(Program program, String packageName, String typeName) { - return BASE_LIBRARY_FILTER.lookupLibraryType(program, packageName, typeName); - } - }; - - refine LookupFullyQualifiedTypes - protected void Program.initializeSourceTypeMap() { - refined(); - typeLookupFilter.initializeSourceTypeMap(this); - } - - refine LookupFullyQualifiedTypes - protected void Program.initializeLibraryTypeMap() { - refined(); - typeLookupFilter.initializeLibraryTypeMap(this); - } - - refine LookupFullyQualifiedTypes - eq Program.lookupType(String packageName, String typeName) { - TypeDecl sourceType = typeLookupFilter.lookupSourceType(this, packageName, typeName); - if (!sourceType.isUnknown()) { - return sourceType; - } - if (!libraryTypeMapInitialized) { - initializeLibraryTypeMap(); - libraryTypeMapInitialized = true; - } - return typeLookupFilter.lookupLibraryType(this, packageName, typeName); - } - - /** - * Add a placeholder type declaration to the library type map. - * This triggers evaluation of a placeholder type NTA and a placeholder - * compilation unit NTA. - */ - public void Program.addPlaceholderType(String packageName, String typeName) { - String fullName = packageName.equals("") ? typeName : packageName + "." + typeName; - CompilationUnit cu = placeholderCompilationUnit(packageName); - cu.setFromSource(false); - cu.setClassSource(ClassSource.NONE); - TypeDecl placeholder = cu.placeholderTypeDecl(typeName); - libraryTypeMap.put(fullName, placeholder); - } - - /** - * Build a placeholder compilation unit for types in a package. - */ - syn nta CompilationUnit Program.placeholderCompilationUnit(String packageName) { - CompilationUnit u = new CompilationUnit(); - u.setPackageDecl(packageName); - return u; - } - - /** - * Build placeholder type declaration. - */ - syn nta TypeDecl CompilationUnit.placeholderTypeDecl(String typeName) { - PlaceholderTypeDecl decl = new PlaceholderTypeDecl(); - decl.setModifiers(new Modifiers(new List().add(new Modifier("public")))); - decl.setID(typeName); - return decl; - } - -} - diff --git a/simplecfg/src/main/jastadd/Findings.jrag b/simplecfg/src/main/jastadd/Findings.jrag deleted file mode 100644 index 104905bf4d3267d9d135e467465c2991c31dba01..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/jastadd/Findings.jrag +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -import java.util.Collection; -import java.util.LinkedList; - -/** - * This aspect provides the general attributes to collect findings for the - * available analyses. - */ -aspect Findings { - /** Collection of API usage findings. */ - coll Collection<ExtendJFinding> CompilationUnit.findings() - [new LinkedList<ExtendJFinding>()] - with add - root CompilationUnit; - - /** Build a new finding with the given subcategory and message. */ - syn ExtendJFinding ASTNode.finding(String subcategory, String message) { - ASTNode location = locationNode(); - return new ExtendJFinding(sourceFile(), subcategory, message, - getLine(location.getStart()), getColumn(location.getStart()), - getLine(location.getEnd()), getColumn(location.getEnd())); - } - - /** Find the closest AST node with source location information. */ - syn ASTNode ASTNode.locationNode() { - ASTNode node = this; - while (node.getParent() != null && node.getStart() == 0) { - node = node.getParent(); - } - return node; - } - - /** Find the indentation for the current statement. */ - inh String Stmt.indentation(); - - /** Find the indentation for the current expression. */ - inh String Expr.indentation(); - - /** Find the indentation for the current type declaration. */ - inh String TypeDecl.indentation(); - - eq Block.getChild().indentation() = indentation() + " "; - eq TypeDecl.getChild().indentation() = indentation() + " "; - - eq CompilationUnit.getChild().indentation() = ""; - eq Program.getChild().indentation() = ""; - - /** A finding produced by an ExtendJ analyzer. */ - public class ExtendJFinding { - - public final String sourcePath; - public final String subcategory; - public final String message; - public final int startLine; - public final int startColumn; - public final int endLine; - public final int endColumn; - public final Collection<ExtendJFix> fixes = new ArrayList<>(); - - /** - * Describes a suggested fix. The suggested fix has a description which does not seem to - * show up in Critique. The new text should end with a newline. - */ - public static class ExtendJFix { - public final String description; - public final int startLine; - public final int endLine; - public final String newText; - - ExtendJFix(String description, int startLine, int endLine, String newText) { - this.description = description; - this.startLine = startLine; - this.endLine = endLine; - this.newText = newText; - } - } - - public ExtendJFinding(String sourcePath, String subcategory, String message, - int startLine, int startColumn, int endLine, int endColumn) { - this.sourcePath = sourcePath; - this.subcategory = subcategory; - this.message = message; - this.startLine = startLine; - this.startColumn = startColumn; - this.endLine = endLine; - this.endColumn = endColumn; - } - - /** - * Set a new suggested fix for this finding. - */ - public ExtendJFinding addFix(String description, int startLine, int endLine, String newText) { - fixes.add(new ExtendJFix(description, startLine, endLine, newText)); - return this; - } - - @Override - public String toString() { - // This message is printed for each finding when running the CLI. - return String.format("%s:%d:%d: %s", sourcePath, startLine, startColumn, message); - } - } -} diff --git a/simplecfg/src/main/jastadd/NullableDereferenceAnalysis.jrag b/simplecfg/src/main/jastadd/NullableDereferenceAnalysis.jrag deleted file mode 100644 index db9afd1b5bab4b1dbc43107c23dd6ac4ff13b69c..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/jastadd/NullableDereferenceAnalysis.jrag +++ /dev/null @@ -1,504 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Adds an analysis that checks for dereferences of a parameter declared nullable. - * - * <p>When a method or constructor parameter is annotated with javax.annotation.Nullable, - * we check that all dereferences of that parameter are guarded by a null-check. The - * analysis is control-flow sensitive in that it will recognize if all control flow paths - * to the dereference are effectively guarded by a null check, for example: {@code - * if (p == null) return; - * p.x(); // Guarded by null check above. - * } - * - * <p>The analysis is not intraprocedural, so in order to avoid false positives - * where a method call guards against nullness the analyzer assumes that - * calling a method with an argument x results in an exception if x is null and - * thus works like an effective null guard for x. - * - * <p>To find potential null dereferences on nullable parameters, the analysis does a forward CFG - * traversal from the entry-point of the method. Note that this is only done whenever a - * {@code @Nullable} parameter has been encountered in the method. The traversal explores all paths - * from the method entry until it finds null guard statements such as {@code if (p != null)}. The - * branches that are protected from nullness get pruned in the search and the search continues on - * other branches. The search is performed by a {@code NullDereferenceLocator}, which implements the - * {@code CfgSearch} interface. This visitor is invoked for each node in the CFG search, and it - * decides if the search will continue from that node, or if the current edge should be skipped - * (i.e., pruned). - * - * <p>In order to find the position in the CFG where a potential null dereference occurs, CFG marker - * nodes are inserted. This is done by adding a synthesized non-terminal attribute (NTA) for - * a CfgMarker on Dot (which represents Java dot expressions). This marker node appears - * in the CFG as "nullable access" because it is inserted whenever a nullable variable is - * dereferenced. - * - * <p>Dataflow analysis is not used, so in order to analyze a parameter it is required to be - * effectively final, i.e. it is not assigned anywhere in side the body of the method/constructor. - */ -aspect NullableDereferenceAnalysis { - - // Give ParameterDeclaration access to the inherited compilationUnit attribute. - inh CompilationUnit ParameterDeclaration.compilationUnit(); - - ParameterDeclaration contributes nullableDereferenceFinding() - when nullableDereferenceFinding() != null - to CompilationUnit.findings() - for compilationUnit(); - - /** - * Generate a NullableDereference finding for this dot expression, - * if no finding should be reported this attribute returns {@code null}. - */ - syn lazy ExtendJFinding ParameterDeclaration.nullableDereferenceFinding() { - if (!getModifiers().hasNullableAnnotation()) { - return null; - } - if (!isFinal() && !isEffectivelyFinal()) { - // Do not analyze non-effectively final parameters. - return null; - } - Expr location = findNullableDereference(this); - if (location == null) { - return null; - } - ExtendJFinding finding = location.finding("NullableDereference", String.format( - "Dereferencing %s, which was declared @Nullable.", name())); - if (compilationUnit().fromSource()) { - ASTNode modifierLocation = nullableModifierLocation(); - int line = getLine(modifierLocation.getStart()); - int startCol = getColumn(modifierLocation.getStart()); - int endCol = getColumn(modifierLocation.getEnd()); - if (startCol < endCol && line == getLine(modifierLocation.getEnd())) { - try { - InputStream data = compilationUnit().getClassSource().openInputStream(); - java.util.Scanner scanner = new java.util.Scanner(data); - for (int i = 1; i < line && scanner.hasNextLine(); ++i) { - scanner.nextLine(); - } - if (scanner.hasNextLine()) { - String text = scanner.nextLine(); - finding.addFix("Remove the @Nullable annotation.", - line, line, - text.substring(0,startCol-1) + text.substring(endCol+1) + "\n"); - } - } catch (IOException e) { - // Failed to unparse the current line. - // This is not a serious problem; we just don't give a fix suggestion. - } - } - } - return finding; - } - - // Exclude variable arity parameters from Nullable dereference analysis. - // When a variable arity parameter is annotated @Nullable, that will most likely be intended as a - // @Nullable annotation for the individual parameters, not the containing argument array. - eq VariableArityParameterDeclaration.nullableDereferenceFinding() = null; - - /** - * Find the location node for the javax.annotation.Nullable annotation in the modifier list. - * Returns {@code null} if the location of the modifier was not found. - */ - syn ASTNode ParameterDeclaration.nullableModifierLocation() = - getModifiers().nullableModifierLocation(); - - syn ASTNode Modifiers.nullableModifierLocation() { - for (Modifier modifier : getModifierList()) { - if (modifier.isAnnotation("javax.annotation", "Nullable")) { - return modifier.locationNode(); - } - } - return null; - } - - /** - * Find a location, not necessarily the first location, in the host method/constructor where the - * parameter is accessed without a null guard. - */ - inh Expr ParameterDeclaration.findNullableDereference(Variable var); - - eq Program.getChild().findNullableDereference(Variable var) = null; - eq BodyDecl.getChild().findNullableDereference(Variable var) = null; - - eq MethodDecl.getParameter().findNullableDereference(Variable var) { - if (!hasBlock()) { - return null; - } - CfgNode cfgNode = entry().bfs(new NullDereferenceLocator(var)); - return cfgNode == null ? null : cfgNode.receiverExpr(); - } - - eq ConstructorDecl.getParameter().findNullableDereference(Variable var) { - CfgNode cfgNode = entry().bfs(new NullDereferenceLocator(var)); - return cfgNode == null ? null : cfgNode.receiverExpr(); - } - - /** - * A CFG visitor that searches in the forward CFG for a nullable dereference. - * - * <p>The search stops at parts of the search tree guarded by a null check - * on the receiver variable. - */ - class NullDereferenceLocator implements CfgVisitor { - private final Variable var; - - public NullDereferenceLocator(Variable var) { - this.var = var; - } - - @Override public SearchAction processEdge(CfgNode pred, CfgNode succ) { - if (pred.isNullGuard(var, succ)) { - return SearchAction.SKIP; - } - Expr receiver = succ.receiverExpr(); - if (receiver != null && receiver.isVariable(var) && !receiver.hasNullGuard(var)) { - return SearchAction.SUCCESSOR_MATCH; - } - return SearchAction.CONTINUE; - } - } - - /** - * Returns the receiver expression if the CFG node is the child of a dereference expression. - * Returns {@code null} otherwise. - */ - inh Expr CfgNode.receiverExpr(); - eq Program.getChild().receiverExpr() = null; - eq BodyDecl.getChild().receiverExpr() = null; - eq BodyDecl.exit().receiverExpr() = null; - eq TryStmt.tryEntryMarker().receiverExpr() = null; - eq BreakStmt.marker().receiverExpr() = null; - eq ContinueStmt.marker().receiverExpr() = null; - eq ReturnStmt.marker().receiverExpr() = null; - eq MethodAccess.exceptionNode().receiverExpr() = null; - eq MethodAccess.call().receiverExpr() = - hasPrevExpr() - ? prevExpr() - : null; - eq ThrowStmt.exceptionNode().receiverExpr() = null; - eq TryStmt.exceptionNode().receiverExpr() = null; - eq ConditionalExpr.branch().receiverExpr() = null; - eq ConditionalExpr.thenEndMarker().receiverExpr() = null; - eq ConditionalExpr.elseEndMarker().receiverExpr() = null; - eq IfStmt.branch().receiverExpr() = null; - eq IfStmt.thenEndMarker().receiverExpr() = null; - eq IfStmt.elseEndMarker().receiverExpr() = null; - eq ForStmt.branch().receiverExpr() = null; - eq EnhancedForStmt.branch().receiverExpr() = null; - eq WhileStmt.branch().receiverExpr() = null; - eq DoStmt.branch().receiverExpr() = null; - eq SwitchStmt.branch().receiverExpr() = null; - eq LambdaBody.exit().receiverExpr() = null; - eq Dot.nullableDereferenceMarker().receiverExpr() = getLeft(); - - /** Marker node used to find location of a nullable dereference in the CFG. */ - syn nta CfgMarker Dot.nullableDereferenceMarker() = new CfgMarker(); - - /** Insert nullable dereference marker in the CFG. */ - refine SimpleCFG - eq Dot.getLeft().follow() = - getRight().isMethodAccess() - ? refined() - : nullableDereferenceMarker(); - - eq Dot.nullableDereferenceMarker().succ() = Collections.singleton(getRight().entry()); - - syn boolean CfgNode.isNullGuard(Variable var, CfgNode succ) = false; - - /** - * We assume that calling a method with the variable var as an argument - * results in an exception thrown by the method call if var is null. This is - * not true for many methods, but it should reduce the false positive rate - * for the NullableDereference analyzer. - */ - eq CfgMethodCall.isNullGuard(Variable var, CfgNode succ) { - if (succ instanceof CfgException) { - return false; - } - MethodAccess access = methodAccess(); - for (Expr arg : access.getArgList()) { - if (arg.isVariable(var)) { - return true; - } - } - return false; - } - - /** Check if this branch has a null-guarding condition. */ - eq CfgBranch.isNullGuard(Variable var, CfgNode succ) = inNullGuard(var, succ); - - inh boolean CfgBranch.inNullGuard(Variable var, CfgNode succ); - - eq IfStmt.branch().inNullGuard(Variable var, CfgNode succ) = - succ == getThen().entry() - ? getCondition().isNonNullWhenTrue(var) - : getCondition().isNonNullWhenFalse(var); - - eq ConditionalExpr.branch().inNullGuard(Variable var, CfgNode succ) = - succ == getTrueExpr().entry() - ? getCondition().isNonNullWhenTrue(var) - : getCondition().isNonNullWhenFalse(var); - - eq ForStmt.branch().inNullGuard(Variable var, CfgNode succ) = - succ == getStmt().entry() - ? getCondition().isNonNullWhenTrue(var) - : getCondition().isNonNullWhenFalse(var); - - eq WhileStmt.branch().inNullGuard(Variable var, CfgNode succ) = - succ == getStmt().entry() - ? getCondition().isNonNullWhenTrue(var) - : getCondition().isNonNullWhenFalse(var); - - eq EnhancedForStmt.branch().inNullGuard(Variable var, CfgNode succ) = false; - eq DoStmt.branch().inNullGuard(Variable var, CfgNode succ) = false; - eq SwitchStmt.branch().inNullGuard(Variable var, CfgNode succ) = false; - - /** Returns {@code true} if this set of modifiers includes {@code javax.annotation.Nullable}. */ - syn boolean Modifiers.hasNullableAnnotation() = hasAnnotation("javax.annotation", "Nullable"); - - /** Return {@code true} if this expression is guarded by a != null check for var. */ - inh boolean Expr.hasNullGuard(Variable var); - eq Program.getChild().hasNullGuard(Variable var) = false; - eq IfStmt.getThen().hasNullGuard(Variable var) = getCondition().isNonNullWhenTrue(var); - eq IfStmt.getElse().hasNullGuard(Variable var) = getCondition().isNonNullWhenFalse(var); - eq WhileStmt.getStmt().hasNullGuard(Variable var) = getCondition().isNonNullWhenTrue(var); - eq ForStmt.getStmt().hasNullGuard(Variable var) = getCondition().isNonNullWhenTrue(var); - eq ConditionalExpr.getTrueExpr().hasNullGuard(Variable var) = - getCondition().isNonNullWhenTrue(var) || hasNullGuard(var); - eq ConditionalExpr.getFalseExpr().hasNullGuard(Variable var) = - getCondition().isNonNullWhenFalse(var) || hasNullGuard(var); - eq AndLogicalExpr.getRightOperand().hasNullGuard(Variable var) = - getLeftOperand().isNonNullWhenTrue(var) || hasNullGuard(var); - eq AndBitwiseExpr.getRightOperand().hasNullGuard(Variable var) = - getLeftOperand().isNonNullWhenTrue(var) || hasNullGuard(var); - eq OrLogicalExpr.getRightOperand().hasNullGuard(Variable var) = - getLeftOperand().isNonNullWhenFalse(var) || hasNullGuard(var); - - /** @return {@code true} if the variable var is null when this expression is true. */ - syn boolean Expr.isNullWhenTrue(Variable var) = false; - - eq NEExpr.isNullWhenTrue(Variable var) = - getLeftOperand().isTrue() && getRightOperand().isNullWhenFalse(var) - || getRightOperand().isTrue() && getLeftOperand().isNullWhenFalse(var) - || getLeftOperand().isFalse() && getRightOperand().isNullWhenTrue(var) - || getRightOperand().isFalse() && getLeftOperand().isNullWhenTrue(var); - - eq EQExpr.isNullWhenTrue(Variable var) = - getLeftOperand().isNull() && getRightOperand().varDecl() == var - || getRightOperand().isNull() && getLeftOperand().varDecl() == var - || getLeftOperand().isTrue() && getRightOperand().isNullWhenTrue(var) - || getRightOperand().isTrue() && getLeftOperand().isNullWhenTrue(var) - || getLeftOperand().isFalse() && getRightOperand().isNullWhenFalse(var) - || getRightOperand().isFalse() && getLeftOperand().isNullWhenFalse(var); - - eq LogNotExpr.isNullWhenTrue(Variable var) = getOperand().isNullWhenFalse(var); - - eq ParExpr.isNullWhenTrue(Variable var) = getExpr().isNullWhenTrue(var); - - eq AndLogicalExpr.isNullWhenTrue(Variable var) = - getLeftOperand().isNullWhenTrue(var) || getRightOperand().isNullWhenTrue(var); - - eq AndBitwiseExpr.isNullWhenTrue(Variable var) = - getLeftOperand().isNullWhenTrue(var) || getRightOperand().isNullWhenTrue(var); - - eq OrLogicalExpr.isNullWhenTrue(Variable var) = - getLeftOperand().isFalse() && getRightOperand().isNullWhenTrue(var) - || getRightOperand().isFalse() && getLeftOperand().isNullWhenTrue(var); - - eq Dot.isNullWhenTrue(Variable var) = - !getLeft().isVariable(var) && getRight().isNullWhenTrue(var); - - // Assume that a method call to X.isNull_(var) is equivalent to a null test on var. - eq MethodAccess.isNullWhenTrue(Variable var) = - name().startsWith("isNull") && getNumArg() == 1 && getArg(0).isVariable(var); - - eq VarAccess.isNullWhenTrue(Variable var) = decl().isNullWhenTrue(var); - - syn boolean Variable.isNullWhenTrue(Variable var); - eq EnumConstant.isNullWhenTrue(Variable var) = false; - eq ParameterDeclaration.isNullWhenTrue(Variable var) = false; - eq FieldDeclarator.isNullWhenTrue(Variable var) = false; - eq CatchParameterDeclaration.isNullWhenTrue(Variable var) = false; - eq InferredParameterDeclaration.isNullWhenTrue(Variable var) = false; - eq VariableDeclarator.isNullWhenTrue(Variable var) = - type().isBoolean() && hasInit() && isEffectivelyFinal() - ? getInit().isNullWhenTrue(var) - : false; - - /** @return {@code true} if the variable var is null when this expression is false. */ - syn boolean Expr.isNullWhenFalse(Variable var) = false; - - eq NEExpr.isNullWhenFalse(Variable var) = - getLeftOperand().isNull() && getRightOperand().varDecl() == var - || getRightOperand().isNull() && getLeftOperand().varDecl() == var - || getLeftOperand().isTrue() && getRightOperand().isNullWhenTrue(var) - || getRightOperand().isTrue() && getLeftOperand().isNullWhenTrue(var) - || getLeftOperand().isFalse() && getRightOperand().isNullWhenFalse(var) - || getRightOperand().isFalse() && getLeftOperand().isNullWhenFalse(var); - - eq EQExpr.isNullWhenFalse(Variable var) = - getLeftOperand().isTrue() && getRightOperand().isNullWhenFalse(var) - || getRightOperand().isTrue() && getLeftOperand().isNullWhenFalse(var) - || getLeftOperand().isFalse() && getRightOperand().isNullWhenTrue(var) - || getRightOperand().isFalse() && getLeftOperand().isNullWhenTrue(var); - - eq LogNotExpr.isNullWhenFalse(Variable var) = getOperand().isNullWhenTrue(var); - - eq ParExpr.isNullWhenFalse(Variable var) = getExpr().isNullWhenFalse(var); - - eq AndLogicalExpr.isNullWhenFalse(Variable var) = - getLeftOperand().isTrue() && getRightOperand().isNullWhenFalse(var) - || getRightOperand().isTrue() && getLeftOperand().isNullWhenFalse(var); - - eq AndBitwiseExpr.isNullWhenFalse(Variable var) = - getLeftOperand().isTrue() && getRightOperand().isNullWhenFalse(var) - || getRightOperand().isTrue() && getLeftOperand().isNullWhenFalse(var); - - eq OrLogicalExpr.isNullWhenFalse(Variable var) = - getLeftOperand().isNullWhenFalse(var) && getRightOperand().isNullWhenFalse(var); - - eq Dot.isNullWhenFalse(Variable var) = - !getLeft().isVariable(var) && getRight().isNullWhenFalse(var); - - // Assume that a method call to X.isNo{t,n}Null_(var) is equivalent to a non-null test on var. - eq MethodAccess.isNullWhenFalse(Variable var) = - (name().startsWith("isNotNull") || name().startsWith("isNonNull")) - && getNumArg() == 1 && getArg(0).isVariable(var); - - eq VarAccess.isNullWhenFalse(Variable var) = decl().isNullWhenFalse(var); - - syn boolean Variable.isNullWhenFalse(Variable var); - eq EnumConstant.isNullWhenFalse(Variable var) = false; - eq ParameterDeclaration.isNullWhenFalse(Variable var) = false; - eq FieldDeclarator.isNullWhenFalse(Variable var) = false; - eq CatchParameterDeclaration.isNullWhenFalse(Variable var) = false; - eq InferredParameterDeclaration.isNullWhenFalse(Variable var) = false; - eq VariableDeclarator.isNullWhenFalse(Variable var) = - type().isBoolean() && hasInit() && isEffectivelyFinal() - ? getInit().isNullWhenFalse(var) - : false; - - /** @return {@code true} if the variable var is non-null when this expression is true. */ - syn boolean Expr.isNonNullWhenTrue(Variable var) = false; - - eq NEExpr.isNonNullWhenTrue(Variable var) = - getLeftOperand().isNull() && getRightOperand().varDecl() == var - || getRightOperand().isNull() && getLeftOperand().varDecl() == var - || getLeftOperand().isTrue() && getRightOperand().isNonNullWhenFalse(var) - || getRightOperand().isTrue() && getLeftOperand().isNonNullWhenFalse(var) - || getLeftOperand().isFalse() && getRightOperand().isNonNullWhenTrue(var) - || getRightOperand().isFalse() && getLeftOperand().isNonNullWhenTrue(var); - - eq EQExpr.isNonNullWhenTrue(Variable var) = - getLeftOperand().isTrue() && getRightOperand().isNonNullWhenTrue(var) - || getRightOperand().isTrue() && getLeftOperand().isNonNullWhenTrue(var) - || getLeftOperand().isFalse() && getRightOperand().isNonNullWhenFalse(var) - || getRightOperand().isFalse() && getLeftOperand().isNonNullWhenFalse(var); - - eq LogNotExpr.isNonNullWhenTrue(Variable var) = getOperand().isNullWhenTrue(var); - - eq ParExpr.isNonNullWhenTrue(Variable var) = getExpr().isNonNullWhenTrue(var); - - eq AndLogicalExpr.isNonNullWhenTrue(Variable var) = - getLeftOperand().isNonNullWhenTrue(var) || getRightOperand().isNonNullWhenTrue(var); - - eq AndBitwiseExpr.isNonNullWhenTrue(Variable var) = - getLeftOperand().isNonNullWhenTrue(var) || getRightOperand().isNonNullWhenTrue(var); - - eq OrLogicalExpr.isNonNullWhenTrue(Variable var) = - getLeftOperand().isFalse() && getRightOperand().isNonNullWhenTrue(var) - || getRightOperand().isFalse() && getLeftOperand().isNonNullWhenTrue(var); - - eq Dot.isNonNullWhenTrue(Variable var) = - !getLeft().isVariable(var) && getRight().isNonNullWhenTrue(var); - - // Assume that a method call to X.isNo{t,n}Null_(var) is equivalent to a non-null test on var. - eq MethodAccess.isNonNullWhenTrue(Variable var) = - (name().startsWith("isNotNull") || name().startsWith("isNonNull")) - && getNumArg() == 1 && getArg(0).isVariable(var); - - eq VarAccess.isNonNullWhenTrue(Variable var) = decl().isNonNullWhenTrue(var); - - syn boolean Variable.isNonNullWhenTrue(Variable var); - eq EnumConstant.isNonNullWhenTrue(Variable var) = false; - eq ParameterDeclaration.isNonNullWhenTrue(Variable var) = false; - eq FieldDeclarator.isNonNullWhenTrue(Variable var) = false; - eq CatchParameterDeclaration.isNonNullWhenTrue(Variable var) = false; - eq InferredParameterDeclaration.isNonNullWhenTrue(Variable var) = false; - eq VariableDeclarator.isNonNullWhenTrue(Variable var) = - type().isBoolean() && hasInit() && isEffectivelyFinal() - ? getInit().isNonNullWhenTrue(var) - : false; - - // An instanceof check guards against the variable being null. - eq InstanceOfExpr.isNonNullWhenTrue(Variable var) = getExpr().isVariable(var); - - /** @return {@code true} if the variable var is non-null when this expression is false. */ - syn boolean Expr.isNonNullWhenFalse(Variable var) = false; - - eq NEExpr.isNonNullWhenFalse(Variable var) = - getLeftOperand().isTrue() && getRightOperand().isNonNullWhenTrue(var) - || getRightOperand().isTrue() && getLeftOperand().isNonNullWhenTrue(var) - || getLeftOperand().isFalse() && getRightOperand().isNonNullWhenFalse(var) - || getRightOperand().isFalse() && getLeftOperand().isNonNullWhenFalse(var); - - eq EQExpr.isNonNullWhenFalse(Variable var) = - getLeftOperand().isNull() && getRightOperand().varDecl() == var - || getRightOperand().isNull() && getLeftOperand().varDecl() == var - || getLeftOperand().isTrue() && getRightOperand().isNonNullWhenFalse(var) - || getRightOperand().isTrue() && getLeftOperand().isNonNullWhenFalse(var) - || getLeftOperand().isFalse() && getRightOperand().isNonNullWhenTrue(var) - || getRightOperand().isFalse() && getLeftOperand().isNonNullWhenTrue(var); - - eq LogNotExpr.isNonNullWhenFalse(Variable var) = getOperand().isNonNullWhenTrue(var); - - eq ParExpr.isNonNullWhenFalse(Variable var) = getExpr().isNonNullWhenFalse(var); - - eq AndLogicalExpr.isNonNullWhenFalse(Variable var) = - getLeftOperand().isTrue() && getRightOperand().isNonNullWhenFalse(var) - || getRightOperand().isTrue() && getLeftOperand().isNonNullWhenFalse(var); - - eq AndBitwiseExpr.isNonNullWhenFalse(Variable var) = - getLeftOperand().isTrue() && getRightOperand().isNonNullWhenFalse(var) - || getRightOperand().isTrue() && getLeftOperand().isNonNullWhenFalse(var); - - eq OrLogicalExpr.isNonNullWhenFalse(Variable var) = - getLeftOperand().isNonNullWhenFalse(var) || getRightOperand().isNonNullWhenFalse(var); - - eq Dot.isNonNullWhenFalse(Variable var) = - !getLeft().isVariable(var) && getRight().isNonNullWhenFalse(var); - - // Assume that a method call to X.isNull_(var) is equivalent to a null test on var. - eq MethodAccess.isNonNullWhenFalse(Variable var) = - name().startsWith("isNull") && getNumArg() == 1 && getArg(0).isVariable(var); - - eq VarAccess.isNonNullWhenFalse(Variable var) = decl().isNonNullWhenFalse(var); - - syn boolean Variable.isNonNullWhenFalse(Variable var); - eq EnumConstant.isNonNullWhenFalse(Variable var) = false; - eq ParameterDeclaration.isNonNullWhenFalse(Variable var) = false; - eq FieldDeclarator.isNonNullWhenFalse(Variable var) = false; - eq CatchParameterDeclaration.isNonNullWhenFalse(Variable var) = false; - eq InferredParameterDeclaration.isNonNullWhenFalse(Variable var) = false; - eq VariableDeclarator.isNonNullWhenFalse(Variable var) = - type().isBoolean() && hasInit() && isEffectivelyFinal() - ? getInit().isNonNullWhenFalse(var) - : false; - - syn boolean Expr.isNull() = type().isNull(); - eq NullLiteral.isNull() = true; -} diff --git a/simplecfg/src/main/jastadd/PrintCfg.jrag b/simplecfg/src/main/jastadd/PrintCfg.jrag deleted file mode 100644 index 35b7f87b20941a63f9140fb13ba2e5fa7f21c244..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/jastadd/PrintCfg.jrag +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.util.Collections; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.LinkedList; -import java.util.Set; -import java.util.Queue; - -/** Helper attributes used to print a CFG in dot graph format. */ -aspect PrintCfg { - - @Override - public String CfgNode.toString() { - return name(); - } - - public void BodyDecl.printReverseCfg() { - entry().initPredecessors(); - System.out.println("digraph " + graphName() + " {"); - exit().printReverseCfg(); - System.out.println("}"); - } - - public void CfgNode.printReverseCfg() { - Set<CfgNode> visited = Collections.newSetFromMap(new IdentityHashMap<CfgNode, Boolean>()); - Queue<CfgNode> queue = new LinkedList<CfgNode>(); - - // Enqueue this node. - visited.add(this); - queue.add(this); - - while (!queue.isEmpty()) { - CfgNode work = queue.poll(); - - System.out.format(" %s%s;\n", work.dotId(), work.dotAttributes()); - - // Add all out-edges for this node. - for (CfgNode succ : work.predecessors) { - System.out.format(" %s -> %s;\n", work.dotId(), succ.dotId()); - if (!visited.contains(succ)) { - visited.add(succ); - queue.add(succ); - } - } - } - } - - public void BodyDecl.printCfg() { - System.out.println("digraph " + graphName() + " {"); - entry().printCfg(); - System.out.println("}"); - } - - public void CfgNode.printCfg() { - Set<CfgNode> visited = Collections.newSetFromMap(new IdentityHashMap<CfgNode, Boolean>()); - Queue<CfgNode> queue = new LinkedList<CfgNode>(); - - // Enqueue this node. - visited.add(this); - queue.add(this); - - while (!queue.isEmpty()) { - CfgNode work = queue.poll(); - - System.out.format(" %s%s;\n", work.dotId(), work.dotAttributes()); - - // Add all out-edges for this node. - for (CfgNode succ : work.successors()) { - System.out.format(" %s -> %s;\n", work.dotId(), succ.dotId()); - if (!visited.contains(succ)) { - visited.add(succ); - queue.add(succ); - } - } - } - } - - syn String BodyDecl.graphName() = ""; - eq MethodDecl.graphName() = name(); - - /** - * The ID for this node in a dot graph. - */ - syn String CfgNode.dotId() = String.format("n%08X", hashCode()); - - // TODO(joqvist): escape string literals in generated labels. - syn String CfgNode.dotAttributes() = " [label=\"" + name() + "\"]"; - eq CfgBranch.dotAttributes() = " [label=\"" + name() + "\",shape=diamond]"; - eq CfgException.dotAttributes() = " [label=\"" + name() + "\",shape=box]"; - eq CfgMarker.dotAttributes() = " [label=\"" + name() + "\",shape=box]"; - - syn String CfgNode.name(); - eq CfgBranch.name() = branchLabel(); - eq CfgEntry.name() = "entry"; - eq CfgExit.name() = "exit"; - eq CfgException.name() = "exception"; - eq CfgMarker.name() = markerName(); - eq CfgMethodCall.name() = callLabel(); - - inh String CfgMethodCall.callLabel(); - eq MethodAccess.call().callLabel() = name() + "()"; - - inh String CfgBranch.branchLabel(); - eq IfStmt.branch().branchLabel() = "if (" + getCondition().prettyPrint() + ")"; - eq ConditionalExpr.branch().branchLabel() = "if (" + getCondition().prettyPrint() + ")"; - eq ForStmt.branch().branchLabel() = "for (" + getCondition().prettyPrint() + ")"; - eq WhileStmt.branch().branchLabel() = "while (" + getCondition().prettyPrint() + ")"; - eq DoStmt.branch().branchLabel() = "do_while (" + getCondition().prettyPrint() + ")"; - eq EnhancedForStmt.branch().branchLabel() = String.format("for (%s %s : %s)", - getVariableDecl().getTypeAccess().prettyPrint(), - getVariableDecl().getID(), - getExpr().prettyPrint()); - eq SwitchStmt.branch().branchLabel() = "switch (" + getExpr().prettyPrint() + ")"; - - inh String CfgMarker.markerName(); - eq BreakStmt.marker().markerName() = "break"; - eq ContinueStmt.marker().markerName() = "continue"; - eq ConditionalExpr.thenEndMarker().markerName() = "then-end"; - eq ConditionalExpr.elseEndMarker().markerName() = "else-end"; - eq IfStmt.thenEndMarker().markerName() = "then-end"; - eq IfStmt.elseEndMarker().markerName() = "else-end"; - eq ReturnStmt.marker().markerName() = "return"; - eq TryStmt.tryEntryMarker().markerName() = "try"; - eq Program.getChild().markerName() = "marker"; - eq Dot.nullableDereferenceMarker().markerName() = "nullable access"; - eq ForStmt.loopEndMarker().markerName() = "for-end"; - eq EnhancedForStmt.loopEndMarker().markerName() = "for-end"; - eq WhileStmt.loopEndMarker().markerName() = "while-end"; - eq DoStmt.doEntryMarker().markerName() = "do-entry"; -} diff --git a/simplecfg/src/main/jastadd/PrintCfgTest.jrag b/simplecfg/src/main/jastadd/PrintCfgTest.jrag deleted file mode 100644 index cc881f8bc2e746752bd5a7e8ed88022c5a3c81da..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/jastadd/PrintCfgTest.jrag +++ /dev/null @@ -1,179 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.util.Set; - -import java.util.Collections; -import java.util.Queue; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.Queue; -import java.util.LinkedList; - -/** Attributes useful for generating a test case from a CFG. */ -aspect PrintCfgTest { - - /** Generate a test case from the CFG of this body decl. */ - public void BodyDecl.printCfgTest() { - CfgNode entry = entry(); - String className = hostType().name(); - String testName = className.substring(0, 1).toLowerCase() - + className.substring(1); - System.out.println(" @Test public void " + testName + "() {"); - System.out.println(" CfgNode entry = parseCfg(\"" + className + "\");"); - Queue<CfgNode> work = new LinkedList<CfgNode>(); - Set<CfgNode> visited = Collections.newSetFromMap( - new IdentityHashMap<CfgNode, Boolean>()); - visited.add(entry); - Map<CfgNode, String> vars = new HashMap<CfgNode, String>(); - vars.put(entry, entry.toString()); - Map<String, Integer> nextIds = new HashMap<String, Integer>(); - nextIds.put("entry", 2); - work.add(entry); - while (!work.isEmpty()) { - CfgNode node = work.poll(); - boolean testSuccs = node.printAssert(visited, vars, nextIds); - if (testSuccs) { - for (CfgNode succ : node.successors()) { - if (!visited.contains(succ)) { - visited.add(succ); - work.add(succ); - } - } - } - } - System.out.println(" }"); - } - - /** - * @return {@code true} if successors should be tested. - */ - protected boolean CfgNode.printAssert( - Set<CfgNode> visited, - Map<CfgNode, String> vars, - Map<String, Integer> nextIds) { - Set<? extends CfgNode> successors = successors(); - if (successors.size() == 1) { - CfgNode succ = successors.iterator().next(); - String nodeName = nextVarName(succ.varName(), nextIds); - if (!visited.contains(succ)) { - vars.put(succ, nodeName); - System.out.println(String.format( - " CfgNode %s = succ(%s, \"%s\");", - nodeName, vars.get(this), succ.name())); - } else { - System.out.println(String.format( - " assertThat(succ(%s, \"%s\")).isSameAs(%s);", - vars.get(this), succ.name(), vars.get(succ))); - } - } else if (successors.size() > 1) { - boolean duplicates = false; - Set<String> dups = new HashSet<String>(); - for (CfgNode succ : successors) { - if (dups.contains(succ.name())) { - duplicates = true; - break; - } - dups.add(succ.name()); - } - if (duplicates) { - System.out.print(String.format( - " assertThat(%s.successors()).containsExactly(\"", - vars.get(this))); - boolean first = true; - for (CfgNode succ : successors) { - if (!first) { - System.out.print("\", \""); - } - first = false; - System.out.print(succ.name()); - } - System.out.println("\");"); - System.out.println(String.format( - " // NOTE Code to test the successors of %s was not " - + "auto-generated\n // due to identical successor names.", - vars.get(this))); - return false; - } else { - String arrayName = nextVarName(this.varName() + "Succ", nextIds); - System.out.print(String.format( - " CfgNode[] %s = succ(%s", - arrayName, vars.get(this))); - int index = 0; - Map<String, CfgNode> succMap = new HashMap<String, CfgNode>(); - for (CfgNode succ : successors) { - System.out.format(", \"%s\"", succ.name()); - succMap.put(arrayName + "[" + index + "]", succ); - index += 1; - } - System.out.println(");"); - for (Map.Entry<String, CfgNode> succ : succMap.entrySet()) { - if (!visited.contains(succ.getValue())) { - vars.put(succ.getValue(), succ.getKey()); - } else { - System.out.println(String.format( - " assertThat(%s).isSameAs(%s);", - succ.getKey(), vars.get(succ.getValue()))); - } - } - } - } - return true; - } - - protected static String CfgNode.nextVarName(String name, - Map<String, Integer> nextIds) { - if (nextIds.containsKey(name)) { - int id = nextIds.get(name); - nextIds.put(name, id+1); - return name + id; - } else { - nextIds.put(name, 2); - return name; - } - } - - syn String CfgNode.varName() = name(); - eq CfgBranch.varName() = branchKind() + "Branch"; - eq CfgException.varName() = "exception"; - eq CfgMarker.varName() = markerVarName(); - eq CfgMethodCall.varName() = methodAccess().getID(); - - inh String CfgBranch.branchKind(); - eq IfStmt.branch().branchKind() = "if"; - eq ConditionalExpr.branch().branchKind() = "if"; - eq ForStmt.branch().branchKind() = "for"; - eq WhileStmt.branch().branchKind() = "while"; - eq DoStmt.branch().branchKind() = "doWhile"; - eq EnhancedForStmt.branch().branchKind() = "for"; - eq SwitchStmt.branch().branchKind() = "switch"; - - inh String CfgMarker.markerVarName(); - eq BreakStmt.marker().markerVarName() = "breakMarker"; - eq ContinueStmt.marker().markerVarName() = "continueMarker"; - eq ConditionalExpr.thenEndMarker().markerVarName() = "thenEnd"; - eq ConditionalExpr.elseEndMarker().markerVarName() = "elseEnd"; - eq IfStmt.thenEndMarker().markerVarName() = "thenEnd"; - eq IfStmt.elseEndMarker().markerVarName() = "elseEnd"; - eq ReturnStmt.marker().markerVarName() = "returnMarker"; - eq TryStmt.tryEntryMarker().markerVarName() = "tryEntry"; - eq Program.getChild().markerVarName() = "marker"; - eq Dot.nullableDereferenceMarker().markerVarName() = "nullable"; - eq ForStmt.loopEndMarker().markerVarName() = "forEnd"; - eq EnhancedForStmt.loopEndMarker().markerVarName() = "forEnd"; - eq WhileStmt.loopEndMarker().markerVarName() = "whileEnd"; - eq DoStmt.doEntryMarker().markerVarName() = "doEntry"; -} diff --git a/simplecfg/src/main/jastadd/SimpleCFG.jrag b/simplecfg/src/main/jastadd/SimpleCFG.jrag deleted file mode 100644 index 162622bb10fa429e861076736a12e726958f7378..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/jastadd/SimpleCFG.jrag +++ /dev/null @@ -1,791 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.util.Collection; -import java.util.Collections; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.Set; - -/** - * Attributes to build a simplified Control Flow Graph (CFG) for a methods, - * constructors, and initializers. - * - * <p>The simple CFG contains only method calls and branches. The simple CFG has - * a naive exception model - any exception is assumed to be throwable by any - * statement. - */ -aspect SimpleCFG { - - /** @return {@code true} if this node corresponds to a method call. */ - syn boolean CfgNode.isCall() = false; - eq CfgMethodCall.isCall() = true; - - /** @return {@code true} if this node corresponds to an exception branch. */ - syn boolean CfgNode.isException() = false; - eq CfgException.isException() = true; - - /** @return {@code true} if this node corresponds to a branch. */ - syn boolean CfgNode.isBranch() = false; - eq CfgBranch.isBranch() = true; - - /** - * Successor nodes in the CFG. - */ - syn lazy Set<? extends CfgNode> CfgNode.successors(); - - eq CfgEntry.successors() = Collections.singleton(getSucc()); - - eq CfgExit.successors() = Collections.emptySet(); - - eq CfgMethodCall.successors() = succ(); - - eq CfgBranch.successors() = succ(); - - eq CfgException.successors() = succ(); - - eq CfgMarker.successors() = succ(); - - /** - * Set that contains either one or two unique objects. The objects are - * compared with reference equality. - */ - class IdentityTupleSet<E> implements Set<E> { - final E a, b; - - public IdentityTupleSet(E a, E b) { - this.a = a; - this.b = b; - } - - @Override - public boolean add(E e) { - throw new UnsupportedOperationException(); - } - @Override - public boolean addAll(Collection<? extends E> e) { - throw new UnsupportedOperationException(); - } - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - @Override - public boolean contains(Object o) { - return o == a || o == b; - } - @Override - public boolean containsAll(Collection<?> c) { - for (Object o : c) { - if (!contains(o)) { - return false; - } - } - return true; - } - @Override - public int hashCode() { - return a.hashCode() + b.hashCode(); - } - @Override - public boolean isEmpty() { - return false; - } - @Override - public Iterator<E> iterator() { - return new Iterator<E>() { - int index = 0; - @Override - public boolean hasNext() { - return (a == b && index < 1) - || (a != b && index < 2); - } - @Override - public E next() { - return ++index == 1 ? a : b; - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - @Override - public boolean remove(Object o) { - throw new UnsupportedOperationException(); - } - @Override - public boolean removeAll(Collection<?> c) { - throw new UnsupportedOperationException(); - } - @Override - public boolean retainAll(Collection<?> c) { - throw new UnsupportedOperationException(); - } - @Override - public int size() { - return a == b ? 1 : 2; - } - @Override - public Object[] toArray() { - return new Object[] { a, b }; - } - @Override - public <T> T[] toArray(T[] array) { - array[0] = (T) a; - array[1] = (T) b; - return array; - } - @Override - public String toString() { - if (a == b) { - return "[" + a + "]"; - } else { - return "[" + a + ", " + b + "]"; - } - } - } - - /** Successors to this branch node. */ - inh Set<? extends CfgNode> CfgBranch.succ(); - - /** Successors to this method call node. */ - inh Set<? extends CfgNode> CfgMethodCall.succ(); - - inh Set<? extends CfgNode> CfgException.succ(); - - inh Set<? extends CfgNode> CfgMarker.succ(); - - /** Build a small set with two elements. */ - public <T> Set<T> ASTNode.smallSet(T a, T b) { - return new IdentityTupleSet<T>(a, b); - } - - /** - * The entry CFG node of this statement. This is the next method call, - * branch, or exit node of the simplified CFG following the entry of - * this statement. - */ - syn CfgNode Stmt.entry() = follow(); - - /** - * Find the next CFG node representing the next branch, or the next - * method access following this statement. - */ - inh CfgNode Stmt.follow(); - - inh CfgNode Expr.follow(); - - // Needed for completeness, but never used by anything relevant. - eq Program.getChild().follow() = new CfgExit(); - - /** - * The entry node in a filtered CFG. - */ - syn lazy CfgEntry BodyDecl.entry() = new CfgEntry(exit()); - - eq MethodDecl.entry() = - hasBlock() - ? new CfgEntry(getBlock().entry()) - : new CfgEntry(exit()); - - eq ConstructorDecl.entry() = new CfgEntry(getBlock().entry()); - - eq InstanceInitializer.entry() = new CfgEntry(getBlock().entry()); - - eq StaticInitializer.entry() = new CfgEntry(getBlock().entry()); - - /** - * The exit node in a filtered CFG. - */ - syn nta CfgExit BodyDecl.exit() = new CfgExit(); - - eq Block.entry() { - if (getNumStmt() > 0) { - return getStmt(0).entry(); - } else { - return follow(); - } - } - - eq LabeledStmt.entry() = getStmt().entry(); - - eq VarDeclStmt.entry() = - getNumDeclarator() > 0 - ? getDeclarator(0).entry() - : follow(); - - eq VarDeclStmt.getDeclarator(int index).follow() = - index + 1 < getNumDeclarator() - ? getDeclarator(index + 1).entry() - : follow(); - - inh CfgNode VariableDeclarator.follow(); - - syn CfgNode VariableDeclarator.entry() = - hasInit() - ? getInit().entry() - : follow(); - - eq SynchronizedStmt.entry() = getExpr().entry(); - - eq SynchronizedStmt.getExpr().follow() = getBlock().entry(); - - // Note: catch-all clauses get special treatment! - - eq TryStmt.entry() = tryEntryMarker(); - - eq TryWithResources.entry() = - getNumResource() > 0 - ? getResource(0).entry() - : super.entry(); - - eq TryWithResources.getResource(int index).follow() = - index+1 < getNumResource() - ? getResource(index+1).entry() - : super.entry(); - - /** - * The entry of a try statement has a branch to the block and to each - * catch clause or finally block. - */ - syn nta CfgMarker TryStmt.tryEntryMarker() = new CfgMarker(); - - eq TryStmt.tryEntryMarker().succ() = - joinSets(Collections.singleton(getBlock().entry()), catchBranches()); - - eq MethodAccess.exceptionNode().succ() = exceptionBranches(); - - eq ThrowStmt.exceptionNode().succ() = exceptionBranches(); - - /** - * Gives the set of CFG nodes targeted by an exception thrown at this - * statement. This includes the catch blocks of the enclosing try statement as - * well as the finally block. Does not include any targets following a - * catch of Throwable. - */ - inh Set<? extends CfgNode> MethodAccess.exceptionBranches(); - inh Set<? extends CfgNode> TryStmt.exceptionBranches(); - inh Set<? extends CfgNode> ThrowStmt.exceptionBranches(); - - inh TypeDecl TryStmt.typeThrowable(); - - eq TryStmt.getBlock().exceptionBranches() = catchBranches(); - - eq TryWithResources.getResource().exceptionBranches() = catchBranches(); - - /** - * Gives the set of CFG nodes targeted by an exception thrown inside this try - * statement. This includes the catch blocks of this try statements as - * well as the finally block. Does not include any targets following a - * catch of Throwable. - */ - syn Set<? extends CfgNode> TryStmt.catchBranches() { - // Check for catch-all clauses (catching java.lang.Throwable). - Set<CfgNode> set = Collections.newSetFromMap(new IdentityHashMap<CfgNode, Boolean>()); - for (CatchClause clause : getCatchClauseList()) { - set.add(clause.getBlock().entry()); - if (clause instanceof BasicCatch - && ((BasicCatch) clause).getParameter().type() == typeThrowable()) { - // This is a catch-all clause: no other clauses after this can catch an - // exception. - return set; - } - } - if (hasNonEmptyFinally()) { - set.add(getExceptionHandler().entry()); - } - return set; - } - - eq TryStmt.getExceptionHandler().follow() = exceptionNode(); - eq TryStmt.exceptionNode().succ() = exceptionBranches(); - - eq BodyDecl.getChild().exceptionBranches() = Collections.singleton(exit()); - - eq CompilationUnit.getChild().exceptionBranches() = Collections.emptySet(); - eq TypeDecl.getChild().exceptionBranches() = Collections.emptySet(); - - public <U, V extends U> Set<U> Stmt.joinSets(Set<U> a, Set<V> b) { - Set<U> set = Collections.newSetFromMap( - new IdentityHashMap<U, Boolean>()); - set.addAll(a); - set.addAll(b); - return set; - } - - eq TryStmt.getBlock().follow() = - hasNonEmptyFinally() - ? getFinally().entry() - : follow(); - - eq TryStmt.getCatchClause(int index).follow() = - hasNonEmptyFinally() - ? getFinally().entry() - : follow(); - - /** The CFG marker for this break statement. */ - syn nta CfgMarker BreakStmt.marker() = new CfgMarker(); - - eq BreakStmt.entry() = marker(); - eq BreakStmt.marker().succ() = - hasFinally() - ? Collections.singleton(getFinally().entry()) - : Collections.singleton(targetStmt().follow()); - eq BreakStmt.marker().follow() = - hasFinally() - ? getFinally().entry() - : targetStmt().follow(); - - eq BreakStmt.getFinally().follow() = targetStmt().follow(); - - /** The CFG marker for this continue statement. */ - syn nta CfgMarker ContinueStmt.marker() = new CfgMarker(); - - eq ContinueStmt.entry() = marker(); - eq ContinueStmt.marker().succ() = - hasFinally() - ? Collections.singleton(getFinally().entry()) - : Collections.singleton(targetStmt().entry()); - eq ContinueStmt.marker().follow() = - hasFinally() - ? getFinally().entry() - : targetStmt().entry(); - - eq ContinueStmt.getFinally().follow() = targetStmt().follow(); - - /** The CFG marker for this continue statement. */ - syn nta CfgMarker ReturnStmt.marker() = new CfgMarker(); - - eq ReturnStmt.entry() = marker(); - eq ReturnStmt.marker().succ() = - hasResult() - ? Collections.singleton(getResult().entry()) - : Collections.singleton(returnTarget()); - eq ReturnStmt.marker().follow() = - hasResult() - ? getResult().entry() - : returnTarget(); - - eq ReturnStmt.getResult().follow() = returnTarget(); - - inh CompilationUnit ReturnStmt.compilationUnit(); - - syn CfgNode ReturnStmt.returnTarget() = - hasFinally() - ? getFinally().entry() - : methodExit(); - - eq ReturnStmt.getFinally().follow() = methodExit(); - - /** - * Finds the CFG exit node for the enclosing method, constructor, or - * initializer. - */ - inh CfgNode ReturnStmt.methodExit(); - - eq BodyDecl.getChild().methodExit() = exit(); - - eq LambdaBody.getChild().methodExit() = exit(); - - eq ThrowStmt.entry() = getExpr().entry(); - - // Since we not have precise type lookups we need to approximate the possible - // exception branches. - eq ThrowStmt.getExpr().follow() = exceptionNode(); - - /** - * This node represents the control flow path taken when an exception - * interrupts the call. - */ - syn nta CfgException MethodAccess.exceptionNode() = new CfgException(); - - /** This node represents the control flow following the exception. */ - syn nta CfgException ThrowStmt.exceptionNode() = new CfgException(); - - /** - * This node represents the control flow path taken if an exception - * is thrown in the start of a try statement. - */ - syn nta CfgException TryStmt.exceptionNode() = new CfgException(); - - eq ExprStmt.entry() = getExpr().entry(); - - syn CfgNode Expr.entry(); - - eq ArrayAccess.entry() = getExpr().entry(); - - // All of these nodes are uninteresting for the simple CFG. - // Setting entry() = follow() makes sure the node is not included in the CFG. - eq AbstractWildcard.entry() = follow(); - eq ClassAccess.entry() = follow(); - eq DiamondAccess.entry() = follow(); - eq PackageAccess.entry() = follow(); - eq ParseName.entry() = follow(); // Always rewritten. - eq ParTypeAccess.entry() = follow(); - eq SuperAccess.entry() = follow(); - eq ThisAccess.entry() = follow(); - eq VarAccess.entry() = follow(); - eq TypeAccess.entry() = follow(); - eq SyntheticTypeAccess.entry() = follow(); - eq ClassReference.entry() = follow(); - eq ArrayReference.entry() = follow(); - eq LambdaExpr.entry() = follow(); - eq TypeMethodReference.entry() = follow(); - eq AmbiguousMethodReference.entry() = follow(); - - eq ParExpr.entry() = getExpr().entry(); - eq CastExpr.entry() = getExpr().entry(); - eq IntersectionCastExpr.entry() = getExpr().entry(); - eq Unary.entry() = getOperand().entry(); - - eq ExprMethodReference.entry() = getExpr().entry(); - - /** The method call node for this method access. */ - syn nta CfgMethodCall MethodAccess.call() = new CfgMethodCall(); - - eq MethodAccess.call().succ() = - isInsideTryBlockOrResource() - ? smallSet(exceptionNode(), follow()) - : Collections.singleton(follow()); - - // If there are arguments control flow passes to the arguments first. - eq MethodAccess.entry() = - getNumArg() > 0 - ? getArg(0).entry() - : call(); - - // If we have arguments the CfgMethodCall is placed after the last argument. - eq MethodAccess.getArg(int index).follow() = - index+1 < getNumArg() - ? getArg(index+1).entry() - : call(); - - // If there are arguments control flow passes to the arguments first. - eq ConstructorAccess.entry() = - getNumArg() > 0 - ? getArg(0).entry() - : follow(); - - // If we have arguments the CfgMethodCall is placed after the last argument. - eq ConstructorAccess.getArg(int index).follow() = - index+1 < getNumArg() - ? getArg(index+1).entry() - : follow(); - - eq ClassInstanceExpr.entry() = - getNumArg() > 0 - ? getArg(0).entry() - : getAccess().entry(); - - eq ClassInstanceExpr.getArg(int index).follow() = - index+1 < getNumArg() - ? getArg(index+1).entry() - : getAccess().entry(); - - eq ArrayInit.entry() = - getNumInit() > 0 - ? getInit(0).entry() - : follow(); - - eq ArrayInit.getInit(int index).follow() = - index+1 < getNumInit() - ? getInit(index+1).entry() - : follow(); - - /** @return {@code true} if this statement is inside a try block. */ - inh boolean MethodAccess.isInsideTryBlockOrResource(); - inh boolean Stmt.isInsideTryBlockOrResource(); - - eq CompilationUnit.getChild().isInsideTryBlockOrResource() = false; - eq TypeDecl.getChild().isInsideTryBlockOrResource() = false; - eq BodyDecl.getChild().isInsideTryBlockOrResource() = false; - eq LambdaBody.getChild().isInsideTryBlockOrResource() = false; - eq TryStmt.getBlock().isInsideTryBlockOrResource() = true; - eq TryWithResources.getResource().isInsideTryBlockOrResource() = true; - eq NTAFinallyBlock.getChild().isInsideTryBlockOrResource() = - origin.getFinallyBlock().isInsideTryBlockOrResource(); - eq Program.getChild().isInsideTryBlockOrResource() = false; - - eq InstanceOfExpr.entry() = getExpr().entry(); - - eq AssignExpr.entry() = getSource().entry(); - - eq AssignExpr.getSource().follow() = getDest().entry(); - - eq Literal.entry() = follow(); - - eq ArrayCreationExpr.entry() = - hasArrayInit() - ? getArrayInit().entry() - : follow(); - - eq Binary.entry() = getLeftOperand().entry(); - eq Binary.getLeftOperand().follow() = getRightOperand().entry(); - - eq Dot.entry() = getLeft().entry(); - eq Dot.getLeft().follow() = getRight().entry(); - - /** The branch node for this conditional expression. */ - syn nta CfgBranch ConditionalExpr.branch() = new CfgBranch(); - - /** - * The then-end node is a marker node marking the end of a then-branch in a conditional - * expression. - */ - syn nta CfgMarker ConditionalExpr.thenEndMarker() = new CfgMarker(); - - /** - * The else-end node is a marker node marking the end of a else-branch in a conditional - * expression. - */ - syn nta CfgMarker ConditionalExpr.elseEndMarker() = new CfgMarker(); - - eq ConditionalExpr.entry() = getCondition().entry(); - eq ConditionalExpr.getCondition().follow() = branch(); - eq ConditionalExpr.getTrueExpr().follow() = thenEndMarker(); - eq ConditionalExpr.getFalseExpr().follow() = elseEndMarker(); - eq ConditionalExpr.thenEndMarker().follow() = follow(); - eq ConditionalExpr.elseEndMarker().follow() = follow(); - eq ConditionalExpr.thenEndMarker().succ() = Collections.singleton(follow()); - eq ConditionalExpr.elseEndMarker().succ() = Collections.singleton(follow()); - - eq ConditionalExpr.branch().succ() = - smallSet(getTrueExpr().entry(), getFalseExpr().entry()); - - /** The branch node for this statement. */ - syn nta CfgBranch IfStmt.branch() = new CfgBranch(); - - /** The then-end node is a marker node marking the end of a then-branch in an if statement. */ - syn nta CfgMarker IfStmt.thenEndMarker() = new CfgMarker(); - - /** The else-end node is a marker node marking the end of a else-branch in an if statement. */ - syn nta CfgMarker IfStmt.elseEndMarker() = new CfgMarker(); - - eq IfStmt.entry() = getCondition().entry(); - - eq IfStmt.getCondition().follow() = branch(); - eq IfStmt.getThen().follow() = thenEndMarker(); - eq IfStmt.getElse().follow() = elseEndMarker(); - eq IfStmt.thenEndMarker().follow() = follow(); - eq IfStmt.elseEndMarker().follow() = follow(); - eq IfStmt.thenEndMarker().succ() = Collections.singleton(follow()); - eq IfStmt.elseEndMarker().succ() = Collections.singleton(follow()); - - eq IfStmt.branch().succ() = - hasElse() - ? smallSet(getThen().entry(), getElse().entry()) - : smallSet(getThen().entry(), follow()); - - /** The branch node for this statement. */ - syn nta CfgBranch ForStmt.branch() = new CfgBranch(); - - /** The CFG end marker for this loop. */ - syn nta CfgMarker ForStmt.loopEndMarker() = new CfgMarker(); - - eq ForStmt.entry() = - getNumInitStmt() > 0 - ? getInitStmt(0).entry() - : getCondition().entry(); - - eq ForStmt.getInitStmt(int index).follow() = - index+1 < getNumInitStmt() - ? getInitStmt(index+1).entry() - : getCondition().entry(); - - eq ForStmt.getCondition().follow() = branch(); - - eq ForStmt.getUpdateStmt(int index).follow() = - index+1 < getNumUpdateStmt() - ? getUpdateStmt(index+1).entry() - : getCondition().entry(); - - eq ForStmt.getStmt().follow() = loopEndMarker(); - - eq ForStmt.loopEndMarker().follow() = - getNumUpdateStmt() > 0 - ? getUpdateStmt(0).entry() - : getCondition().entry(); - - eq ForStmt.loopEndMarker().succ() = - getNumUpdateStmt() > 0 - ? Collections.singleton(getUpdateStmt(0).entry()) - : Collections.singleton(getCondition().entry()); - - eq ForStmt.branch().succ() { - if (getCondition().isTrue()) { - return Collections.singleton(getStmt().entry()); - } else if (getCondition().isFalse()) { - return Collections.singleton(follow()); - } else { - return smallSet(getStmt().entry(), follow()); - } - } - - /** The branch node for this statement. */ - syn nta CfgBranch EnhancedForStmt.branch() = new CfgBranch(); - - /** The CFG end marker for this loop. */ - syn nta CfgMarker EnhancedForStmt.loopEndMarker() = new CfgMarker(); - - eq EnhancedForStmt.branch().succ() = - smallSet(getStmt().entry(), follow()); - - eq EnhancedForStmt.entry() = getExpr().entry(); - - eq EnhancedForStmt.getExpr().follow() = branch(); - - eq EnhancedForStmt.getStmt().follow() = loopEndMarker(); - - eq EnhancedForStmt.loopEndMarker().follow() = entry(); // Loop back. - - eq EnhancedForStmt.loopEndMarker().succ() = Collections.singleton(entry()); - - /** The branch node for this statement. */ - syn nta CfgBranch WhileStmt.branch() = new CfgBranch(); - - /** The CFG end marker for this loop. */ - syn nta CfgMarker WhileStmt.loopEndMarker() = new CfgMarker(); - - eq WhileStmt.entry() = getCondition().entry(); - - eq WhileStmt.getCondition().follow() = branch(); - - eq WhileStmt.getStmt().follow() = loopEndMarker(); - - eq WhileStmt.loopEndMarker().follow() = entry(); // Loop back. - - eq WhileStmt.loopEndMarker().succ() = Collections.singleton(entry()); - - eq WhileStmt.branch().succ() { - if (getCondition().isTrue()) { - return Collections.singleton(getStmt().entry()); - } else if (getCondition().isFalse()) { - return Collections.singleton(follow()); - } else { - return smallSet(getStmt().entry(), follow()); - } - } - - /** The branch node for this statement. */ - syn nta CfgBranch DoStmt.branch() = new CfgBranch(); - - /** The CFG entry marker for this loop. */ - syn nta CfgMarker DoStmt.doEntryMarker() = new CfgMarker(); - - eq DoStmt.entry() = doEntryMarker(); - - eq DoStmt.doEntryMarker().follow() = getStmt().entry(); - - eq DoStmt.doEntryMarker().succ() = Collections.singleton(getStmt().entry()); - - eq DoStmt.getStmt().follow() = getCondition().entry(); - - eq DoStmt.getCondition().follow() = branch(); - - // Loop back. - eq DoStmt.branch().succ() { - if (getCondition().isTrue()) { - return Collections.singleton(entry()); - } else if (getCondition().isFalse()) { - return Collections.singleton(follow()); - } else { - return smallSet(entry(), follow()); - } - } - - syn nta CfgBranch SwitchStmt.branch() = new CfgBranch(); - - eq SwitchStmt.entry() = getExpr().entry(); - - eq SwitchStmt.getExpr().follow() = branch(); - - eq SwitchStmt.branch().succ() { - Set<CfgNode> set = Collections.newSetFromMap( - new IdentityHashMap<CfgNode, Boolean>()); - boolean hasDefault = false; - for (Stmt stmt : getBlock().getStmtList()) { - if (stmt instanceof Case) { - set.add(stmt.entry()); - if (stmt instanceof DefaultCase) { - hasDefault = true; - } - } - } - if (!hasDefault) { - set.add(follow()); - } - return set; - } - - eq BodyDecl.getChild().follow() = exit(); - - eq Block.getStmt(int index).follow() = - index+1 < getNumStmt() - ? getStmt(index+1).entry() - : follow(); - - syn lazy CfgEntry LambdaBody.entry(); - eq BlockLambdaBody.entry() = new CfgEntry(getBlock().entry()); - eq ExprLambdaBody.entry() = new CfgEntry(getExpr().entry()); - - syn nta CfgExit LambdaBody.exit() = new CfgExit(); - - eq BlockLambdaBody.getBlock().follow() = exit(); - eq ExprLambdaBody.getExpr().follow() = exit(); - - /** Find the method access which this call node is associated with. */ - inh MethodAccess CfgMethodCall.methodAccess(); - eq MethodAccess.call().methodAccess() = this; - - /** Find the entry node to the CFG this statement belongs to. */ - inh lazy CfgEntry Stmt.cfg(); - inh lazy CfgEntry Expr.cfg(); - - eq BodyDecl.getChild().cfg() = entry(); - eq LambdaBody.getChild().cfg() = entry(); - - eq CompilationUnit.getChild().cfg() { - throw new Error("Not in a CFG."); - } - - /** - * Predecessors of this node in the CFG. Predecessors are filled in when - * accessing the CFG through the cfg() attribute. - */ - protected Collection<CfgNode> CfgNode.predecessors = - new LinkedList<CfgNode>(); - - private boolean CfgEntry.initializedPredecessors = false; - - /** Initializes the predecessor sets for each node in a CFG. */ - protected void CfgEntry.initPredecessors() { - if (!initializedPredecessors) { - initializedPredecessors = true; - Queue<CfgNode> queue = new LinkedList<CfgNode>(); - queue.add(this); - while (!queue.isEmpty()) { - CfgNode node = queue.poll(); - for (CfgNode succ : node.successors()) { - if (succ.predecessors.isEmpty()) { - queue.add(succ); - } - succ.predecessors.add(node); - } - } - } - } -} diff --git a/simplecfg/src/main/jastadd/VariableDeclarationScope.jrag b/simplecfg/src/main/jastadd/VariableDeclarationScope.jrag deleted file mode 100644 index 653d51169e81577c0611a9970b4c60505790cf36..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/jastadd/VariableDeclarationScope.jrag +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * This aspect adds attributes to check if a variable was declared inside an a statement represented - * by a particular CFG node. - */ -aspect VariableDeclarationScope { - - /** @return {@code true} if this method access has the given variable as receiver. */ - syn boolean MethodAccess.hasReceiver(Variable receiver) = - hasPrevExpr() && prevExpr().isVariable(receiver); - - /** - * Test if the CFG node is tied to a statement that declares the variable, - * or if the declaration of the variable is somewhere inside the statement this - * branch represents. - */ - syn boolean CfgNode.isDeclarationOf(Variable var) = false; - - eq CfgBranch.isDeclarationOf(Variable var) = - branchDeclaresVariable(var) - || variableDeclaredInsideStatement(var); - - syn boolean CfgBranch.variableDeclaredInsideStatement(Variable var) { - Stmt stmt = hostStatement(); - ASTNode node = (ASTNode) var; - while (node != stmt && node != null) { - node = node.getParent(); - } - return node == stmt; - } - - /** The statement this branch represents. */ - inh Stmt CfgBranch.hostStatement(); - - /** The statement this expression is part of. */ - inh Stmt Expr.hostStatement(); - eq Stmt.getChild().hostStatement() = this; - eq Program.getChild().hostStatement() = null; - - eq IfStmt.branch().hostStatement() = this; - eq ConditionalExpr.branch().hostStatement() = hostStatement(); - eq ForStmt.branch().hostStatement() = this; - eq WhileStmt.branch().hostStatement() = this; - eq DoStmt.branch().hostStatement() = this; - eq EnhancedForStmt.branch().hostStatement() = this; - eq SwitchStmt.branch().hostStatement() = this; - - /** Test if the CFG node is tied to a statement that declares the variable. */ - inh boolean CfgBranch.branchDeclaresVariable(Variable var); - - eq EnhancedForStmt.branch().branchDeclaresVariable(Variable var) = - getVariableDecl() == var; - eq IfStmt.branch().branchDeclaresVariable(Variable var) = false; - eq ConditionalExpr.branch().branchDeclaresVariable(Variable var) = false; - eq ForStmt.branch().branchDeclaresVariable(Variable var) = false; - eq WhileStmt.branch().branchDeclaresVariable(Variable var) = false; - eq DoStmt.branch().branchDeclaresVariable(Variable var) = false; - eq SwitchStmt.branch().branchDeclaresVariable(Variable var) = false; - -} diff --git a/simplecfg/src/main/java/com/google/simplecfg/ExtendJAnalyzerFrontend.java b/simplecfg/src/main/java/com/google/simplecfg/ExtendJAnalyzerFrontend.java deleted file mode 100644 index 15ab9aaffe3ac74debc46a5a8551f8ec5a49a7c5..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/java/com/google/simplecfg/ExtendJAnalyzerFrontend.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * <p> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p> - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.simplecfg; - -import org.extendj.ExtendJVersion; -import org.extendj.ast.CompilationUnit; -import org.extendj.ast.ExtendJFinding; -import org.extendj.ast.Frontend; -import org.extendj.ast.Program; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * Produces findings using analyzers implemented in the ExtendJ compiler. - */ -public class ExtendJAnalyzerFrontend extends Frontend { - - private final Collection<ExtendJFinding> findings = new ArrayList<>(); - - public ExtendJAnalyzerFrontend() { - super("Simple CFG Checker", ExtendJVersion.getVersion()); - } - - /** - * Analyze a single file for findings and return the findings in a collection. - */ - public static Collection<ExtendJFinding> analyzeFile(final String path) throws Error { - ExtendJAnalyzerFrontend checker = new ExtendJAnalyzerFrontend(); - int result = checker.run(new String[]{path}); - if (result != EXIT_SUCCESS) { - throw new Error("exit code: " + result); - } - return checker.findings; - } - - /** - * Returns the list of findings from the analyzed source files. - * - * <p>Used by ExtendJAnalyzerMain to print the generated findings on stdout. - */ - Collection<ExtendJFinding> getFindings() { - return findings; - } - - /** - * Run the Java checker. - * - * @param args command-line arguments - * @return 0 on success, 1 on error, 2 on configuration error, 3 on system - */ - public int run(String[] args) { - return run(args, Program.defaultBytecodeReader(), Program.defaultJavaParser()); - } - - @Override - protected int processCompilationUnit(CompilationUnit unit) { - super.processCompilationUnit(unit); - if (unit.fromSource()) { - findings.addAll(unit.findings()); - } - return EXIT_SUCCESS; - } -} diff --git a/simplecfg/src/main/java/com/google/simplecfg/ExtendJAnalyzerMain.java b/simplecfg/src/main/java/com/google/simplecfg/ExtendJAnalyzerMain.java deleted file mode 100644 index 78c7422d7134857755ddb5d67d85107cab81ddf7..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/java/com/google/simplecfg/ExtendJAnalyzerMain.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * <p> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p> - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.simplecfg; - -import org.extendj.ast.ExtendJFinding; - -/** - * Produces findings using analyzers implemented in the ExtendJ compiler. - */ -public class ExtendJAnalyzerMain { - - /** - * Run the ExtendJ analyzer on the files supplied on the command line. - * @param args command-line arguments - */ - public static void main(String[] args) { - ExtendJAnalyzerFrontend checker = new ExtendJAnalyzerFrontend(); - int result = checker.run(args); - if (result != 0) { - System.exit(result); - } - System.out.println("Found " + checker.getFindings().size() + " findings."); - for (ExtendJFinding finding : checker.getFindings()) { - System.out.println(finding); - } - } -} diff --git a/simplecfg/src/main/java/com/google/simplecfg/PrintCfg.java b/simplecfg/src/main/java/com/google/simplecfg/PrintCfg.java deleted file mode 100644 index 31c69ffe3e6f2815fd33a1c121c48c5ce7e669d0..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/java/com/google/simplecfg/PrintCfg.java +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * <p> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p> - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.simplecfg; - -import org.extendj.ast.BodyDecl; -import org.extendj.ast.CompilationUnit; -import org.extendj.ast.Program; -import org.extendj.ast.TypeDecl; -import org.extendj.parser.JavaParser; - -import java.io.FileInputStream; -import java.util.HashSet; -import java.util.Set; - -/** - * Prints a Simplified Control Flow Graph for the first method in a Java program. - */ -public class PrintCfg { - - public static void main(String args[]) { - int exitCode = new PrintCfg().run(args); - if (exitCode != 0) { - System.exit(exitCode); - } - } - - private int run(String args[]) { - Set<String> argSet = new HashSet<>(); - for (String arg : args) { - argSet.add(arg); - } - boolean reverse = argSet.contains("-reverse"); - for (String path : args) { - if (!path.equals("-reverse")) { - try { - Program program = new Program(); - program.setTypeLookupFilter(Program.BASE_LIBRARY_FILTER); - CompilationUnit unit = new JavaParser().parse(new FileInputStream(path), path); - // Attach the parsed unit to a program node so we have a healthy AST. - program.addCompilationUnit(unit); - // Ensure compilation unit is set to final. This is important to get - // caching to work right in the AST. - unit = program.getCompilationUnit(0); - for (TypeDecl type : unit.getTypeDeclList()) { - for (BodyDecl bd : type.getBodyDeclList()) { - if (reverse) { - bd.printReverseCfg(); - } else { - bd.printCfg(); - } - } - } - } catch (Exception e) { - System.err.println("Failed to parse input file: " + path); - e.printStackTrace(); - return 1; - } - } - } - return 0; - } -} diff --git a/simplecfg/src/main/java/com/google/simplecfg/TestGenerator.java b/simplecfg/src/main/java/com/google/simplecfg/TestGenerator.java deleted file mode 100644 index 83172eaf4b0b76d19af80af6476ec4fabb661db7..0000000000000000000000000000000000000000 --- a/simplecfg/src/main/java/com/google/simplecfg/TestGenerator.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * <p> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p> - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.simplecfg; - -import org.extendj.ast.BodyDecl; -import org.extendj.ast.CompilationUnit; -import org.extendj.ast.Program; -import org.extendj.ast.TypeDecl; -import org.extendj.parser.JavaParser; - -import java.io.FileInputStream; - -/** Generate test cases for the first CFG of each input class. */ -class TestGenerator { - - public static void main(String args[]) { - int exitCode = new TestGenerator().run(args); - if (exitCode != 0) { - System.exit(exitCode); - } - } - - private int run(String args[]) { - for (String path : args) { - try { - Program program = new Program(); - program.setTypeLookupFilter(Program.BASE_LIBRARY_FILTER); - CompilationUnit unit = new JavaParser().parse(new FileInputStream(path), path); - // Attach the parsed unit to a program node so we have a healthy AST. - program.addCompilationUnit(unit); - // Ensure compilation unit is set to final. This is important to get - // caching to work right in the AST. - unit = program.getCompilationUnit(0); - if (unit.getNumTypeDecl() < 1) { - System.err.println("Error: no classes declared in file " + path); - return 1; - } - TypeDecl type = unit.getTypeDecl(0); - if (type.getNumBodyDecl() < 1) { - System.err.println("Error: first class has no body decls in file " + path); - return 1; - } - BodyDecl bd = type.getBodyDecl(0); - bd.printCfgTest(); - } catch (Exception e) { - System.err.println("Failed to parse input file: " + path); - e.printStackTrace(); - return 1; - } - } - return 0; - } -} diff --git a/simplecfg/src/test/java/com/google/simplecfg/AlreadyClosedTest.java b/simplecfg/src/test/java/com/google/simplecfg/AlreadyClosedTest.java deleted file mode 100644 index b2db5b2dda0a72955e5472f99619582b697d7e18..0000000000000000000000000000000000000000 --- a/simplecfg/src/test/java/com/google/simplecfg/AlreadyClosedTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.simplecfg; - -import static com.google.common.truth.Truth.assertThat; - -import org.extendj.ast.Program; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.util.Collection; - -/** Integration tests for the already-closed checker. */ -@RunWith(JUnit4.class) -public class AlreadyClosedTest { - - @Test public void test01() { - Collection<String> findings = StmtCfgTest.findings("Close01", Program.ANALYZER_TYPE_FILTER); - assertThat(findings).containsExactly( - "testdata/Close01.javax:23:5: close() may have already been called on writer at this point"); - } - - /** - * Test that an already-closed finding was generated on the correct line for a simple positive - * test case. - * - * <p>This test case effectively checks that the type analysis works because the type used is - * java.io.Writer, and the analyzer will check if that type is a subtype of java.io.Closeable. - */ - @Test public void writer01() { - Collection<String> findings = StmtCfgTest.findings("AlreadyClosedWriter01", - Program.ANALYZER_TYPE_FILTER); - assertThat(findings).hasSize(1); - assertThat(findings).containsExactly( - "testdata/AlreadyClosedWriter01.javax:27:5: close() may have already been called on writer at this point"); - } - - @Test public void controlFlow01() { - Collection<Integer> lines = StmtCfgTest.findingLines("AlreadyClosedControlFlow01", - Program.NO_TYPE_FILTER); - assertThat(lines).containsExactly(34, 60, 68, 79, 84, 103, 118); - } - - @Test public void negativeFindings01() { - Collection<String> findings = StmtCfgTest.findings("AlreadyClosedNegativeFindings01", - Program.ANALYZER_TYPE_FILTER); - assertThat(findings).isEmpty(); - } -} diff --git a/simplecfg/src/test/java/com/google/simplecfg/NullableDereferenceTest.java b/simplecfg/src/test/java/com/google/simplecfg/NullableDereferenceTest.java deleted file mode 100644 index 5d49861b32151b1edd3f9f983d51712fda724839..0000000000000000000000000000000000000000 --- a/simplecfg/src/test/java/com/google/simplecfg/NullableDereferenceTest.java +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.simplecfg; - -import static com.google.common.truth.Truth.assertThat; - -import org.extendj.ast.CompilationUnit; -import org.extendj.ast.ExtendJFinding; -import org.extendj.ast.Program; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.util.Collection; - -/** - * Integration tests for the nullable dereference checker. - * - * <p>Tests are grouped by the type of null guard used, and then split arbitrarily into separate - * tests/files in order to not have too many positive/negative finding tests in a single test file. - */ -@RunWith(JUnit4.class) -public class NullableDereferenceTest { - - @Test public void suggestedFixEndsWithNewline() { - CompilationUnit unit = StmtCfgTest.parseFile("NullableNullGuard01", - Program.ANALYZER_TYPE_FILTER); - Collection<ExtendJFinding> findings = unit.findings(); - assertThat(findings).isNotEmpty(); - ExtendJFinding finding = findings.iterator().next(); - assertThat(finding.fixes).hasSize(1); - assertThat(finding.fixes.iterator().next().newText).endsWith("\n"); - } - - @Test public void nullGuards01() { - Collection<String> findings = StmtCfgTest.findings("NullableNullGuard01"); - assertThat(findings).containsExactly( - "testdata/NullableNullGuard01.javax:42:25: Dereferencing p, which was declared @Nullable.", - "testdata/NullableNullGuard01.javax:49:12: Dereferencing p, which was declared @Nullable.", - "testdata/NullableNullGuard01.javax:62:12: Dereferencing p, which was declared @Nullable.", - "testdata/NullableNullGuard01.javax:93:12: Dereferencing q, which was declared @Nullable." - ); - } - - @Test public void nullGuards02() { - Collection<String> findings = StmtCfgTest.findings("NullableNullGuard02"); - assertThat(findings).containsExactly( - "testdata/NullableNullGuard02.javax:49:7: Dereferencing p, which was declared @Nullable.", - "testdata/NullableNullGuard02.javax:54:7: Dereferencing p, which was declared @Nullable." - ); - } - - @Test public void nullGuards03() { - Collection<Integer> lines = StmtCfgTest.findingLines("NullableNullGuard03", - Program.ANALYZER_TYPE_FILTER); - assertThat(lines).containsExactly(28, 34, 41, 48, 113, 119); - } - - @Test public void methodNullGuard01() { - Collection<String> findings = StmtCfgTest.findings("NullableMethodNullGuard01"); - assertThat(findings).isEmpty(); - } - - @Test public void dataflow01() { - Collection<String> findings = StmtCfgTest.findings("NullableDataflow01"); - assertThat(findings).containsExactly( - "testdata/NullableDataflow01.javax:27:7: Dereferencing p, which was declared @Nullable.", - "testdata/NullableDataflow01.javax:35:7: Dereferencing p, which was declared @Nullable." - ); - } - - @Test public void instanceOf() { - Collection<String> findings = StmtCfgTest.findings("NullableInstanceOf"); - assertThat(findings).isEmpty(); - } - - @Test public void variableArity() { - Collection<String> findings = StmtCfgTest.findings("NullableVariableArity"); - assertThat(findings).isEmpty(); - } - - @Test public void nullableDereference01() { - Collection<String> findings = StmtCfgTest.findings("NullableDereference01"); - assertThat(findings).containsExactly( - "testdata/NullableDereference01.javax:27:12: Dereferencing p, which was declared @Nullable.", - "testdata/NullableDereference01.javax:31:12: Dereferencing p, which was declared @Nullable." - ); - } - - /** Test false positive for GitHub issue #10. */ - @Test public void issue10() { - Collection<String> findings = StmtCfgTest.findings("NullableDereferenceIssue10"); - assertThat(findings).containsExactly( - "testdata/NullableDereferenceIssue10.javax:34:31: Dereferencing y, which was declared @Nullable." - ); - } - - @Test public void issue11() { - Collection<String> findings = StmtCfgTest.findings("NullableDereferenceIssue11"); - assertThat(findings).isEmpty(); - } - - @Test public void issue12() { - Collection<String> findings = StmtCfgTest.findings("NullableDereferenceIssue12"); - assertThat(findings).isEmpty(); - } - - @Test public void eqExpr() { - Collection<String> findings = StmtCfgTest.findings("NullableDereferenceEqExpr"); - assertThat(findings).isEmpty(); - } - - @Test public void neExpr() { - Collection<String> findings = StmtCfgTest.findings("NullableDereferenceNeExpr"); - assertThat(findings).isEmpty(); - } - - @Test public void methodCall() { - Collection<String> findings = StmtCfgTest.findings("NullableDereferenceMethodCall"); - assertThat(findings).containsExactly( - "testdata/NullableDereferenceMethodCall.javax:41:16: " - + "Dereferencing p, which was declared @Nullable."); - } - - @Test public void issue13() { - Collection<String> findings = StmtCfgTest.findings("NullableDereferenceIssue13"); - assertThat(findings).containsExactly( - "testdata/NullableDereferenceIssue13.javax:33:7: " - + "Dereferencing obj, which was declared @Nullable."); - } -} diff --git a/simplecfg/src/test/java/com/google/simplecfg/StmtCfgTest.java b/simplecfg/src/test/java/com/google/simplecfg/StmtCfgTest.java deleted file mode 100644 index b9d3f1c49142aa1793083e57ce7343bc6e7ffc84..0000000000000000000000000000000000000000 --- a/simplecfg/src/test/java/com/google/simplecfg/StmtCfgTest.java +++ /dev/null @@ -1,629 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.simplecfg; - -import org.extendj.ast.*; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.util.*; - -import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; - -/** Tests for simplified Control Flow Graphs built for methods/constructors/initializers. */ -@RunWith(JUnit4.class) -public class StmtCfgTest { - - /** Helper method to parse an ExtendJ compilation unit from a file. */ - protected static CompilationUnit parseFile(String filename, TypeLookupFilter typeFilter) { - String path = "testdata/" + filename + ".javax"; - try { - Program program = new Program(); - program.initBytecodeReader(Program.defaultBytecodeReader()); - program.initJavaParser(Program.defaultJavaParser()); - program.setTypeLookupFilter(typeFilter); - - CompilationUnit unit = program.addSourceFile(path); - - TypeDecl object = program.lookupType("java.lang", "Object"); - if (object.isUnknown()) { - // If we try to continue without java.lang.Object, we'll just get a stack overflow - // in member lookups because the unknown (Object) type would be treated as circular. - System.err.println("Error: java.lang.Object is missing." - + " The Java standard library was not found."); - throw new RuntimeException("exiting with unhandled error!"); - } - - return unit; - } catch (Exception e) { - e.printStackTrace(); - fail("failed to parse test input file: " + path); - } - // Failed. - return null; - } - - /** Helper to get the findings for a given file. */ - protected static Collection<String> findings(String filename) { - return findings(filename, Program.ANALYZER_TYPE_FILTER); - } - - /** Helper to get the findings for a given file. */ - protected static Collection<String> findings(String filename, TypeLookupFilter typeFilter) { - CompilationUnit unit = StmtCfgTest.parseFile(filename, typeFilter); - Collection<String> findings = new HashSet<String>(); - for (ExtendJFinding finding : unit.findings()) { - findings.add(finding.toString()); - } - return findings; - } - - /** Helper to get the line numbers where findings were reported for a given file. */ - protected static Collection<Integer> findingLines(String filename, TypeLookupFilter typeFilter) { - CompilationUnit unit = StmtCfgTest.parseFile(filename, typeFilter); - Collection<Integer> lines = new LinkedList<>(); - for (ExtendJFinding finding : unit.findings()) { - lines.add(finding.startLine); - } - return lines; - } - - private static CfgNode parseCfg(String filename) { - CompilationUnit unit = parseFile(filename, Program.BASE_LIBRARY_FILTER); - assertThat(unit.getTypeDeclList()).isNotEmpty(); - assertThat(unit.getTypeDecl(0).getBodyDeclList()).isNotEmpty(); - return unit.getTypeDecl(0).getBodyDecl(0).entry(); - } - - /** - * Assert and return a single successor of the node. - */ - private static CfgNode succ(CfgNode node, String successor) { - assertThat(cfgNames(node.successors())).containsExactly(successor); - return node.successors().iterator().next(); - } - - /** - * Assert the successors of the node and return them in an array - * using the same ordering as the input array. - */ - private static CfgNode[] succ(CfgNode node, String... successors) { - assertThat(cfgNames(node.successors())).containsExactly((Object[]) successors); - - // Ensure no duplicate successor names. - Set<String> dups = new HashSet<String>(); - for (String succ : successors) { - if (dups.contains(succ)) { - fail("can not assert successors with duplicate names"); - } - dups.add(succ); - } - - Map<String, CfgNode> successorMap = new HashMap<>(); - for (CfgNode successor : node.successors()) { - successorMap.put(successor.toString(), successor); - } - - CfgNode[] result = new CfgNode[successors.length]; - for (int i = 0; i < successors.length; ++i) { - result[i] = successorMap.get(successors[i]); - } - return result; - } - - /** Convert a collection of CfgNodes to a collection of of the node names. */ - private static Collection<String> cfgNames(Iterable<? extends CfgNode> cfgs) { - // Use a linked list because we need to preserve duplicate names. - // TODO(joqvist): Use Java 8 stream api to map CfgNode -> String. - Collection<String> names = new LinkedList<>(); - for (CfgNode cfg : cfgs) { - names.add(cfg.toString()); - } - return names; - } - - @Test public void ifStmt01() { - CfgNode entry = parseCfg("IfStmt01"); - CfgNode call1 = succ(entry, "call1()"); - CfgNode branch = succ(call1, "if (call1())"); - CfgNode[] targets = succ(branch, "onTrue()", "exit"); - CfgNode thenEnd = succ(targets[0], "then-end"); - assertThat(succ(thenEnd, "exit")).isSameAs(targets[1]); - } - - @Test public void ifStmt02() { - CfgNode entry = parseCfg("IfStmt02"); - CfgNode call1 = succ(entry, "call1()"); - CfgNode branch = succ(call1, "if (call1())"); - CfgNode[] targets = succ(branch, "onTrue()", "onFalse()"); - CfgNode thenEnd = succ(targets[0], "then-end"); - CfgNode elseEnd = succ(targets[1], "else-end"); - assertThat(succ(thenEnd, "exit")).isSameAs(succ(elseEnd, "exit")); - } - - @Test public void ifStmt03() { - CfgNode entry = parseCfg("IfStmt03"); - CfgNode call1 = succ(entry, "call1()"); - CfgNode branch = succ(call1, "if (call1())"); - CfgNode[] targets = succ(branch, "onTrue()", "onFalse()"); - succ(succ(targets[0], "then-end"), "exit"); - succ(targets[1], "call2()"); - } - - @Test public void ifStmt04() { - CfgNode entry = parseCfg("IfStmt04"); - CfgNode call1 = succ(entry, "call1()"); - CfgNode branch = succ(call1, "if (call1())"); - CfgNode[] targets = succ(branch, "onTrue()", "onFalse()"); - succ(targets[0], "call2()"); - succ(succ(targets[1], "else-end"), "exit"); - } - - @Test public void forStmt01() { - CfgNode entry = parseCfg("ForStmt01"); - CfgNode call1 = succ(entry, "call1()"); - CfgNode branch = succ(call1, "for (call1())"); - CfgNode[] targets = succ(branch, "for-end", "exit"); - assertThat(succ(targets[0], "call1()")).isSameAs(call1); - } - - @Test public void forStmt02() { - CfgNode entry = parseCfg("ForStmt02"); - CfgNode call1 = succ(entry, "call1()"); - CfgNode branch = succ(call1, "for (call1())"); - CfgNode[] targets = succ(branch, "call2()", "exit"); - CfgNode forEnd = succ(targets[0], "for-end"); - assertThat(succ(forEnd, "call1()")).isSameAs(call1); - } - - @Test public void forStmt03() { - CfgNode entry = parseCfg("ForStmt03"); - CfgNode init = succ(entry, "init()"); - CfgNode cond = succ(init, "cond()"); - CfgNode branch = succ(cond, "for (cond())"); - CfgNode[] targets = succ(branch, "stmt()", "exit"); - CfgNode stmt = targets[0]; - CfgNode forEnd = succ(stmt, "for-end"); - CfgNode update = succ(forEnd, "update()"); - assertThat(succ(update, "cond()")).isSameAs(cond); - } - - @Test public void forStmt04() { - CfgNode entry = parseCfg("ForStmt04"); - CfgNode i = succ(entry, "i()"); - CfgNode j = succ(i, "j()"); - CfgNode cond = succ(j, "cond()"); - CfgNode branch = succ(cond, "for (cond())"); - CfgNode[] targets = succ(branch, "stmt()", "exit"); - CfgNode stmt = targets[0]; - CfgNode forEnd = succ(stmt, "for-end"); - CfgNode u1 = succ(forEnd, "u1()"); - CfgNode u2 = succ(u1, "u2()"); - CfgNode u3 = succ(u2, "u3()"); - assertThat(succ(u3, "cond()")).isSameAs(cond); - } - - @Test public void forStmt05() { - CfgNode entry = parseCfg("ForStmt05"); - CfgNode i = succ(entry, "i()"); - CfgNode branch = succ(i, "for (false)"); - CfgNode y = succ(branch, "y()"); - succ(y, "exit"); - } - - @Test public void whileStmt01() { - CfgNode entry = parseCfg("WhileStmt01"); - CfgNode branch = succ(entry, "while (true)"); - CfgNode whileEnd = succ(branch, "while-end"); - assertThat(succ(whileEnd, "while (true)")).isSameAs(branch); - } - - @Test public void whileStmt02() { - CfgNode entry = parseCfg("WhileStmt02"); - CfgNode cond = succ(entry, "cond()"); - CfgNode branch = succ(cond, "while (cond())"); - CfgNode[] targets = succ(branch, "while-end", "exit"); - assertThat(succ(targets[0], "cond()")).isSameAs(cond); - } - - @Test public void whileStmt03() { - CfgNode entry = parseCfg("WhileStmt03"); - CfgNode whileBranch = succ(entry, "while (true)"); - CfgNode cond = succ(whileBranch, "cond()"); - CfgNode ifBranch = succ(cond, "if (cond())"); - CfgNode[] whileSucc = succ(ifBranch, "while-end", "break"); - assertThat(succ(whileSucc[0], "while (true)")).isSameAs(whileBranch); - succ(succ(whileSucc[1], "tail()"), "exit"); - } - - @Test public void whileStmt04() { - CfgNode entry = parseCfg("WhileStmt04"); - CfgNode whileBranch = succ(entry, "while (true)"); - CfgNode cond = succ(whileBranch, "cond()"); - CfgNode ifBranch = succ(cond, "if (cond())"); - CfgNode[] ifSucc = succ(ifBranch, "continue", "x()"); - assertThat(succ(ifSucc[0], "while (true)")).isSameAs(whileBranch); - CfgNode y = succ(succ(ifSucc[1], "break"), "y()"); - succ(y, "exit"); - } - - @Test public void whileStmt05() { - CfgNode entry = parseCfg("WhileStmt05"); - CfgNode branch = succ(entry, "while (false)"); - CfgNode y = succ(branch, "y()"); - succ(y, "exit"); - } - - @Test public void doStmt01() { - CfgNode entry = parseCfg("DoStmt01"); - CfgNode doEntry = succ(entry, "do-entry"); - CfgNode x = succ(doEntry, "x()"); - CfgNode y = succ(x, "y()"); - CfgNode branch = succ(y, "do_while (y())"); - CfgNode[] targets = succ(branch, "z()", "do-entry"); - succ(targets[0], "exit"); - assertThat(succ(targets[1], "x()")).isSameAs(x); - } - - @Test public void doStmt02() { - CfgNode entry = parseCfg("DoStmt02"); - CfgNode doEntry = succ(entry, "do-entry"); - CfgNode x = succ(doEntry, "x()"); - CfgNode branch = succ(x, "do_while (false)"); - CfgNode y = succ(branch, "y()"); - succ(y, "exit"); - } - - @Test public void enhancedFor01() { - CfgNode entry = parseCfg("EnhancedFor01"); - CfgNode aList = succ(entry, "aList()"); - CfgNode branch = succ(aList, "for (int a : aList())"); - CfgNode[] targets = succ(branch, "x()", "exit"); - CfgNode forEnd = succ(targets[0], "for-end"); - assertThat(succ(forEnd, "aList()")).isSameAs(aList); - } - - @Test public void methodAccess01() { - CfgNode entry = parseCfg("MethodAccess01"); - CfgNode p1 = succ(entry, "p1()"); - CfgNode p2 = succ(p1, "p2()"); - CfgNode p3 = succ(p2, "p3()"); - CfgNode x = succ(p3, "x()"); - succ(x, "exit"); - } - - @Test public void conditionalExpr01() { - CfgNode entry = parseCfg("ConditionalExpr01"); - CfgNode x = succ(entry, "x()"); - CfgNode branch = succ(x, "if (x())"); - CfgNode[] targets = succ(branch, "y()", "z()"); - CfgNode thenEnd = succ(targets[0], "then-end"); - CfgNode elseEnd = succ(targets[1], "else-end"); - // Assert that the branches converge on exit. - assertThat(succ(thenEnd, "exit")).isSameAs(succ(elseEnd, "exit")); - } - - @Test public void switchStmt01() { - CfgNode entry = parseCfg("SwitchStmt01"); - CfgNode expr = succ(entry, "expr()"); - CfgNode branch = succ(expr, "switch (expr())"); - CfgNode[] targets = succ(branch, "x()", "y()", "z()", "d()"); - assertThat(succ(targets[0], "y()")).isSameAs(targets[1]); - CfgNode exit = succ(succ(targets[1], "break"), "exit"); - assertThat(succ(targets[2], "d()")).isSameAs(targets[3]); - assertThat(succ(targets[3], "exit")).isSameAs(exit); - } - - @Test public void switchStmt02() { - CfgNode entry = parseCfg("SwitchStmt02"); - CfgNode expr = succ(entry, "expr()"); - CfgNode branch = succ(expr, "switch (expr())"); - CfgNode[] targets = succ(branch, "x()", "y()", "z()", "exit"); - assertThat(succ(targets[0], "y()")).isSameAs(targets[1]); - assertThat(succ(succ(targets[1], "break"), "exit")).isSameAs(targets[3]); - assertThat(succ(targets[2], "exit")).isSameAs(targets[3]); - } - - @Test public void tryStmt01() { - CfgNode entry = parseCfg("TryStmt01"); - CfgNode tryBranch = succ(entry, "try"); - CfgNode[] trySucc = succ(tryBranch, "cond()", "x()"); - CfgNode[] condSucc = succ(trySucc[0], "exception", "if (cond())"); - CfgNode x = succ(condSucc[0], "x()"); - assertThat(x).isSameAs(trySucc[1]); - CfgNode exit = succ(succ(x, "exception"), "exit"); - CfgNode[] ifSucc = succ(condSucc[1], "a()", "return"); - CfgNode[] aSucc = succ(ifSucc[0], "exception", "x()"); - assertThat(succ(aSucc[0], "x()")).isSameAs(x); - assertThat(aSucc[1]).isNotSameAs(x); - assertThat(succ(succ(aSucc[1], "y()"), "exit")).isSameAs(exit); - CfgNode x2 = succ(ifSucc[1], "x()"); - assertThat(x2).isNotSameAs(x); - assertThat(succ(x2, "exit")).isSameAs(exit); - } - - @Test public void tryStmt02() { - CfgNode entry = parseCfg("TryStmt02"); - CfgNode tryBranch = succ(entry, "try"); - CfgNode[] tryTargets = succ(tryBranch, "c1()", "c2()", "exit"); - assertThat(succ(tryTargets[0], "exit")).isSameAs(tryTargets[2]); - assertThat(succ(tryTargets[1], "exit")).isSameAs(tryTargets[2]); - } - - @Test public void tryStmt03() { - CfgNode entry = parseCfg("TryStmt03"); - CfgNode tryEntry = succ(entry, "try"); - CfgNode[] targets = succ(tryEntry, "if (condition)", "x()"); - - CfgNode exception = succ(targets[1], "exception"); - CfgNode exit = succ(exception, "exit"); - - CfgNode[] ifSucc = succ(targets[0], "return", "x()"); - assertThat(succ(succ(ifSucc[0], "x()"), "exit")).isSameAs(exit); - assertThat(succ(succ(ifSucc[1], "y()"), "exit")).isSameAs(exit); - } - - @Test public void filtering01() { - CfgNode entry = parseCfg("Filtering01"); - CfgNode i = succ(entry, "i()"); - CfgNode j = succ(i, "j()"); - CfgNode cond = succ(j, "cond()"); - CfgNode forBranch = succ(cond, "for (cond() && c == 3)"); - CfgNode[] forSucc = succ(forBranch, "stmt()", "return"); - CfgNode stmt = forSucc[0]; - CfgNode u1 = succ(succ(stmt, "for-end"), "u1()"); - CfgNode u2 = succ(u1, "u2()"); - CfgNode u3 = succ(u2, "u3()"); - assertThat(succ(u3, "cond()")).isSameAs(cond); - } - - @Test public void throwStmt01() { - CfgNode entry = parseCfg("ThrowStmt01"); - CfgNode x = succ(entry, "x()"); - CfgNode exception = succ(x, "exception"); - succ(exception, "exit"); - } - - // Note: tests should be designed so that there is no need to test duplicate - // successors. Simply insert an extra call at the start of one of the - // branches. - - // Generated tests below here. - // Be extra careful when generating a test: you must manually verify that - // it tests the graph correctly and that the generated graph matches your - // expectations. Watch out for nodes that should be identical but appear to - // be separate: in some cases this is okay but it could also indicate faulty - // caching for NTAs. - - @Test public void genTryStmt01() { - CfgNode entry = parseCfg("GenTryStmt01"); - CfgNode tryEntry = succ(entry, "try"); - CfgNode[] targets = succ(tryEntry, "cond()", "c1()", "c2()"); - CfgNode[] targets2 = succ(targets[0], "exception", "if (cond())"); - CfgNode exit = succ(targets[1], "exit"); - assertThat(succ(targets[2], "exit")).isSameAs(exit); - CfgNode[] targets3 = succ(targets2[0], "c1()", "c2()"); - assertThat(targets3[0]).isSameAs(targets[1]); - assertThat(targets3[1]).isSameAs(targets[2]); - CfgNode[] targets4 = succ(targets2[1], "exception", "x()"); - CfgNode[] targets5 = succ(targets4[0], "c1()", "c2()"); - assertThat(targets5[1]).isSameAs(targets[2]); - assertThat(targets5[0]).isSameAs(targets[1]); - CfgNode[] targets6 = succ(targets4[1], "exception", "exit"); - assertThat(targets6[1]).isSameAs(exit); - CfgNode[] targets7 = succ(targets6[0], "c1()", "c2()"); - assertThat(targets7[0]).isSameAs(targets[1]); - assertThat(targets7[1]).isSameAs(targets[2]); - } - - @Test public void genTryStmt02() { - CfgNode entry = parseCfg("GenTryStmt02"); - CfgNode tryEntry = succ(entry, "try"); - CfgNode[] targets = succ(tryEntry, "tryBlock()", "c2()", "c1()"); - CfgNode[] targets2 = succ(targets[0], "exception", "exit"); - assertThat(succ(targets[1], "exit")).isSameAs(targets2[1]); - assertThat(succ(targets[2], "exit")).isSameAs(targets2[1]); - CfgNode[] targets3 = succ(targets2[0], "c2()", "c1()"); - assertThat(targets3[0]).isSameAs(targets[1]); - assertThat(targets3[1]).isSameAs(targets[2]); - } - - @Test public void genTryStmt03() { - CfgNode entry = parseCfg("GenTryStmt03"); - CfgNode tryEntry = succ(entry, "try"); - CfgNode[] targets = succ(tryEntry, "c1()", "x()"); - CfgNode f = succ(targets[0], "f()"); - CfgNode[] targets2 = succ(targets[1], "exception", "f()"); - assertThat(targets2[1]).isSameAs(f); - CfgNode exit = succ(f, "exit"); - assertThat(succ(targets2[0], "c1()")).isSameAs(targets[0]); - } - - - @Test public void genTryStmt04() { - CfgNode entry = parseCfg("GenTryStmt04"); - CfgNode tryEntry = succ(entry, "try"); - CfgNode[] tryEntrySucc = succ(tryEntry, "if (condition)", "x()"); - CfgNode[] ifBranchSucc = succ(tryEntrySucc[0], "a()", "x()"); - CfgNode exception = succ(tryEntrySucc[1], "exception"); - CfgNode[] aSucc = succ(ifBranchSucc[0], "exception", "return"); - CfgNode y = succ(ifBranchSucc[1], "y()"); - CfgNode exit = succ(exception, "exit"); - assertThat(succ(aSucc[0], "x()")).isSameAs(tryEntrySucc[1]); - CfgNode x2 = succ(aSucc[1], "x()"); - assertThat(succ(y, "exit")).isSameAs(exit); - assertThat(succ(x2, "exit")).isSameAs(exit); - } - - @Test public void genTryStmt05() { - CfgNode entry = parseCfg("GenTryStmt05"); - CfgNode tryEntry = succ(entry, "try"); - CfgNode[] tryEntrySucc = succ(tryEntry, "f2()", "try"); - CfgNode exception = succ(tryEntrySucc[0], "exception"); - CfgNode[] tryEntrySucc2 = succ(tryEntrySucc[1], "if (condition)", "f1()"); - CfgNode exit = succ(exception, "exit"); - CfgNode[] ifBranchSucc = succ(tryEntrySucc2[0], "exception", "f1()"); - CfgNode[] f1Succ = succ(tryEntrySucc2[1], "exception", "return"); - assertThat(succ(ifBranchSucc[0], "f1()")).isSameAs(tryEntrySucc2[1]); - CfgNode[] f1Succ2 = succ(ifBranchSucc[1], "exception", "return"); - assertThat(succ(f1Succ[0], "f2()")).isSameAs(tryEntrySucc[0]); - CfgNode f22 = succ(f1Succ[1], "f2()"); - assertThat(succ(f1Succ2[0], "f2()")).isSameAs(tryEntrySucc[0]); - CfgNode f24 = succ(f1Succ2[1], "f2()"); - assertThat(succ(f22, "exit")).isSameAs(exit); - assertThat(succ(f24, "exit")).isSameAs(exit); - } - - @Test public void genTryStmt06() { - CfgNode entry = parseCfg("GenTryStmt06"); - CfgNode tryEntry = succ(entry, "try"); - CfgNode[] tryEntrySucc = succ(tryEntry, "f2()", "try"); - CfgNode exception = succ(tryEntrySucc[0], "exception"); - CfgNode[] tryEntrySucc2 = succ(tryEntrySucc[1], "s()", "f1()"); - CfgNode exit = succ(exception, "exit"); - CfgNode[] sSucc = succ(tryEntrySucc2[0], "exception", "f1()"); - CfgNode[] f1Succ = succ(tryEntrySucc2[1], "exception", "return"); - assertThat(succ(sSucc[0], "f1()")).isSameAs(tryEntrySucc2[1]); - CfgNode[] f1Succ2 = succ(sSucc[1], "exception", "return"); - assertThat(succ(f1Succ[0], "f2()")).isSameAs(tryEntrySucc[0]); - CfgNode f22 = succ(f1Succ[1], "f2()"); - assertThat(succ(f1Succ2[0], "f2()")).isSameAs(tryEntrySucc[0]); - CfgNode f24 = succ(f1Succ2[1], "f2()"); - assertThat(succ(f22, "exit")).isSameAs(exit); - assertThat(succ(f24, "exit")).isSameAs(exit); - } - - @Test public void genTryStmt07() { - CfgNode entry = parseCfg("GenTryStmt07"); - CfgNode tryEntry = succ(entry, "try"); - CfgNode[] tryEntrySucc = succ(tryEntry, "c1()", "x()"); - CfgNode returnMarker = succ(tryEntrySucc[0], "return"); - CfgNode[] xSucc = succ(tryEntrySucc[1], "exception", "f()"); - CfgNode f = succ(returnMarker, "f()"); - assertThat(succ(xSucc[0], "c1()")).isSameAs(tryEntrySucc[0]); - CfgNode y = succ(xSucc[1], "y()"); - CfgNode exit = succ(f, "exit"); - assertThat(succ(y, "exit")).isSameAs(exit); - } - - @Test public void genForStmt01() { - CfgNode entry = parseCfg("GenForStmt01"); - CfgNode forBranch = succ(entry, "for (i < 100)"); - CfgNode[] forBranchSucc = succ(forBranch, "c()", "fin()"); - CfgNode whileBranch = succ(forBranchSucc[0], "while (c())"); - CfgNode exit = succ(forBranchSucc[1], "exit"); - CfgNode[] whileBranchSucc = succ(whileBranch, "if (i >= 40)", "for-end"); - CfgNode[] ifBranchSucc = succ(whileBranchSucc[0], "break", "while-end"); - CfgNode u = succ(whileBranchSucc[1], "u()"); - assertThat(succ(ifBranchSucc[0], "fin()")).isSameAs(forBranchSucc[1]); - assertThat(succ(ifBranchSucc[1], "c()")).isSameAs(forBranchSucc[0]); - assertThat(succ(u, "for (i < 100)")).isSameAs(forBranch); - } - - @Test public void genForStmt02() { - CfgNode entry = parseCfg("GenForStmt02"); - CfgNode forBranch = succ(entry, "for (i < 100)"); - CfgNode[] forBranchSucc = succ(forBranch, "c()", "fin()"); - CfgNode whileBranch = succ(forBranchSucc[0], "while (c())"); - CfgNode exit = succ(forBranchSucc[1], "exit"); - CfgNode[] whileBranchSucc = succ(whileBranch, "if (i >= 40)", "for-end"); - CfgNode[] ifBranchSucc = succ(whileBranchSucc[0], "continue", "while-end"); - CfgNode u = succ(whileBranchSucc[1], "u()"); - assertThat(succ(ifBranchSucc[0], "for (i < 100)")).isSameAs(forBranch); - assertThat(succ(ifBranchSucc[1], "c()")).isSameAs(forBranchSucc[0]); - assertThat(succ(u, "for (i < 100)")).isSameAs(forBranch); - } - - @Test public void genClassInstance01() { - CfgNode entry = parseCfg("GenClassInstance01"); - CfgNode p1 = succ(entry, "p1()"); - CfgNode p2 = succ(p1, "p2()"); - CfgNode p3 = succ(p2, "p3()"); - CfgNode p4 = succ(p3, "p4()"); - CfgNode exit = succ(p4, "exit"); - } - - @Test public void genSwitchStmt01() { - CfgNode entry = parseCfg("GenSwitchStmt01"); - CfgNode whileBranch = succ(entry, "while (x + y == 400 - z)"); - CfgNode[] whileBranchSucc = succ(whileBranch, "switch (x)", "exit"); - CfgNode[] switchBranchSucc = succ(whileBranchSucc[0], "c6()", "c3()", "break", "c5()", "c1()", "c4()", "while-end", "c2()"); - CfgNode breakMarker = succ(switchBranchSucc[0], "break"); - assertThat(succ(switchBranchSucc[1], "c2()")).isSameAs(switchBranchSucc[7]); - assertThat(succ(switchBranchSucc[2], "while-end")).isSameAs(switchBranchSucc[6]); - CfgNode returnMarker = succ(switchBranchSucc[3], "return"); - CfgNode breakMarker2 = succ(switchBranchSucc[4], "break"); - CfgNode breakMarker3 = succ(switchBranchSucc[5], "break"); - assertThat(succ(switchBranchSucc[6], "while (x + y == 400 - z)")).isSameAs(whileBranch); - CfgNode continueMarker = succ(switchBranchSucc[7], "continue"); - assertThat(succ(breakMarker, "while-end")).isSameAs(switchBranchSucc[6]); - assertThat(succ(returnMarker, "exit")).isSameAs(whileBranchSucc[1]); - assertThat(succ(breakMarker2, "while-end")).isSameAs(switchBranchSucc[6]); - assertThat(succ(breakMarker3, "while-end")).isSameAs(switchBranchSucc[6]); - assertThat(succ(continueMarker, "while (x + y == 400 - z)")).isSameAs(whileBranch); - } - - @Test public void genClassInstance02() { - CfgNode entry = parseCfg("GenClassInstance02"); - CfgNode toString = succ(entry, "toString()"); - CfgNode exit = succ(toString, "exit"); - } - - @Test public void genTryWithResources01() { - CfgNode entry = parseCfg("GenTryWithResources01"); - CfgNode openStream = succ(entry, "openStream()"); - CfgNode[] openStreamSucc = succ(openStream, "exception", "try"); - CfgNode[] exceptionSucc = succ(openStreamSucc[0], "c()", "f()"); - CfgNode[] tryEntrySucc = succ(openStreamSucc[1], "c()", "stmt()", "f()"); - assertThat(tryEntrySucc[2]).isSameAs(exceptionSucc[1]); - assertThat(tryEntrySucc[0]).isSameAs(exceptionSucc[0]); - CfgNode f = succ(exceptionSucc[0], "f()"); - CfgNode exception = succ(exceptionSucc[1], "exception"); - CfgNode[] stmtSucc = succ(tryEntrySucc[1], "exception", "f()"); - assertThat(stmtSucc[1]).isSameAs(f); - CfgNode exit = succ(f, "exit"); - assertThat(succ(exception, "exit")).isSameAs(exit); - CfgNode[] exceptionSucc2 = succ(stmtSucc[0], "c()", "f()"); - assertThat(exceptionSucc2[0]).isSameAs(exceptionSucc[0]); - assertThat(exceptionSucc2[1]).isSameAs(exceptionSucc[1]); - } - - @Test public void genTryWithResources02() { - CfgNode entry = parseCfg("GenTryWithResources02"); - CfgNode o1 = succ(entry, "o1()"); - CfgNode[] o1Succ = succ(o1, "exception", "o2()"); - CfgNode[] exceptionSucc = succ(o1Succ[0], "c()", "f()"); - CfgNode[] o2Succ = succ(o1Succ[1], "exception", "try"); - CfgNode f = succ(exceptionSucc[0], "f()"); - CfgNode exception = succ(exceptionSucc[1], "exception"); - CfgNode[] exceptionSucc2 = succ(o2Succ[0], "c()", "f()"); - assertThat(exceptionSucc2[0]).isSameAs(exceptionSucc[0]); - assertThat(exceptionSucc2[1]).isSameAs(exceptionSucc[1]); - CfgNode[] tryEntrySucc = succ(o2Succ[1], "c()", "stmt()", "f()"); - assertThat(tryEntrySucc[2]).isSameAs(exceptionSucc[1]); - assertThat(tryEntrySucc[0]).isSameAs(exceptionSucc[0]); - CfgNode exit = succ(f, "exit"); - assertThat(succ(exception, "exit")).isSameAs(exit); - CfgNode[] stmtSucc = succ(tryEntrySucc[1], "exception", "f()"); - assertThat(stmtSucc[1]).isSameAs(f); - CfgNode[] exceptionSucc3 = succ(stmtSucc[0], "c()", "f()"); - assertThat(exceptionSucc3[1]).isSameAs(exceptionSucc[1]); - assertThat(exceptionSucc3[0]).isSameAs(exceptionSucc[0]); - } - -} diff --git a/simplecfg/src/test/java/org/extendj/ast/IdentityTupleSetTest.java b/simplecfg/src/test/java/org/extendj/ast/IdentityTupleSetTest.java deleted file mode 100644 index 417eeb8d6ce2e13e06e3085279c61871eff478fa..0000000000000000000000000000000000000000 --- a/simplecfg/src/test/java/org/extendj/ast/IdentityTupleSetTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.extendj.ast; - -import static com.google.common.truth.Truth.assertThat; - -import java.util.Set; - -import org.extendj.ast.IdentityTupleSet; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link IdentityTupleSet}. */ -@RunWith(JUnit4.class) -public class IdentityTupleSetTest { - - // Two unique objects used for testing. - private Object a = new Object(); - private Object b = new Object(); - - @Test public void testSize() { - assertThat(new IdentityTupleSet<>(null, null)).hasSize(1); - assertThat(new IdentityTupleSet<>(a, a)).hasSize(1); - assertThat(new IdentityTupleSet<>(a, b)).hasSize(2); - assertThat(new IdentityTupleSet<>(null, b)).hasSize(2); - } - - @Test public void testIsEmpty() { - assertThat(new IdentityTupleSet<>(null, null)).isNotEmpty(); - assertThat(new IdentityTupleSet<>(a, a)).isNotEmpty(); - assertThat(new IdentityTupleSet<>(a, b)).isNotEmpty(); - assertThat(new IdentityTupleSet<>(null, b)).isNotEmpty(); - } - - @Test public void testDuplicateContains() { - assertThat(new IdentityTupleSet<>(null, null)).containsExactly((Object) null); - assertThat(new IdentityTupleSet<>(a, a)).containsExactly(a); - } - - @Test public void testContains() { - assertThat(new IdentityTupleSet<>(a, b)).containsExactly(a, b); - } -} diff --git a/simplecfg/testdata/AlreadyClosedControlFlow01.javax b/simplecfg/testdata/AlreadyClosedControlFlow01.javax deleted file mode 100644 index 2463b37f65b00a7ff3f37d6ea2a606dabb23dee8..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/AlreadyClosedControlFlow01.javax +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real code! This file is parsed by the Java API analyzer tests - * to check that the expected findings are reported for this file. - */ -import java.io.BufferedInputStream; -import java.io.Closeable; -import java.io.FileInputStream; - -/* This code is used to check that the already-closed analysis handles different control flow - * structures appropriately. - */ -class AlreadyClosedControlFlow01 { - void for01(FileInputStream in) { - for (int i = 0; i < 10; ++i) { - in.close(); - } - // The analyzer does not know how many loop iterations are executed, assumes 0+ - // iterations are possible. - in.skip(0); // Positive finding. - } - - void for02() { - for (int i = 0; i < 10; ++i) { - FileInputStream in = new FileInputStream("somefile"); - in.skip(0); - in.close(); // Negative finding: new instance each iteration. - } - } - - void if01() { - Closeable in = new FileInputStream("somefile"); - if (System.currentTimeMillis() & 1 == 0) { - in.read(); - in.close(); - } else { - in.read(); - in.close(); - } - } - - void if02() { - Closeable in = new FileInputStream("somefile"); - in.close(); - if (System.currentTimeMillis() & 1 == 0) { - in.read(); // Positive finding. - } - } - - void if03() { - Closeable in = new FileInputStream("foo"); - in.close(); - // Check that the if condition is analyzed. - if (in.read() == -1) { // Positive finding. - } - } - - void while01() { - Closeable in = new FileInputStream("bar"); - while (true) { - in.read(); - in.close(); - break; - } - in.read(); // Positive finding. - } - - void while02() { - Closeable in = new FileInputStream("bar"); - while (in.read() != -1) { // Positive finding. - in.close(); - } - } - - void try01(BufferedInputStream in) { - try { - in.close(); - } catch (Throwable t) { - in.read(); // Negative finding: preceding close call interrupted by exception. - } - } - - void try02(BufferedInputStream in) { - try { - in.close(); - } catch (Throwable t) { - in.read(); - } finally { - in.read(); // Positive finding: can be reached after an uninterrupted close call. - } - } - - void switch01(BufferedInputStream in, int i) { - switch (i) { - case 1: - in.close(); - break; - case 2: - in.read(); - break; - case 3: - in.close(); - case 4: - in.read(); // Positive finding. - break; - } - } - - void switch02(BufferedInputStream in, int i) { - switch (i) { - case 1: - in.close(); - break; - case 2: - in.read(); - break; - case 3: - in.close(); - return; - case 4: - in.read(); - default: - in.close(); - } - } -} diff --git a/simplecfg/testdata/AlreadyClosedNegativeFindings01.javax b/simplecfg/testdata/AlreadyClosedNegativeFindings01.javax deleted file mode 100644 index f59ecd19af455d4b9ea08b870f183917199e57bf..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/AlreadyClosedNegativeFindings01.javax +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real code! This file is parsed by the Java API analyzer tests - * to check that no findings are reported for this file. - */ -import java.io.Closeable; -import java.io.FileInputStream; - -/* Negative findings for the already-closed analyzer. */ -class AlreadyClosedNegativeFindings01 { - - static class MyCloseable { - public void close() { - } - public void write() { - } - } - - void f1() { - // MyCloseable does not implement java.io.Closeable, so it should not cause findings. - MyCloseable closeable = new MyCloseable(); - closeable.close(); - closeable.write(); - } - - void f2() { - while (true) { - // This is a new instance each iteration, so close is only called once per instance. - Closeable in = new FileInputStream("x"); - in.read(); - in.close(); - if (System.currentTimeMillis() % 2 == 1) { - break; - } - } - - void f3() { - // This local variable is not effectively final, so it should not be analyzed. - Closeable in = new FileInputStream("x"); - in.read(); - in.close(); - in = new FileInputStream("y"); - in.read(); - } - - void f4() { - // This local variable is not effectively final, so it should not be analyzed. - Closeable in = new FileInputStream("x"); - in.read(); - in.close(); - in = new FileInputStream("y"); - in.read(); - } - - void f5(Closeable in) { - // Repeated calls to close() are allowed and do not produce findings. - in.close(); - in.close(); - in.close(); - in.close(); - in.close(); - } - - String f6(ByteArrayOutputStream out) { - out.close(); - return out.toString(); // Negative finding: calling toString() after close() is okay. - } - - byte[] f7(ByteArrayOutputStream out) { - out.close(); - return out.toByteArray(); // Negative finding: calling toByteArray() after close() is okay. - } -} diff --git a/simplecfg/testdata/AlreadyClosedWriter01.javax b/simplecfg/testdata/AlreadyClosedWriter01.javax deleted file mode 100644 index 2b7769c0f5333ade6ce2d9aafc9482be9225f68a..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/AlreadyClosedWriter01.javax +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real code! This file is parsed by the Java API analyzer tests - * to check that the expected findings are reported for this file. - */ - -/* This code is used to check that the already-closed analyzer can identify java.io.Writer - * as a subtype of java.io.Closeable and report a finding for a simple call after close. - */ -class AlreadyClosedWriter01 { - void f(java.io.Writer writer) { - writer.close(); - writer.flush(); // Finding: Calling flush() after close(). - } -} diff --git a/simplecfg/testdata/Close01.javax b/simplecfg/testdata/Close01.javax deleted file mode 100644 index 025fc45599d3724fbc211d78e48717aa4e191f7c..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/Close01.javax +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -public class Close01 { - void f(java.io.Writer writer) { - writer.close(); - writer.write(new byte[10]); - } -} diff --git a/simplecfg/testdata/ConditionalExpr01.javax b/simplecfg/testdata/ConditionalExpr01.javax deleted file mode 100644 index de8385b6bf9b2144b19711bccb0c8045c0e4cfc5..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/ConditionalExpr01.javax +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class ConditionalExpr01 { - static { - // Conditional expressions work like if statements. - int unused = x() ? y() : z(); - } -} diff --git a/simplecfg/testdata/DoStmt01.javax b/simplecfg/testdata/DoStmt01.javax deleted file mode 100644 index d2a6d832c3a6db205f19b2c0570aa2cb1bc4c5d2..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/DoStmt01.javax +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class DoStmt01 { - { - do { - x(); - } while (y()); - z(); - } -} diff --git a/simplecfg/testdata/DoStmt02.javax b/simplecfg/testdata/DoStmt02.javax deleted file mode 100644 index 2e1fb9eb949f7797c03fd0e385c8a1e83e024bba..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/DoStmt02.javax +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class DoStmt02 { - { - // Test do statement with constant false condition. - do { - x(); - } while (false); - y(); - } -} diff --git a/simplecfg/testdata/EnhancedFor01.javax b/simplecfg/testdata/EnhancedFor01.javax deleted file mode 100644 index f1532b23592ed6f6f6b22fe9dcf641409ca852c7..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/EnhancedFor01.javax +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class EnhancedFor01 { - { - for (int a : aList()) { - x(); - } - } -} diff --git a/simplecfg/testdata/Filtering01.javax b/simplecfg/testdata/Filtering01.javax deleted file mode 100644 index 8f83cee0544b48b338ef50ba730ebc49e405839f..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/Filtering01.javax +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class Filtering01 { - int x(int c) { - // Test that uninteresting expressions are not included in the CFG. - int a = 4; - int b = 3; - for (int i = i(1, 4 * 5), j = j(); cond() && c == 3; u1(), j += c / 2, u2(), u3(), i++) { - stmt(); - a += (--b) * c; - } - return a + b; - } -} diff --git a/simplecfg/testdata/ForStmt01.javax b/simplecfg/testdata/ForStmt01.javax deleted file mode 100644 index ce58d63becab96d0b5fa5fb498817e97854f8518..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/ForStmt01.javax +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class ForStmt01 { - void x() { - for (; call1(); ) { - } - } -} diff --git a/simplecfg/testdata/ForStmt02.javax b/simplecfg/testdata/ForStmt02.javax deleted file mode 100644 index f204489cd686042e0bacffe8b5368af12ff207f9..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/ForStmt02.javax +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class ForStmt02 { - void x() { - for (; call1(); ) { - call2(); - } - } -} diff --git a/simplecfg/testdata/ForStmt03.javax b/simplecfg/testdata/ForStmt03.javax deleted file mode 100644 index 720fefd193cc581a23ac7aa8c3f0b794d2c82701..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/ForStmt03.javax +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class ForStmt03 { - void x() { - for (int i = init(); cond(); update()) - stmt(); - } -} diff --git a/simplecfg/testdata/ForStmt04.javax b/simplecfg/testdata/ForStmt04.javax deleted file mode 100644 index 29b036334033967540d8c8a3f71b078b8238d22e..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/ForStmt04.javax +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class ForStmt04 { - { - // Initializer expressions and update statements are evaluated in the order they are listed. - for (int i = i(), j = j(); cond(); u1(), u2(), u3()) { - stmt(); - } - } -} diff --git a/simplecfg/testdata/ForStmt05.javax b/simplecfg/testdata/ForStmt05.javax deleted file mode 100644 index 7cea144800964ac35735329cc6f0803023cb30b0..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/ForStmt05.javax +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class ForStmt05 { - { - // Test for statement with constant false condition. - for (Object o = i(); false; u()) { - x(); - } - y(); - } -} diff --git a/simplecfg/testdata/GenClassInstance01.javax b/simplecfg/testdata/GenClassInstance01.javax deleted file mode 100644 index 26e7baeeee6582ca92fddd82f3272e65b823c3dd..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenClassInstance01.javax +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenClassInstance01 { - GenClassInstance01() { - new C(p1(), p2(), new D(p3() + p4())); - } -} diff --git a/simplecfg/testdata/GenClassInstance02.javax b/simplecfg/testdata/GenClassInstance02.javax deleted file mode 100644 index a73a972e46c5ae098041f3528a701e7d54302d6e..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenClassInstance02.javax +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenClassInstance02 { - { - new Object() { - void f() { - notInParentCfg(); - } - }.toString(); - } -} diff --git a/simplecfg/testdata/GenForStmt01.javax b/simplecfg/testdata/GenForStmt01.javax deleted file mode 100644 index a1dab9ad9e9689d31297dde0950bfcb22ee48c09..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenForStmt01.javax +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenForStmt01 { - { - // Test a labeled break. - loop1: - for (int i = 3 * x; i < 100; ++i, u()) { - while (c()) { - if (i >= 40) { - break loop1; - } - } - } - fin(); - } -} diff --git a/simplecfg/testdata/GenForStmt02.javax b/simplecfg/testdata/GenForStmt02.javax deleted file mode 100644 index 23535baf67376b1a0d3ee5e7d69f5a906575dfa8..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenForStmt02.javax +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenForStmt02 { - { - // Test a labeled continue. - loop1: - for (int i = 3 * x; i < 100; ++i, u()) { - while (c()) { - if (i >= 40) { - continue loop1; - } - } - } - fin(); - } -} diff --git a/simplecfg/testdata/GenSwitchStmt01.javax b/simplecfg/testdata/GenSwitchStmt01.javax deleted file mode 100644 index 1ef81a62a8217e678e0dec43256448b5d44a0492..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenSwitchStmt01.javax +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenSwitchStmt01 { - GenSwitchStmt01() { - while (x + y == 400 - z) { - switch (x) { - case -1: - c1(); - break; - case 1: - break; - case 3: - c3(); - case 2: - c2(); - continue; - case 4: - c4(); - break; - case 5: - c5(); - return; - case 6: - c6(); - break; - } - } - } -} diff --git a/simplecfg/testdata/GenTryStmt01.javax b/simplecfg/testdata/GenTryStmt01.javax deleted file mode 100644 index 63975d3b5f46a503bbe353af2216a20e3f19de7e..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenTryStmt01.javax +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenTryStmt01 { - void f(Exception exception) { - // Test that branches from throw statement go to both all catch clauses. - try { - if (cond()) { - throw exception; - } - x(); - } catch (Exception1 e) { - c1(); - } catch (Exception2 e) { - c2(); - } - } -} diff --git a/simplecfg/testdata/GenTryStmt02.javax b/simplecfg/testdata/GenTryStmt02.javax deleted file mode 100644 index 3fb2f476c9c7917d1f5108a02bb4bf9c0804b9ee..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenTryStmt02.javax +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenTryStmt02 { - { - try { - tryBlock(); - } catch (Exception unused) { - c1(); - } catch (Throwable unused) { - c2(); - } - } -} diff --git a/simplecfg/testdata/GenTryStmt03.javax b/simplecfg/testdata/GenTryStmt03.javax deleted file mode 100644 index 3d0cf1fb671fb71b91f1c107f1f8446246b4eca5..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenTryStmt03.javax +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenTryStmt03 { - { - try { - x(); - } catch (Throwable unused) { - c1(); - } catch (Exception unused) { - // Never reached. - c2(); - } finally { - f(); - } - } -} diff --git a/simplecfg/testdata/GenTryStmt04.javax b/simplecfg/testdata/GenTryStmt04.javax deleted file mode 100644 index 66f3e7d2f0b4adbdfff36d17505d6526008a939c..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenTryStmt04.javax +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenTryStmt04 { - void m() { - // Test that finally handlers are generated in separate CFG branches. - // Non-identical CFG nodes with the same name are expected in this graph. - try { - if (condition) { - a(); - return; - } - } finally { - x(); - } - y(); - } -} diff --git a/simplecfg/testdata/GenTryStmt05.javax b/simplecfg/testdata/GenTryStmt05.javax deleted file mode 100644 index 2d4d5540093ede8bcf6134e59af27a6f03337156..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenTryStmt05.javax +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenTryStmt05 { - void z() { - try { - try { - if (condition) throw exception; - } finally { - f1(); - return; - } - a(); - } finally { - f2(); - } - b(); - } -} diff --git a/simplecfg/testdata/GenTryStmt06.javax b/simplecfg/testdata/GenTryStmt06.javax deleted file mode 100644 index 8af1b8308cc75a258ccbaa322c3caff67503c125..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenTryStmt06.javax +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenTryStmt06 { - { - // Abrupt exit from nested finally block. - try { - try { - s(); - } finally { - f1(); - return; - } - } finally { - f2(); - } - } -} diff --git a/simplecfg/testdata/GenTryStmt07.javax b/simplecfg/testdata/GenTryStmt07.javax deleted file mode 100644 index 02a27a98cd8c99ea6770bf94a8ba9caf0f028da7..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenTryStmt07.javax +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenTryStmt07 { - { - try { - x(); - } catch (Throwable unused) { - c1(); - return; - } catch (Exception unused) { - // Never reached. - c2(); - } finally { - f(); - } - y(); - } -} diff --git a/simplecfg/testdata/GenTryWithResources01.javax b/simplecfg/testdata/GenTryWithResources01.javax deleted file mode 100644 index c0c5c43ce8718e34c2d2ec33db5311797808c2e1..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenTryWithResources01.javax +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenTryWithResources01 { - { - try (AutoCloseable stream = openStream()) { - stmt(); - } catch (IOException e) { - c(); - } finally { - f(); - } - } -} diff --git a/simplecfg/testdata/GenTryWithResources02.javax b/simplecfg/testdata/GenTryWithResources02.javax deleted file mode 100644 index d814c2492e69522ae548e8db8876f9369121cea3..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/GenTryWithResources02.javax +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class GenTryWithResources02 { - { - try (AutoCloseable s1 = o1(); - AutoCloseable s2 = o2()) { - stmt(); - } catch (IOException e) { - c(); - } finally { - f(); - } - } -} diff --git a/simplecfg/testdata/IfStmt01.javax b/simplecfg/testdata/IfStmt01.javax deleted file mode 100644 index ef8dd0bfcd8a7c3c4611ac212626d94b1345c160..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/IfStmt01.javax +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class IfStmt01 { - void f() { - if (call1()) { - onTrue(); - } - } -} diff --git a/simplecfg/testdata/IfStmt02.javax b/simplecfg/testdata/IfStmt02.javax deleted file mode 100644 index 0271e6843c7bb0b95fcf8cc0dfc4597ea014114c..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/IfStmt02.javax +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class IfStmt02 { - void f() { - if (call1()) { - onTrue(); - } else { - onFalse(); - } - } -} diff --git a/simplecfg/testdata/IfStmt03.javax b/simplecfg/testdata/IfStmt03.javax deleted file mode 100644 index e515c9cdc0878e4acf7e9fbf7f846fed49027732..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/IfStmt03.javax +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class IfStmt03 { - void f() { - if (call1()) { - onTrue(); - } else { - onFalse(); - call2(); - } - } -} diff --git a/simplecfg/testdata/IfStmt04.javax b/simplecfg/testdata/IfStmt04.javax deleted file mode 100644 index 19c6c45ce5e5722e4e966e0a7c0c457d583fcb20..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/IfStmt04.javax +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class IfStmt04 { - void f() { - if (call1()) { - onTrue(); - call2(); - } else { - onFalse(); - } - } -} diff --git a/simplecfg/testdata/MethodAccess01.javax b/simplecfg/testdata/MethodAccess01.javax deleted file mode 100644 index dad7cc795334f280e67c969422fda0e5a13daddd..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/MethodAccess01.javax +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class MethodAccess01 { - void f() { - // Parameters are evaluated before the outer method call. - x(p1(), p2(), p3()); - } -} diff --git a/simplecfg/testdata/NullableDataflow01.javax b/simplecfg/testdata/NullableDataflow01.javax deleted file mode 100644 index 41013edcba70b58bdc5b2ad9e0b6d822ef1aa397..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableDataflow01.javax +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - */ -import javax.annotation.Nullable; - -public class NullableDataflow01 { - boolean x = false; - - void fp1(@Nullable String p) { - boolean var = p == null; - if (!var) { - p.hashCode(); // False positive: condition variable not effectively final. - } - var = false; - } - - void fp2(@Nullable String p) { - boolean var = p != null; - if (var) { - p.hashCode(); // False positive: condition variable not effectively final. - } - var = false; - } - - void n1(@Nullable String p) { - boolean var = p == null; - if (!var) { - p.hashCode(); // Negative. - } - } - - void n2(@Nullable String p) { - boolean var = p != null; - if (var) { - p.hashCode(); // Negative. - } - } -} diff --git a/simplecfg/testdata/NullableDereference01.javax b/simplecfg/testdata/NullableDereference01.javax deleted file mode 100644 index e9b01b97c546e496ea3b971801364c424c5a889d..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableDereference01.javax +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -import javax.annotation.Nullable; - -/** - * Test some simple positive findings for the Nullable Dereference analyzer. - */ -class NullableDereference01 { - int p1(@Nullable String[] p) { - return p.length; - } - - String p2(@Nullable String[] p) { - return p[0]; - } - - int fn3(@Nullable String[] p) { - return p[0].size(); // False negative. - } -} diff --git a/simplecfg/testdata/NullableDereferenceEqExpr.javax b/simplecfg/testdata/NullableDereferenceEqExpr.javax deleted file mode 100644 index 95adffa692f4fe7e0cca4ac84e3c4829643659e2..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableDereferenceEqExpr.javax +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import javax.annotation.Nullable; - -/** - * This is test data, not real source code! - * This contains tests for EQExpr null guards. Each test method contains - * one false positive dereference of the parameter p. The parameter is - * guarded by a null check in an equality expression. - */ -public class NullableDereferenceEqExpr { - /** - * Non-null when true condition. - * Null test in left hand side, comparing to false. - */ - int nntLhsFalse(@Nullable String p) { - if (false == (p == null)) { - return p.size(); - } - return 0; - } - - /** - * Non-null when true condition. - * Null test in right hand side, comparing to false. - */ - int nntRhsFalse(@Nullable String p) { - if ((p == null) == false) { - return p.size(); - } - return 0; - } - - /** - * Non-null when true condition. - * Null test in left hand side, comparing to true. - */ - int nntLhsTrue(@Nullable String p) { - if (true == (p != null)) { - return p.size(); - } - return 0; - } - - /** - * Non-null when true condition. - * Null test in right hand side, comparing to true. - */ - int nntRhsTrue(@Nullable String p) { - if ((p != null) == true) { - return p.size(); - } - return 0; - } - - /** - * Non-null when false condition. - * Null test in left hand side, comparing to false. - */ - int nnfLhsFalse(@Nullable String p) { - if (false == (p != null)) { - return 0; - } - return p.size(); - } - - /** - * Non-null when false condition. - * Null test in right hand side, comparing to false. - */ - int nnfRhsFalse(@Nullable String p) { - if ((p != null) == false) { - return 0; - } - return p.size(); - } - - /** - * Non-null when false condition. - * Null test in left hand side, comparing to true. - */ - int nnfLhsTrue(@Nullable String p) { - if (true == (p == null)) { - return 0; - } - return p.size(); - } - - /** - * Non-null when false condition. - * Null test in right hand side, comparing to true. - */ - int nnfRhsTrue(@Nullable String p) { - if ((p == null) == true) { - return 0; - } - return p.size(); - } - - /** - * Null when true condition (negated). - * Null test in left hand side, comparing to false. - */ - int ntLhsFalse(@Nullable String p) { - if (!(false == (p != null))) { - return p.size(); - } - return 0; - } - - /** - * Null when true condition (negated). - * Null test in right hand side, comparing to false. - */ - int ntRhsFalse(@Nullable String p) { - if (!((p != null) == false)) { - return p.size(); - } - return 0; - } - - /** - * Null when true condition (negated). - * Null test in left hand side, comparing to true. - */ - int ntLhsTrue(@Nullable String p) { - if (!(true == (p == null))) { - return p.size(); - } - return 0; - } - - /** - * Null when true condition (negated). - * Null test in right hand side, comparing to true. - */ - int ntRhsTrue(@Nullable String p) { - if (!((p == null) == true)) { - return p.size(); - } - return 0; - } - - /** - * Null when false condition (negated). - * Null test in left hand side, comparing to false. - */ - int nfLhsFalse(@Nullable String p) { - if (!(false == (p == null))) { - return 0; - } - return p.size(); - } - - /** - * Null when false condition (negated). - * Null test in right hand side, comparing to false. - */ - int nfRhsFalse(@Nullable String p) { - if (!((p == null) == false)) { - return 0; - } - return p.size(); - } - - /** - * Null when false condition (negated). - * Null test in left hand side, comparing to true. - */ - int nfLhsTrue(@Nullable String p) { - if (!(true == (p != null))) { - return 0; - } - return p.size(); - } - - /** - * Null when false condition (negated). - * Null test in right hand side, comparing to true. - */ - int nfRhsTrue(@Nullable String p) { - if (!((p != null) == true)) { - return 0; - } - return p.size(); - } -} diff --git a/simplecfg/testdata/NullableDereferenceIssue10.javax b/simplecfg/testdata/NullableDereferenceIssue10.javax deleted file mode 100644 index cd5e584fe48031543be7eff1b0d730e9a7571472..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableDereferenceIssue10.javax +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* This is test data, not real source code! */ -import javax.annotation.Nullable; - -/** - * Test a false positive finding from GitHub issue #10 - * (https://github.com/google/simplecfg/issues/10). - */ -class NullableDereferenceIssue10 { - static class A { - public void m() { - } - } - - void fp1(@Nullable A x, @Nullable A y) { - if (x == null && y == null) { - return; - } - // If x is null then y is not null. - z = (x != null) ? x.m() : y.m(); // False positive for y.m(). - } -} diff --git a/simplecfg/testdata/NullableDereferenceIssue11.javax b/simplecfg/testdata/NullableDereferenceIssue11.javax deleted file mode 100644 index fb1fdaa8c6f7e51aa8b1c58efe37cc2df02df959..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableDereferenceIssue11.javax +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import javax.annotation.Nullable; - -/** - * This is test data, not real source code! - * Test for GitHub issue #11 (https://github.com/google/simplecfg/issues/11). - */ -public class Issue11 { - /** Test nullable deref in true-part of conditional expression. */ - int test(@Nullable String p, boolean maybe) { - if (p == null || (maybe ? p.size() != 1 : false)) { // Negative finding. - return 1; - } - return 2; - } - - /** Test nullable deref in false-part of conditional expression. */ - int test2(@Nullable String p, boolean maybe) { - if (p == null || (maybe ? false : p.size() != 1)) { // Negative finding. - return 1; - } - return 2; - } - - /** Test that the same null-guard used above works outside of conditional expression. */ - int test3(@Nullable String p) { - if (p == null || p.size() != 1) { // Negative finding. - return 1; - } - return 2; - } -} diff --git a/simplecfg/testdata/NullableDereferenceIssue12.javax b/simplecfg/testdata/NullableDereferenceIssue12.javax deleted file mode 100644 index 95ca23534a6c6aa81c31d6f822230aff6d21cd20..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableDereferenceIssue12.javax +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import javax.annotation.Nullable; - -/** - * This is test data, not real source code! - * Test for GitHub issue #12 (https://github.com/google/simplecfg/issues/12). - */ -public class NullableDereferenceIssue12 { - /** - * The condition (false == x) is equivalent to (!x), however this test - * shows a bug causing a null guard check to fail for (false == x) - * expressions. - */ - int test(@Nullable String p) { - if (false == (p != null)) { - return 0; - } - return p.size(); // Negative finding: not reachable if p == null. - } - - /** - * The condition in this if-statement and the one in the first test are - * equivalent but this version does not give a false positive. - */ - int test2(@Nullable String p) { - if (!(p != null)) { - return 0; - } - return p.size(); // Negative finding. - } -} diff --git a/simplecfg/testdata/NullableDereferenceIssue13.javax b/simplecfg/testdata/NullableDereferenceIssue13.javax deleted file mode 100644 index 27a28b932568fc5a83788ad1c451866b06e55fa2..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableDereferenceIssue13.javax +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import javax.annotation.Nullable; - -/** - * This is test data, not real source code! - * Test for GitHub issue #13 (https://github.com/google/simplecfg/issues/13). - */ -public class NullableDereferenceIssue13 { - protected final Object obj; - - public NullableDereferenceIssue13(@Nullable Object obj) { - this.obj = obj; - - // Calling test() is equivalent to checking obj != null, - // however, the current NullableDereference implementation - // can not handle this case, even though test() is declared - // inside the same class. - if (test()) { - obj.hashCode(); // False positive finding generated here. - } - } - - private boolean test() { - return obj != null; - } -} diff --git a/simplecfg/testdata/NullableDereferenceMethodCall.javax b/simplecfg/testdata/NullableDereferenceMethodCall.javax deleted file mode 100644 index c2bcf2093c49be3c57d09751597d66b5a0ba68a2..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableDereferenceMethodCall.javax +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import javax.annotation.Nullable; - -/** - * This is test data, not real source code! - * - * <p>This class contains tests checking that a null dereference - * finding is not reported for a parameter p after p has been used - * as an argument in a method call. The NullableDereference - * analyzer is not an interprocedural analysis, so we can not know - * if the method called will perform a null check and ensure - * non-nullness of the argument after the call completes. Instead - * we should just stop analyzing a parameter after it has been - * passed to another method. - */ -public class NullableDereferenceMethodCall { - public interface SomeApi { - public void doSomething(String str); - } - - int interfaceMethodCall(@Nullable String p, SomeApi s) { - s.doSomething(p); - return p.size(); // No finding here, since doSomething might have done a null check. - } - - int interfaceMethodCall2(@Nullable String p, SomeApi s) { - int size = p.size(); // Finding here: no call yet. - s.doSomething(p); - return size; - } - - int methodCall(@Nullable String p, String q) { - q.equals(p); - return p.size(); - } - - int localMethodCall(@Nullable String p) { - localMethod(p); - return p.size(); // No finding here, we don't analyze even local methods. - } -} diff --git a/simplecfg/testdata/NullableDereferenceNeExpr.javax b/simplecfg/testdata/NullableDereferenceNeExpr.javax deleted file mode 100644 index f70f138138b976faeb9e2b5ba40c0802712408e0..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableDereferenceNeExpr.javax +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import javax.annotation.Nullable; - -/** - * This is test data, not real source code! - * This contains tests for NEExpr null guards. Each test method contains - * one false positive dereference of the parameter p. The parameter is - * guarded by a null check in an inequality expression. - */ -public class NullableDereferenceNeExpr { - /** - * Non-null when true condition. - * Null test in left hand side, comparing to false. - */ - int nntLhsFalse(@Nullable String p) { - if (false != (p != null)) { - return p.size(); - } - return 0; - } - - /** - * Non-null when true condition. - * Null test in right hand side, comparing to false. - */ - int nntRhsFalse(@Nullable String p) { - if ((p != null) != false) { - return p.size(); - } - return 0; - } - - /** - * Non-null when true condition. - * Null test in left hand side, comparing to true. - */ - int nntLhsTrue(@Nullable String p) { - if (true != (p == null)) { - return p.size(); - } - return 0; - } - - /** - * Non-null when true condition. - * Null test in right hand side, comparing to true. - */ - int nntRhsTrue(@Nullable String p) { - if ((p == null) != true) { - return p.size(); - } - return 0; - } - - /** - * Non-null when false condition. - * Null test in left hand side, comparing to false. - */ - int nnfLhsFalse(@Nullable String p) { - if (false != (p == null)) { - return 0; - } - return p.size(); - } - - /** - * Non-null when false condition. - * Null test in right hand side, comparing to false. - */ - int nnfRhsFalse(@Nullable String p) { - if ((p == null) != false) { - return 0; - } - return p.size(); - } - - /** - * Non-null when false condition. - * Null test in left hand side, comparing to true. - */ - int nnfLhsTrue(@Nullable String p) { - if (true != (p != null)) { - return 0; - } - return p.size(); - } - - /** - * Non-null when false condition. - * Null test in right hand side, comparing to true. - */ - int nnfRhsTrue(@Nullable String p) { - if ((p != null) != true) { - return 0; - } - return p.size(); - } - - /** - * Null when true condition (negated). - * Null test in left hand side, comparing to false. - */ - int ntLhsFalse(@Nullable String p) { - if (!(false != (p == null))) { - return p.size(); - } - return 0; - } - - /** - * Null when true condition (negated). - * Null test in right hand side, comparing to false. - */ - int ntRhsFalse(@Nullable String p) { - if (!((p == null) != false)) { - return p.size(); - } - return 0; - } - - /** - * Null when true condition (negated). - * Null test in left hand side, comparing to true. - */ - int ntLhsTrue(@Nullable String p) { - if (!(true != (p != null))) { - return p.size(); - } - return 0; - } - - /** - * Null when true condition (negated). - * Null test in right hand side, comparing to true. - */ - int ntRhsTrue(@Nullable String p) { - if (!((p != null) != true)) { - return p.size(); - } - return 0; - } - - /** - * Null when false condition (negated). - * Null test in left hand side, comparing to false. - */ - int nfLhsFalse(@Nullable String p) { - if (!(false != (p != null))) { - return 0; - } - return p.size(); - } - - /** - * Null when false condition (negated). - * Null test in right hand side, comparing to false. - */ - int nfRhsFalse(@Nullable String p) { - if (!((p != null) != false)) { - return 0; - } - return p.size(); - } - - /** - * Null when false condition (negated). - * Null test in left hand side, comparing to true. - */ - int nfLhsTrue(@Nullable String p) { - if (!(true != (p == null))) { - return 0; - } - return p.size(); - } - - /** - * Null when false condition (negated). - * Null test in right hand side, comparing to true. - */ - int nfRhsTrue(@Nullable String p) { - if (!((p == null) != true)) { - return 0; - } - return p.size(); - } -} diff --git a/simplecfg/testdata/NullableInstanceOf.javax b/simplecfg/testdata/NullableInstanceOf.javax deleted file mode 100644 index de6c0691c31ce276ab1a060fce4c333760dbf8ba..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableInstanceOf.javax +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -import javax.annotation.Nullable; - -/** - * Using instanceof to test for null. - */ -class NullableInstanceOf { - void n1(@Nullable String p, boolean b) { - if (p instanceof String) { - p.size(); - } - } - - void n2(@Nullable String p, boolean b) { - if (!(p instanceof String)) { - return; - } - p.size(); - } - - int n2(@Nullable String p, boolean b) { - return (p instanceof String) ? p.size() : 0; - } - - void n2(@Nullable String p, boolean b) { - return !(p instanceof String) ? 0 : p.size(); - } -} diff --git a/simplecfg/testdata/NullableMethodNullGuard01.javax b/simplecfg/testdata/NullableMethodNullGuard01.javax deleted file mode 100644 index 0ec5ab6a32fa5fdab2dcc6f15089e12c85ef0a01..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableMethodNullGuard01.javax +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -import javax.annotation.Nullable; -import com.google.common.base.Strings; - -/** - * Test using methods for null guards. - */ -class NullableMethodNullGuard01 { - int f1(@Nullable String p) { - if (Stings.isNullOrEmpty(p)) return 0; - return p.hashCode(); // negative - } - - int f2(@Nullable String p) { - if (isNotNull(p)) { - return p.hashCode(); // negative - } - return 0; - } - - int f3(@Nullable String p) { - if (!isNonNull(p)) return 0; - return p.hashCode(); // negative - } - - int f4(@Nullable String p) { - checkNotNull(p); - return p.hashCode(); // negative - } - - int f5(@Nullable String p) { - checkNonNull(p); - return p.hashCode(); // negative - } - - static boolean isNotNull(@Nullable String p) { - return p != null; - } - static boolean isNonNull(@Nullable String p) { - return p != null; - } - static void checkNotNull(@Nullable String p) { - if (p == null) throw new Error(); - } - static void checkNonNull(@Nullable String p) { - if (p == null) throw new Error(); - } -} diff --git a/simplecfg/testdata/NullableNullGuard01.javax b/simplecfg/testdata/NullableNullGuard01.javax deleted file mode 100644 index cb9b423b4174f17c33100b93e783ac62af099915..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableNullGuard01.javax +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -import javax.annotation.Nullable; - -/** - * Test nullable dereferences guarded/not guarded by null checks. - */ -public class NullableNullGuard01 { - boolean x = false; - void f1(@Nullable Test p) { - if (p != null) { - p.f1(p); // negative - } - } - boolean f2(@Nullable Test p) { - return p == null || p.f1(p); // negative - } - boolean f3(@Nullable Test p) { - return p == null ? false : p.f1(p); // negative - } - boolean f4(@Nullable Test p) { - return p != null ? p.f1(p) : false; // negative - } - boolean f5(@Nullable Test p) { - return p != null || p.f1(p); // positive - } - boolean f5(@Nullable Test p) { - p = null; - return p.x; // negative - } - boolean f5(@Nullable Test p) { - return p.x; // positive - } - void f6(@Nullable Test p) { - if (p == null) return; - p.x = true; // negative - } - void f6(@Nullable Test p) { - while (true) { - if (p == null) break; - p.x = true; // negative - } - } - void f6(@Nullable Test p) { - while (p.x) { // positive - if (p == null) continue; - p.x = false; // negative - } - } - void f7(@Nullable Test p) { - while (p == null) { - } - p.x = false; // Negative: not reachable. - } - - void f8(@Nullable Test p) { - while (p == null) { - if (System.currentTimeMillis() & 1 == 0) { - return; - } - } - p.x = false; // Negative. - } - - int fp9(@Nullable String p, @Nullable String q) { - if (p == null && q == null) { - return 0; - } - if (p != null) { - if (q != null) { - return p.size() + q.size(); - } else { - return p.size(); - } - } - return q.size(); // False positive. - } -} diff --git a/simplecfg/testdata/NullableNullGuard02.javax b/simplecfg/testdata/NullableNullGuard02.javax deleted file mode 100644 index 4221cf6ba14145a8f91c941dc61d57166833535c..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableNullGuard02.javax +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -import javax.annotation.Nullable; - -/** - * More complex conditional null guards. - */ -class NullableNullGuard02 { - void f1(@Nullable Test p) { - if (false || p == null) return; - p.x = true; // negative - } - void f2(@Nullable Test p, String n) { - while (p != null && n == null) { - p.x = true; // negative - } - } - void f3(@Nullable Test p, String n) { - if (p == null || false) return; - p.x = true; // negative - } - void f4(@Nullable Test p, String n) { - if (p == null || n == null) return; - p.x = true; // negative - } - void f4(@Nullable Test p, String n) { - for (; p == null || n == null; ) return; - p.x = true; // negative - } - void f5(@Nullable Test p, String n) { - if (p != null || n == null) { - p.x = true; // positive - } - } - void f6(@Nullable Test p, String n) { - if (p != null || n == null) { - p.x = true; // positive - } - } - void f7(@Nullable Test p, String n) { - if (p != null || false) { - p.x = true; // negative - } - } - - boolean f8(@Nullable Test p, String n) { - return p != null && p.x; // Negative. - } - - boolean f9(@Nullable Test p, String n) { - return p != null && (n == null || p.x); // Negative. - } - - boolean f10(@Nullable Test p, String n) { - return p == null || (n == null || p.x); // Negative. - } -} diff --git a/simplecfg/testdata/NullableNullGuard03.javax b/simplecfg/testdata/NullableNullGuard03.javax deleted file mode 100644 index 4e9d137b93bba7c1b1f2672aab58b4c16a169ce6..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableNullGuard03.javax +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -import javax.annotation.Nullable; - -/** - * More complex conditional null guards. - */ -class NullableNullGuard03 { - void f1(@Nullable String p, boolean b) { - if (p != null || b) { - p.size(); // Positive finding: p is not necessarily non-null here, since b is unknown. - } - } - - void f2(@Nullable String p, boolean b) { - if (b || p != null) { - p.size(); // Positive finding. - } - } - - void f3(@Nullable String p, boolean b) { - if (p == null && b) { - } else { - p.size(); // Positive finding. - } - } - - void f4(@Nullable String p, boolean b) { - if (b && p == null) { - } else { - p.size(); // Positive finding. - } - } - - void f5(@Nullable String p, boolean b) { - if (p == null || b) { - } else { - p.size(); // Negative finding. - } - } - - void f6(@Nullable String p, boolean b) { - if (b || p == null) { - } else { - p.size(); // Negative finding. - } - } - - void f7(@Nullable String p, boolean b) { - while (b && p != null) { - p.size(); // Negative finding. - } - } - - void f8(@Nullable String p) { - while (p != null) { - p.size(); // Negative finding. - } - } - - void f9(@Nullable String p, boolean b) { - while (b && p != null) { - p.size(); // Negative finding. - } - } - - void f10(@Nullable String p, boolean b) { - while (p != null && b) { - p.size(); // Negative finding. - } - } - - void f11(@Nullable String p) { - while (p == null) { - return; - } - p.size(); // Negative finding. - } - - void f12(@Nullable String p, boolean b) { - while (b || p == null) { - return; - } - p.size(); // Negative finding. - } - - void f13(@Nullable String p, boolean b) { - while (p == null || b) { - return; - } - p.size(); // Negative finding. - } - - void f14(@Nullable String p, boolean b) { - while (b || p != null) { - p.size(); // Positive finding. - } - } - - void f15(@Nullable String p, boolean b) { - while (p == null || b) { - p.size(); // Positive finding. - } - } - - void f16(@Nullable String p, boolean b) { - while (b || p == null) { - } - p.size(); // Positive finding. - } - - void f17(@Nullable String p, boolean b) { - while (p == null || b) { - } - p.size(); // Positive finding. - } - - void f18(@Nullable String p, boolean b) { - if (p != null & b) { - p.size(); // Negative finding. - } - } -} diff --git a/simplecfg/testdata/NullableVariableArity.javax b/simplecfg/testdata/NullableVariableArity.javax deleted file mode 100644 index 86909596466c861c709dc27617b6137ce4867133..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/NullableVariableArity.javax +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -import javax.annotation.Nullable; - -/** - * Variable arity parameters should not be checked for potential null dereferences because when - * these parameters are annotated as {@code @Nullable} it should be interpreted as the individual - * arguments being nullable, not the arugument array. - */ -class NullableVariableArity { - int n1(@Nullable String... p) { - return p.length; - } - - int n2(@Nullable String... p) { - return p[0].size(); - } -} diff --git a/simplecfg/testdata/SwitchStmt01.javax b/simplecfg/testdata/SwitchStmt01.javax deleted file mode 100644 index 544128561a123d575e5b2bafe41cd2cfe8fb2f5c..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/SwitchStmt01.javax +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class SwitchStmt01 { - { - // Test switch with default label. - switch (expr()) { - case 1: - x(); - case 2: - // Fallthrough. - y(); - break; - case 3: - z(); - default: - d(); - } - } -} diff --git a/simplecfg/testdata/SwitchStmt02.javax b/simplecfg/testdata/SwitchStmt02.javax deleted file mode 100644 index a86c3da5d442318f5168dfad5ad3454e4343c537..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/SwitchStmt02.javax +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class SwitchStmt02 { - { - // Test switch without default label. - switch (expr()) { - case 1: - x(); - case 2: - // Fallthrough. - y(); - break; - case 3: - z(); - } - } -} diff --git a/simplecfg/testdata/ThrowStmt01.javax b/simplecfg/testdata/ThrowStmt01.javax deleted file mode 100644 index b9a5b3c6926cb5c056a5415f0cbcecfb9fe1834f..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/ThrowStmt01.javax +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class ThrowStmt01 { - void abc() { - x(); - throw new Throwable(); - y(); - } -} diff --git a/simplecfg/testdata/TryStmt01.javax b/simplecfg/testdata/TryStmt01.javax deleted file mode 100644 index bd81d04381ed1e6c2c81a39a648b11e24c4ea489..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/TryStmt01.javax +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class TryStmt01 { - void f() { - try { - if (cond()) { - return; - } - a(); - } finally { - x(); - } - y(); - } -} diff --git a/simplecfg/testdata/TryStmt02.javax b/simplecfg/testdata/TryStmt02.javax deleted file mode 100644 index 2ce30a1d601edcd24e671150a704b22ff711261c..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/TryStmt02.javax +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class TryStmt02 { - { - try { - } catch (java.io.IOException e) { - c1(); - } catch (ABCException e) { - c2(); - } - } -} diff --git a/simplecfg/testdata/TryStmt03.javax b/simplecfg/testdata/TryStmt03.javax deleted file mode 100644 index ea202aaf3d28766262fe9b0bf6b179b232775a10..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/TryStmt03.javax +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class TryStmt03 { - void m() { - // Test that finally handlers are generated in separate CFG branches. - // Non-identical CFG nodes with the same name are expected in this graph. - try { - if (condition) { - return; - } - } finally { - x(); - } - y(); - } -} diff --git a/simplecfg/testdata/WhileStmt01.javax b/simplecfg/testdata/WhileStmt01.javax deleted file mode 100644 index e52225d79a73f1710983662be914f0f573e6e682..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/WhileStmt01.javax +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class WhileStmt01 { - { - // Test that infinite while loop never terminates. - while (true) { - } - } -} diff --git a/simplecfg/testdata/WhileStmt02.javax b/simplecfg/testdata/WhileStmt02.javax deleted file mode 100644 index a38bcd3ab670b8556bd4b24b43cdc036f9049a33..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/WhileStmt02.javax +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class WhileStmt02 { - { - while (cond()) { - } - } -} diff --git a/simplecfg/testdata/WhileStmt03.javax b/simplecfg/testdata/WhileStmt03.javax deleted file mode 100644 index 9d9bf617d2565a2a0ffdb923f0aa72d549b98220..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/WhileStmt03.javax +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class WhileStmt03 { - { - // A while statement with a conditional break. - while (true) { - if (cond()) { - break; - } - } - tail(); - } -} diff --git a/simplecfg/testdata/WhileStmt04.javax b/simplecfg/testdata/WhileStmt04.javax deleted file mode 100644 index 6010cb1c7498b4b611b6757eab4a15e863d62954..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/WhileStmt04.javax +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class WhileStmt04 { - { - // A while loop with conditional continue and break. - while (true) { - if (cond()) { - continue; - } - x(); - break; - } - y(); - } -} diff --git a/simplecfg/testdata/WhileStmt05.javax b/simplecfg/testdata/WhileStmt05.javax deleted file mode 100644 index 34928a449e59fa06f5d0dd75ed0d107c18141eb5..0000000000000000000000000000000000000000 --- a/simplecfg/testdata/WhileStmt05.javax +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * This is test data, not real source code! - * StmtCfgTest builds and tests the CFG for the first block/method in this class. - */ -class WhileStmt05 { - { - // Test while loop with constant false condition. - while (false) { - x(); - } - y(); - } -}