initial synchronization

master
Open Source Synchronization 10 years ago
commit b8982270f2

@ -0,0 +1,25 @@
[alias]
endtoend_test_objc = //infer/tests/endtoend:objc_endtoend_tests
frontend_test_objc = //infer/tests/frontend:objc_frontend_tests
endtoend_test_java = //infer/tests/endtoend:java_endtoend_tests
endtoend_test_c = //infer/tests/endtoend:edgc_endtoend_tests
integration_tests = //infer/tests:integration_tests
objc = //infer/tests:objc_tests
c = //infer/tests:c_tests
cpp = //infer/tests:cpp_tests
objcpp = //infer/tests:objcpp_tests
clang = //infer/tests:clang_tests
java = //infer/tests/endtoend:java_endtoend_tests
java_libraries = //dependencies/java:java_libraries
infer = //infer/tests/endtoend/java/infer:infer
eradicate = //infer/tests/endtoend/java/eradicate:eradicate
checkers = //infer/tests/endtoend/java/checkers:checkers
tracing = //infer/tests/endtoend/java/tracing:tracing
[project]
ignore = .git, .ml, .mli

89
.gitignore vendored

@ -0,0 +1,89 @@
# Generated files #
###################
*.pyc
*.specs
*.cm*
*.o
*~
*.swp
*.annot
*.class
*.log
*.orig
*.rej
# Directories generated by Ocamlbuild
_build
# IntelliJ files
scripts/.idea/
infer/tests/.idea/dictionaries
infer/tests/.idea/inspectionProfiles
infer/tests/.idea/tasks.xml
infer/tests/.idea/uiDesigner.xml
infer/tests/.idea/workspace.xml
infer/tests/.idea/misc.xml
infer/tests/.idea/runConfigurations
infer/tests/.idea/copyright/profiles_settings.xml
# Eclipse settings file
.project
.cproject
.paths
.pydevproject
.settings/
.classpath
# Arcanist
/arcanist/.phutil_module_cache
# MacOS generated files
.DS_Store
# Directories and files generated by Infer
infer-out/
*.o.astlog
*.o.sh
# Directories generated by buck
buck-out/
.buckd/
#other
/infer/bin/InferAnalyze
/infer/bin/InferClang
/infer/bin/InferJava
/infer/bin/InferPrint
/infer/bin/Typeprop
/infer/src/backend/version.ml
infer/models/java/models/
infer/lib/java/models.jar
infer/models/java/bootclasspath
infer/lib/specs/c_models
infer/lib/specs/cpp_models
infer/lib/specs/objc_models
infer/lib/specs/clean_models
dependencies/clang-plugin/clang-plugin-version.done
include/
share/
#atdgen stubs
infer/src/backend/jsonbug_*
# intelliJ files
.idea
*.iml
/infer/src/backend/.projectSettings
infer/models/out/
/infer/_build-infer/
/infer/src/clang/clang_ast_j.ml
/infer/src/clang/clang_ast_j.mli
/infer/src/clang/clang_ast_proj.ml
/infer/src/clang/clang_ast_proj.mli
/infer/src/clang/clang_ast_t.ml
/infer/src/clang/clang_ast_t.mli
/infer/annotations/annotations.jar

@ -0,0 +1 @@
We require contributors to sign our Contributor License Agreement. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla. If you have any questions, please drop us a line at cla@fb.com. Thanks!

@ -0,0 +1,134 @@
#Install Infer
We provide pre-built Infer binaries for Linux and MacOS.
If you just wish to use Infer, and are not interested in making contributions to it, then these binaries are all you need.
Otherwise, if you wish to compile Infer, here are also instructions to do so, depending on your operating system.
- [Install the Infer binaries](INSTALL.md#Install-the-Infer-binaries)
- [Mac OS X](INSTALL.md#Mac-OS-X)
- [Linux](INSTALL.md#Linux)
- [Install Infer from source](INSTALL.md#Install-Infer-from-source)
- [Download Infer](INSTALL.md#Download-Infer)
- [Mac OS X](INSTALL.md#Mac-OS-X)
- [Linux](INSTALL.md#Linux)
##Install the Infer binaries
###Mac OS X
Get the latest `infer-osx-vXX.tar.xz` from [infer releases](https://github.com/facebook/infer/releases) and run the commands below in your terminal to install Infer.
```bash
tar xf infer-osx-vXX.tar.xz
# this assumes you use bash, adapt to your needs in case you use
# another shell
echo "export PATH=$PATH:`pwd`/infer-osx/infer/infer/bin" \
>> ~/.bashrc && source ~/.bashrc
```
###Linux (64 bit)
Get the latest `infer-linux64-vXX.tar.xz` from [infer releases](https://github.com/facebook/infer/releases) and run the commands below in your terminal to install Infer.
```bash
tar xf infer-linux64-vXX.tar.xz
# this assumes you use bash, adapt to your needs in case you use
# another shell
echo "export PATH=$PATH:`pwd`/infer-0.1-x64-linux/infer/infer/bin" \
>> ~/.bashrc && source ~/.bashrc
```
##Install Infer from source
The following instructions describe how to compile Infer on different platforms.
###<a name="download"></a> Download the Infer repository
git clone https://github.com/facebook/infer.git
To analyse C and ObjC, Infer requires clang and the [facebook-clang-plugin](https://github.com/facebook/facebook-clang-plugins). If you wish to analyse only Java/Android code, then you could skip these dependencies. Details below.
###MacOS X
####Requirements
- `opam` (Instructions [here](https://opam.ocaml.org/doc/Install.html#OSX))
##### Requirements for Java analysis
- `Java <= 1.7`
- Android dev setup for analysis of Android apps.
##### Requirements for C/ObjC analysis
- `XCode <= 6.3, >= 6.1`
- `clang` (XCode command line tools. You can install them with the command `xcode-select --install`)
###Installation instructions
Install OCaml dependencies:
```bash
opam init --comp=4.01.0 # (answer 'y' to the question)
opam install sawja.1.5 atdgen.1.5.0 javalib.2.3 extlib.1.5.4
```
If you do not require support for the C/Objective C analysis in Infer, and only wish to analyse Java files, continue with these instructions. By the way, Java 1.8 is not supported.
```bash
cd infer
make -C infer java
export PATH=`pwd`/infer/bin:$PATH
```
To compile support for both Java and C/Objective C, do this instead.
```bash
cd infer
./update-fcp.sh && ../facebook-clang-plugin/clang/setup.sh && ./compile-fcp.sh # go have a coffee :)
make -C infer
export PATH=`pwd`/infer/bin:$PATH
```
###Linux
These instructions were tested on Linux (64 Bit), on the following distributions: Debian 7, Ubuntu 14.04 and Ubuntu 12.04.4 LTS.
Install OCaml dependencies:
```bash
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git openjdk-7-jdk m4 zlib1g-dev python-software-properties build-essential libgmp-dev libmpfr-dev libmpc-dev unzip
wget https://github.com/ocaml/opam/releases/download/1.2.2/opam-1.2.2-x86_64-Linux -O opam
chmod +x opam
./opam init --comp=4.01.0 #(then say 'y' to the final question)
eval `./opam config env`
./opam install sawja.1.5 atdgen.1.5.0 javalib.2.3 extlib.1.5.4 #(then say 'y' to the question)
```
If you do not require support for the C/Objective C analysis in Infer, and only wish to analyse Java files, continue with these instructions. By the way, Java 1.8 is not supported.
```bash
cd infer
make -C infer java
export PATH=`pwd`/infer/bin:$PATH
```
To compile support for both Java and C/Objective C, do this instead. If your distribution is Ubuntu 12.04.4 LTS, you need to install `gcc 4.8` and `g++ 4.8` as well. Follow the following instructions to do that. You may skip this step in other distributions.
```bash
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-4.8 g++-4.8
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8
```
Then continue with:
```bash
cd infer
./update-fcp.sh
../facebook-clang-plugin/clang/setup.sh # go have a coffee :)
./compile-fcp.sh
make -C infer
export PATH=`pwd`/infer/bin:$PATH
```

@ -0,0 +1,30 @@
BSD License
For Infer software
Copyright (c) 2013-, Facebook, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name Facebook nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -0,0 +1,33 @@
Additional Grant of Patent Rights Version 2
"Software" means the Infer software distributed by Facebook, Inc.
Facebook, Inc. (“Facebook”) hereby grants to each recipient of the Software
(“you”) a perpetual, worldwide, royalty-free, non-exclusive, irrevocable
(subject to the termination provision below) license under any Necessary
Claims, to make, have made, use, sell, offer to sell, import, and otherwise
transfer the Software. For avoidance of doubt, no license is granted under
Facebook's rights in any patent claims that are infringed by (i) modifications
to the Software made by you or any third party or (ii) the Software in
combination with any software or other technology.
The license granted hereunder will terminate, automatically and without notice,
if you (or any of your subsidiaries, corporate affiliates or agents) initiate
directly or indirectly, or take a direct financial interest in, any Patent
Assertion: (i) against Facebook or any of its subsidiaries or corporate
affiliates, (ii) against any party if such Patent Assertion arises in whole or
in part from any software, technology, product or service of Facebook or any of
its subsidiaries or corporate affiliates, or (iii) against any party relating
to the Software. Notwithstanding the foregoing, if Facebook or any of its
subsidiaries or corporate affiliates files a lawsuit alleging patent
infringement against you in the first instance, and you respond by filing a
patent infringement counterclaim in that lawsuit against that party that is
unrelated to the Software, the license granted hereunder will not terminate
under section (i) of this paragraph due to such counterclaim.
A "Necessary Claim" is a claim of a patent owned by Facebook that is
necessarily infringed by the Software standing alone.
A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
or contributory infringement or inducement to infringe any patent, including a
cross-claim or counterclaim.

@ -0,0 +1,15 @@
Infer
=====
Infer is a static analysis tool for Java and C / Objective C.
To see what it can do for you, check out the documentation at <http://facebook.github.io/infer/>.
Installation
------------
Read the [INSTALL.md](INSTALL.md) file for details on installing Infer.
License
-------
Infer is BSD-licensed. We also provide an additional patent grant.

@ -0,0 +1,48 @@
#!/bin/bash
set -e
set -x
# This script installs the facebook-clang-plugins
#
# TODO (t5939566): ADD INSTRUCTIONS ON HOW TO CUSTOMIZE THE ENVVARS FOR
# THE INSTALLATION OF THE PLUGINS.
INFER_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PLUGIN_DIR="$INFER_ROOT/../facebook-clang-plugin"
CLANG_EXEC="$PLUGIN_DIR/clang/bin/clang"
# check if clang is available
if ! $CLANG_EXEC --version 2>&1 | grep -q '3\.6'; then
echo "The required version of clang has not been found in $CLANG_EXEC" && exit 1
fi
# install facebook-clang-plugins
pushd "$PLUGIN_DIR"
# prepare flags for the compilation on the Linux platform
platform="$(uname)"
if [ "$platform" == 'Linux' ]; then
export SDKPATH=""
export PATH="$PLUGIN_DIR/clang/bin:$PATH"
[ -z "$CC" ] && export CC="$PLUGIN_DIR/clang/bin/clang"
[ -z "$CXX" ] && export CXX="$PLUGIN_DIR/clang/bin/clang++"
[ -z "$CFLAGS" ] && export CFLAGS="-std=c++11 -fPIC"
[ -z "$LDFLAGS" ] && export LDFLAGS="-shared"
[ -z "$CLANG_PREFIX" ] && export CLANG_PREFIX="$PLUGIN_DIR/clang"
[ -z "$LLVM_INCLUDES" ] && export LLVM_INCLUDES="$PLUGIN_DIR/clang/include"
[ -z "$CLANG_INCLUDES" ] && export CLANG_INCLUDES="$LLVM_INCLUDES $CLANG_PREFIX/include"
fi
# compile
make clean
make -C clang-ocaml clean
make
make -C clang-ocaml all build/clang_ast_proj.ml build/clang_ast_proj.mli
popd
# check YojsonASTExporter works with clang
echo "int main() { return 0; }" | \
$CLANG_EXEC -o /dev/null -x c \
-Xclang -load -Xclang $PLUGIN_DIR/libtooling/build/FacebookClangPlugin.dylib \
-Xclang -plugin -Xclang YojsonASTExporter -c - > /dev/null \
|| { echo "$CLANG_EXEC and the facebook-clang-plugins are not working.";
echo "Check you're using the right revision of clang, then retry"; exit 1; }

@ -0,0 +1 @@
ab60f2578bf51a8b58afa63de7cee65d7ad891c9

@ -0,0 +1,17 @@
java_library(
name = 'java_libraries',
deps=[
'//dependencies/java/guava:guava',
'//dependencies/java/junit:hamcrest',
'//dependencies/java/jackson:jackson',
'//dependencies/java/jsr-305:jsr-305',
'//dependencies/java/junit:junit',
'//dependencies/java/opencsv:opencsv'
],
visibility = [
'PUBLIC'
]
)
project_config(
src_target = ':java_libraries',
)

@ -0,0 +1,7 @@
prebuilt_jar(
name = 'guava',
binary_jar = 'guava-10.0.1-fork.jar',
visibility = [
'PUBLIC'
]
)

Binary file not shown.

@ -0,0 +1,10 @@
prebuilt_jar(
name = 'jackson',
binary_jar = 'jackson-2.2.3.jar',
deps = [
'//dependencies/java/guava:guava',
],
visibility = [
'PUBLIC',
]
)

Binary file not shown.

@ -0,0 +1,8 @@
prebuilt_jar(
name = 'jsr-305',
binary_jar = 'jsr305.jar',
source_jar = 'jsr305-src.jar',
visibility = [
'PUBLIC',
],
)

Binary file not shown.

Binary file not shown.

@ -0,0 +1,20 @@
prebuilt_jar(
name = 'hamcrest',
binary_jar = 'hamcrest-core-1.3.jar',
visibility = [
'PUBLIC'
]
)
prebuilt_jar(
name = 'junit',
binary_jar = 'junit-4.11.jar',
deps = [
':hamcrest'
],
visibility = [
'PUBLIC'
]
)

Binary file not shown.

Binary file not shown.

@ -0,0 +1,7 @@
prebuilt_jar(
name = 'opencsv',
binary_jar = 'opencsv-2.3.jar',
visibility = [
'PUBLIC'
]
)

@ -0,0 +1 @@
http://www.apache.org/licenses/LICENSE-2.0

Binary file not shown.

@ -0,0 +1,6 @@
class Hello {
int test() {
String s = null;
return s.length();
}
}

@ -0,0 +1,12 @@
#import <Foundation/Foundation.h>
@interface Hello: NSObject
@property NSString* s;
@end
@implementation Hello
NSString* m() {
Hello* hello = nil;
return hello->_s;
}
@end

@ -0,0 +1,39 @@
This directory contains small examples to play with Infer. They each exhibit
one simple programming error that is caught by Infer.
Contents
--------
- Hello.java: try this example by running
infer -- javac Hello.java
- Hello.m: try this example by running
infer -- clang -c Hello.m
- hello.c: try this example by running
infer -- gcc -c hello.c
In this case, note that Infer captures the gcc command and runs
clang instead to parse C files. Thus you may get compiler errors and
warnings that differ from gcc's.
- android_hello/: a sample Android app. Try this example by running
infer -- ./gradlew build
Make sure that you have the Android SDK 22 installed and up to date, and in
particular the "Android SDK Build-tools" and "Android Support Repository".
- ios_hello/: a sample iOS app. Try this example by running
infer -- xcodebuild -target HelloWorldApp -configuration Debug -sdk iphonesimulator
- c_hello/: a sample make-based C project. Try this example by running
infer -- make
Note
----
The infer toplevel command must be in your PATH for the commands above to
succeed. Otherwise, modify the commands to use the correct path to infer, eg
../infer/bin/infer -- javac Hello.java

@ -0,0 +1,6 @@
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build

@ -0,0 +1,25 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "infer.inferandroidexample"
minSdkVersion 8
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
}

@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/irp/android-sdk-macosx/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

@ -0,0 +1,13 @@
package infer.inferandroidexample;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="infer.inferandroidexample" >
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

@ -0,0 +1,63 @@
package infer.inferandroidexample;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String s = getDay();
int length = s.length();
writeToFile();
}
private String getDay() {
if (Calendar.getInstance().get(Calendar.DAY_OF_WEEK) == Calendar.WEDNESDAY) {
return "Wednesday";
} else return null;
}
private void writeToFile() {
byte[] arr = {1, 2, 3};
FileOutputStream fis;
try {
fis = new FileOutputStream("file.txt");
fis.write(arr);
fis.close();
} catch (IOException e) {
//Deal with exception
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

@ -0,0 +1,11 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView android:text="@string/hello_world" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>

@ -0,0 +1,6 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
<item android:id="@+id/action_settings" android:title="@string/action_settings"
android:orderInCategory="100" app:showAsAction="never" />
</menu>

@ -0,0 +1,6 @@
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>

@ -0,0 +1,5 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">InferAndroidExample</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
</resources>

@ -0,0 +1,8 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>

@ -0,0 +1,19 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}

@ -0,0 +1,18 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

@ -0,0 +1,6 @@
#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip

@ -0,0 +1,164 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

@ -0,0 +1,11 @@
SOURCES = $(shell ls *.c)
OBJECTS = $(SOURCES:.c=.o)
all: $(OBJECTS)
.c.o:
${CC} -c $<
clean:
rm -rf $(OBJECTS)

@ -0,0 +1,60 @@
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/select.h>
#include <unistd.h>
struct Person {
int age;
int height;
int weight;
};
int simple_null_pointer() {
struct Person *max = 0;
return max->age;
}
struct Person *Person_create(int age, int height, int weight) {
struct Person *who = 0;
return who;
}
int get_age(struct Person *who) {
return who->age;
}
int null_pointer_interproc() {
struct Person *joe = Person_create(32, 64, 140);
return get_age(joe);
}
void fileNotClosed()
{
int fd = open("hi.txt", O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd != -1) {
char buffer[256];
// We can easily batch that by separating with space
write(fd, buffer, strlen(buffer));
}
}
void simple_leak() {
int *p;
p = (int*) malloc(sizeof(int));
}
void common_realloc_leak() {
int *p, *q;
p = (int*) malloc(sizeof(int));
q = (int*) realloc(p, sizeof(int) * 42);
// if realloc fails, then p becomes unreachable
if (q != NULL) free(q);
}

@ -0,0 +1,6 @@
#include <stdlib.h>
void test() {
int *s = NULL;
*s = 42;
}

@ -0,0 +1,433 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
124F6C531B0CDAE400C16385 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 124F6C521B0CDAE400C16385 /* main.m */; };
124F6C561B0CDAE400C16385 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 124F6C551B0CDAE400C16385 /* AppDelegate.m */; };
124F6C591B0CDAE400C16385 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 124F6C581B0CDAE400C16385 /* ViewController.m */; };
124F6C5C1B0CDAE400C16385 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 124F6C5A1B0CDAE400C16385 /* Main.storyboard */; };
124F6C5E1B0CDAE400C16385 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 124F6C5D1B0CDAE400C16385 /* Images.xcassets */; };
124F6C611B0CDAE400C16385 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 124F6C5F1B0CDAE400C16385 /* LaunchScreen.xib */; };
124F6C6D1B0CDAE400C16385 /* HelloWorldAppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 124F6C6C1B0CDAE400C16385 /* HelloWorldAppTests.m */; };
124F6C771B0CED9B00C16385 /* Hello.m in Sources */ = {isa = PBXBuildFile; fileRef = 124F6C761B0CED9B00C16385 /* Hello.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
124F6C671B0CDAE400C16385 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 124F6C451B0CDAE400C16385 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 124F6C4C1B0CDAE400C16385;
remoteInfo = HelloWorldApp;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
124F6C4D1B0CDAE400C16385 /* HelloWorldApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorldApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
124F6C511B0CDAE400C16385 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
124F6C521B0CDAE400C16385 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
124F6C541B0CDAE400C16385 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
124F6C551B0CDAE400C16385 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
124F6C571B0CDAE400C16385 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
124F6C581B0CDAE400C16385 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
124F6C5B1B0CDAE400C16385 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
124F6C5D1B0CDAE400C16385 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
124F6C601B0CDAE400C16385 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
124F6C661B0CDAE400C16385 /* HelloWorldAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HelloWorldAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
124F6C6B1B0CDAE400C16385 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
124F6C6C1B0CDAE400C16385 /* HelloWorldAppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HelloWorldAppTests.m; sourceTree = "<group>"; };
124F6C761B0CED9B00C16385 /* Hello.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Hello.m; sourceTree = "<group>"; };
124F6C781B0CEDAF00C16385 /* Hello.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Hello.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
124F6C4A1B0CDAE400C16385 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
124F6C631B0CDAE400C16385 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
124F6C441B0CDAE400C16385 = {
isa = PBXGroup;
children = (
124F6C4F1B0CDAE400C16385 /* HelloWorldApp */,
124F6C691B0CDAE400C16385 /* HelloWorldAppTests */,
124F6C4E1B0CDAE400C16385 /* Products */,
);
sourceTree = "<group>";
};
124F6C4E1B0CDAE400C16385 /* Products */ = {
isa = PBXGroup;
children = (
124F6C4D1B0CDAE400C16385 /* HelloWorldApp.app */,
124F6C661B0CDAE400C16385 /* HelloWorldAppTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
124F6C4F1B0CDAE400C16385 /* HelloWorldApp */ = {
isa = PBXGroup;
children = (
124F6C541B0CDAE400C16385 /* AppDelegate.h */,
124F6C551B0CDAE400C16385 /* AppDelegate.m */,
124F6C571B0CDAE400C16385 /* ViewController.h */,
124F6C581B0CDAE400C16385 /* ViewController.m */,
124F6C5A1B0CDAE400C16385 /* Main.storyboard */,
124F6C5D1B0CDAE400C16385 /* Images.xcassets */,
124F6C5F1B0CDAE400C16385 /* LaunchScreen.xib */,
124F6C501B0CDAE400C16385 /* Supporting Files */,
124F6C761B0CED9B00C16385 /* Hello.m */,
124F6C781B0CEDAF00C16385 /* Hello.h */,
);
path = HelloWorldApp;
sourceTree = "<group>";
};
124F6C501B0CDAE400C16385 /* Supporting Files */ = {
isa = PBXGroup;
children = (
124F6C511B0CDAE400C16385 /* Info.plist */,
124F6C521B0CDAE400C16385 /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
124F6C691B0CDAE400C16385 /* HelloWorldAppTests */ = {
isa = PBXGroup;
children = (
124F6C6C1B0CDAE400C16385 /* HelloWorldAppTests.m */,
124F6C6A1B0CDAE400C16385 /* Supporting Files */,
);
path = HelloWorldAppTests;
sourceTree = "<group>";
};
124F6C6A1B0CDAE400C16385 /* Supporting Files */ = {
isa = PBXGroup;
children = (
124F6C6B1B0CDAE400C16385 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
124F6C4C1B0CDAE400C16385 /* HelloWorldApp */ = {
isa = PBXNativeTarget;
buildConfigurationList = 124F6C701B0CDAE400C16385 /* Build configuration list for PBXNativeTarget "HelloWorldApp" */;
buildPhases = (
124F6C491B0CDAE400C16385 /* Sources */,
124F6C4A1B0CDAE400C16385 /* Frameworks */,
124F6C4B1B0CDAE400C16385 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = HelloWorldApp;
productName = HelloWorldApp;
productReference = 124F6C4D1B0CDAE400C16385 /* HelloWorldApp.app */;
productType = "com.apple.product-type.application";
};
124F6C651B0CDAE400C16385 /* HelloWorldAppTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 124F6C731B0CDAE400C16385 /* Build configuration list for PBXNativeTarget "HelloWorldAppTests" */;
buildPhases = (
124F6C621B0CDAE400C16385 /* Sources */,
124F6C631B0CDAE400C16385 /* Frameworks */,
124F6C641B0CDAE400C16385 /* Resources */,
);
buildRules = (
);
dependencies = (
124F6C681B0CDAE400C16385 /* PBXTargetDependency */,
);
name = HelloWorldAppTests;
productName = HelloWorldAppTests;
productReference = 124F6C661B0CDAE400C16385 /* HelloWorldAppTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
124F6C451B0CDAE400C16385 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0620;
ORGANIZATIONNAME = "Dulma Rodriguez";
TargetAttributes = {
124F6C4C1B0CDAE400C16385 = {
CreatedOnToolsVersion = 6.2;
};
124F6C651B0CDAE400C16385 = {
CreatedOnToolsVersion = 6.2;
TestTargetID = 124F6C4C1B0CDAE400C16385;
};
};
};
buildConfigurationList = 124F6C481B0CDAE400C16385 /* Build configuration list for PBXProject "HelloWorldApp" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 124F6C441B0CDAE400C16385;
productRefGroup = 124F6C4E1B0CDAE400C16385 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
124F6C4C1B0CDAE400C16385 /* HelloWorldApp */,
124F6C651B0CDAE400C16385 /* HelloWorldAppTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
124F6C4B1B0CDAE400C16385 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
124F6C5C1B0CDAE400C16385 /* Main.storyboard in Resources */,
124F6C611B0CDAE400C16385 /* LaunchScreen.xib in Resources */,
124F6C5E1B0CDAE400C16385 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
124F6C641B0CDAE400C16385 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
124F6C491B0CDAE400C16385 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
124F6C591B0CDAE400C16385 /* ViewController.m in Sources */,
124F6C561B0CDAE400C16385 /* AppDelegate.m in Sources */,
124F6C771B0CED9B00C16385 /* Hello.m in Sources */,
124F6C531B0CDAE400C16385 /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
124F6C621B0CDAE400C16385 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
124F6C6D1B0CDAE400C16385 /* HelloWorldAppTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
124F6C681B0CDAE400C16385 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 124F6C4C1B0CDAE400C16385 /* HelloWorldApp */;
targetProxy = 124F6C671B0CDAE400C16385 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
124F6C5A1B0CDAE400C16385 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
124F6C5B1B0CDAE400C16385 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
124F6C5F1B0CDAE400C16385 /* LaunchScreen.xib */ = {
isa = PBXVariantGroup;
children = (
124F6C601B0CDAE400C16385 /* Base */,
);
name = LaunchScreen.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
124F6C6E1B0CDAE400C16385 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
124F6C6F1B0CDAE400C16385 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
124F6C711B0CDAE400C16385 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = HelloWorldApp/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
124F6C721B0CDAE400C16385 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = HelloWorldApp/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
124F6C741B0CDAE400C16385 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = HelloWorldAppTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HelloWorldApp.app/HelloWorldApp";
};
name = Debug;
};
124F6C751B0CDAE400C16385 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
INFOPLIST_FILE = HelloWorldAppTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HelloWorldApp.app/HelloWorldApp";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
124F6C481B0CDAE400C16385 /* Build configuration list for PBXProject "HelloWorldApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
124F6C6E1B0CDAE400C16385 /* Debug */,
124F6C6F1B0CDAE400C16385 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
124F6C701B0CDAE400C16385 /* Build configuration list for PBXNativeTarget "HelloWorldApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
124F6C711B0CDAE400C16385 /* Debug */,
124F6C721B0CDAE400C16385 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
124F6C731B0CDAE400C16385 /* Build configuration list for PBXNativeTarget "HelloWorldAppTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
124F6C741B0CDAE400C16385 /* Debug */,
124F6C751B0CDAE400C16385 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
/* End XCConfigurationList section */
};
rootObject = 124F6C451B0CDAE400C16385 /* Project object */;
}

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:HelloWorldApp.xcodeproj">
</FileRef>
</Workspace>

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "HelloWorldApp/AppDelegate.m"
timestampString = "453837074.323482"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "30"
endingLineNumber = "30"
landmarkName = "-resource_leak_bug"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "124F6C4C1B0CDAE400C16385"
BuildableName = "HelloWorldApp.app"
BlueprintName = "HelloWorldApp"
ReferencedContainer = "container:HelloWorldApp.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "124F6C651B0CDAE400C16385"
BuildableName = "HelloWorldAppTests.xctest"
BlueprintName = "HelloWorldAppTests"
ReferencedContainer = "container:HelloWorldApp.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "124F6C651B0CDAE400C16385"
BuildableName = "HelloWorldAppTests.xctest"
BlueprintName = "HelloWorldAppTests"
ReferencedContainer = "container:HelloWorldApp.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "124F6C4C1B0CDAE400C16385"
BuildableName = "HelloWorldApp.app"
BlueprintName = "HelloWorldApp"
ReferencedContainer = "container:HelloWorldApp.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "124F6C4C1B0CDAE400C16385"
BuildableName = "HelloWorldApp.app"
BlueprintName = "HelloWorldApp"
ReferencedContainer = "container:HelloWorldApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "124F6C4C1B0CDAE400C16385"
BuildableName = "HelloWorldApp.app"
BlueprintName = "HelloWorldApp"
ReferencedContainer = "container:HelloWorldApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>HelloWorldApp.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>124F6C4C1B0CDAE400C16385</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>124F6C651B0CDAE400C16385</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

@ -0,0 +1,17 @@
//
// AppDelegate.h
// HelloWorldApp
//
// Created by Dulma Rodriguez on 20/05/2015.
// Copyright (c) 2015 Dulma Rodriguez. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

@ -0,0 +1,78 @@
//
// AppDelegate.m
// HelloWorldApp
//
// Created by Dulma Rodriguez on 20/05/2015.
// Copyright (c) 2015 Dulma Rodriguez. All rights reserved.
//
#import "AppDelegate.h"
#import "Hello.h"
#import <UIKit/UIKit.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
-(void) memory_leak_bug {
CGPathRef shadowPath = CGPathCreateWithRect(self.inputView.bounds, NULL);
}
-(void) resource_leak_bug {
FILE *fp;
fp=fopen("c:\\test.txt", "r");
}
-(void) parameter_not_null_checked_block_bug:(void (^)())callback {
callback();
}
-(NSArray*) npe_in_array_literal_bug {
NSString *str = nil;
return @[@"horse", str, @"dolphin"];
}
-(NSArray*) premature_nil_termination_argument_bug {
NSString *str = nil;
return [NSArray arrayWithObjects: @"horse", str, @"dolphin", nil];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
Hello *hello = [Hello new];
[hello null_dereference_bug];
[self memory_leak_bug];
[self resource_leak_bug];
[hello parameter_not_null_checked_bug:nil];
[self parameter_not_null_checked_block_bug:nil];
[hello ivar_not_nullable_bug:nil];
[self npe_in_array_literal_bug];
[self premature_nil_termination_argument_bug];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Dulma Rodriguez. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="HelloWorldApp" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="140" width="441" height="43"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
</document>

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="vXZ-lx-hvc">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="ufC-wZ-h7g">
<objects>
<viewController id="vXZ-lx-hvc" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="jyV-Pf-zRb"/>
<viewControllerLayoutGuide type="bottom" id="2fi-mo-0CV"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="kh9-bI-dsS">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

@ -0,0 +1,24 @@
//
// Hello.h
// HelloWorldApp
//
// Created by Dulma Rodriguez on 20/05/2015.
// Copyright (c) 2015 Dulma Rodriguez. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Hello : NSObject
@property (strong) NSString* s;
@property (strong) Hello* hello;
-(Hello*) return_hello;
-(NSString*) null_dereference_bug;
-(NSString*) ivar_not_nullable_bug:(Hello*) hello;
-(NSString*) parameter_not_null_checked_bug:(Hello*) hello;
@end

@ -0,0 +1,33 @@
//
// Hello.m
// HelloWorldApp
//
// Created by Dulma Rodriguez on 20/05/2015.
// Copyright (c) 2015 Dulma Rodriguez. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Hello.h"
@implementation Hello
-(Hello*) return_hello {
return [Hello new];
}
-(NSString*) null_dereference_bug {
Hello *hello = nil;
return hello->_s;
}
-(NSString*) ivar_not_nullable_bug:(Hello*) hello {
Hello* ret_hello = [hello->_hello return_hello];
return ret_hello->_s;
}
-(NSString*) parameter_not_null_checked_bug:(Hello*) hello {
Hello *ret_hello = [hello return_hello];
return ret_hello->_s;
}
@end

@ -0,0 +1,38 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>com.facebook.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

@ -0,0 +1,15 @@
//
// ViewController.h
// HelloWorldApp
//
// Created by Dulma Rodriguez on 20/05/2015.
// Copyright (c) 2015 Dulma Rodriguez. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end

@ -0,0 +1,27 @@
//
// ViewController.m
// HelloWorldApp
//
// Created by Dulma Rodriguez on 20/05/2015.
// Copyright (c) 2015 Dulma Rodriguez. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end

@ -0,0 +1,16 @@
//
// main.m
// HelloWorldApp
//
// Created by Dulma Rodriguez on 20/05/2015.
// Copyright (c) 2015 Dulma Rodriguez. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

@ -0,0 +1,40 @@
//
// HelloWorldAppTests.m
// HelloWorldAppTests
//
// Created by Dulma Rodriguez on 20/05/2015.
// Copyright (c) 2015 Dulma Rodriguez. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
@interface HelloWorldAppTests : XCTestCase
@end
@implementation HelloWorldAppTests
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testExample {
// This is an example of a functional test case.
XCTAssert(YES, @"Pass");
}
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
// Put the code you want to measure the time of here.
}];
}
@end

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>com.facebook.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

@ -0,0 +1,4 @@
S src/**
B _build-infer/**
PKG sawja
PKG atdgen

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>EdgNative</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>Ocaml.ocamlMakefileBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>ocaml.ocamlnatureMakefile</nature>
</natures>
</projectDescription>

@ -0,0 +1,25 @@
SHELL := /bin/bash
CWD = $(shell pwd)
ANNOTATIONS = annotations
MODELS = models
SRCDIR = src
.PHONY: clean clang java models
all: clang java
java:
make -C $(SRCDIR) java
make -C $(MODELS) java
make -C $(ANNOTATIONS)
clang:
make -C $(SRCDIR) clang
make -C $(MODELS) clang
clean:
make -C $(SRCDIR) clean
make -C $(MODELS) clean
make -C $(ANNOTATIONS) clean

@ -0,0 +1,7 @@
prebuilt_jar(
name = 'annotations',
binary_jar = 'annotations.jar',
visibility = [
'PUBLIC',
]
)

@ -0,0 +1,13 @@
DEPENDENCIES = ../../dependencies
JSR_JAR = $(DEPENDENCIES)/java/jsr-305/jsr305.jar
CLASSES_OUT = classes
SOURCES = `find . -name "*.java"`
all:
mkdir -p classes
javac -cp $(JSR_JAR) $(SOURCES)
jar cvf annotations.jar $(SOURCES) `find . -name "*.class"`
clean:
rm -rvf `find . -name "*.class"`
rm -rvf annotations.jar

@ -0,0 +1,80 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.infer.annotation;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
public class Assertions {
public static <T> T assumeNotNull(@Nullable T object) {
return object;
}
public static <T> T assumeNotNull(@Nullable T object, String explanation) {
return object;
}
public static <T> T assertNotNull(@Nullable T object) {
if (object == null) {
throw new AssertionError();
}
return object;
}
public static <T> T assertNotNull(@Nullable T object, String explanation) {
if (object == null) {
throw new AssertionError(explanation);
}
return object;
}
public static <T> T getAssumingNotNull(List<T> list, int index) {
return list.get(index);
}
public static <T> T getAssertingNotNull(List<T> list, int index) {
assertCondition(0 <= index && index < list.size());
return assertNotNull(list.get(index));
}
public static <K, V> V getAssumingNotNull(Map<K, V> map, K key) {
return map.get(key);
}
public static <K, V> V getAssertingNotNull(Map<K, V> map, K key) {
assertCondition(map.containsKey(key));
return assertNotNull(map.get(key));
}
public static void assumeCondition(boolean condition) {
}
public static void assumeCondition(boolean condition, String explanation) {
}
public static void assertCondition(boolean condition) {
if (!condition) {
throw new AssertionError();
}
}
public static void assertCondition(boolean condition, String explanation) {
if (!condition) {
throw new AssertionError(explanation);
}
}
public static AssertionError assertUnreachable() {
throw new AssertionError();
}
public static AssertionError assertUnreachable(String explanation) {
throw new AssertionError(explanation);
}
public static AssertionError assertUnreachable(Exception exception) {
throw new AssertionError(exception);
}
}

@ -0,0 +1,19 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.infer.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* A method annotated with @Initializer should always be be called before the object is used.
* Users of the class and static checkers must enforce, and can rely on, this invariant.
* Examples include methods called indirectly by the constructor, protocols of init-then-use
* where some values are initialized after construction but before the first use,
* and builder classes where an object initialization must complete before build() is called.
*/
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface Initializer {}

@ -0,0 +1,12 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.infer.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface Mutable {}

@ -0,0 +1,18 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.infer.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* A class field, or method return/parameter type, of Optional type is annotated @Present
* to indicate that its value cannot be absent.
* Users of the method/field and static checkers must enforce, and can rely on, this invariant.
*/
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR,
ElementType.METHOD, ElementType.PARAMETER})
public @interface Present {}

@ -0,0 +1,21 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.infer.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target({
ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.METHOD,
ElementType.PACKAGE,
ElementType.TYPE,
})
public @interface Strict {
String value() default "";
}

@ -0,0 +1,12 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.infer.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SuppressFieldNotInitialized {}

@ -0,0 +1,12 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.infer.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SuppressFieldNotNullable {}

@ -0,0 +1,12 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.infer.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SuppressNullFieldAccess {}

@ -0,0 +1,12 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.infer.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SuppressNullMethodCall {}

@ -0,0 +1,12 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.infer.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SuppressParameterNotNullable {}

@ -0,0 +1,12 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.infer.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SuppressReturnOverAnnotated {}

@ -0,0 +1,19 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.infer.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target({
ElementType.CONSTRUCTOR,
ElementType.METHOD,
ElementType.PACKAGE,
ElementType.TYPE,
})
public @interface Verify {
}

@ -0,0 +1,531 @@
#!/usr/bin/env python
#
# Copyright (c) 2013-present Facebook. All rights reserved.
#
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import argparse
import csv
import io
import json
import logging
import multiprocessing
import os
import platform
import re
import shutil
import stat
import subprocess
import sys
import tempfile
import time
import traceback
import zipfile
# Infer imports
import inferlib
import utils
ANALYSIS_SUMMARY_OUTPUT = 'analysis_summary.txt'
BUCK_CONFIG = '.buckconfig.local'
BUCK_CONFIG_BACKUP = '.buckconfig.local.backup_generated_by_BuckAnalyze'
DEFAULT_BUCK_OUT = os.path.join(os.getcwd(), 'buck-out')
DEFAULT_BUCK_OUT_GEN = os.path.join(DEFAULT_BUCK_OUT, 'gen')
INFER_REPORT = os.path.join(utils.BUCK_INFER_OUT, utils.CSV_REPORT_FILENAME)
INFER_STATS = os.path.join(utils.BUCK_INFER_OUT, utils.STATS_FILENAME)
INFERJ_SCRIPT = """\
#!/bin/sh
{0} {1} javac $@
"""
LOCAL_CONFIG = """\
[tools]
javac = %s
"""
def prepare_build(args):
"""Creates script that redirects javac calls to inferJ and a local buck
configuration that tells buck to use that script.
"""
inferJ_options = [
'--buck',
'--analyzer',
args.analyzer,
]
if args.debug:
inferJ_options.append('--debug')
if args.analyzer_mode:
inferJ_options.append('--analyzer_mode')
inferJ_options.append(args.analyzer_mode)
# Create a temporary directory as a cache for jar files.
infer_cache_dir = os.path.join(args.infer_out, 'cache')
if not os.path.isdir(infer_cache_dir):
os.mkdir(infer_cache_dir)
inferJ_options.append('--infer_cache')
inferJ_options.append(infer_cache_dir)
temp_files = [infer_cache_dir]
try:
inferJ = utils.get_cmd_in_bin_dir('inferJ') + ' ' +\
' '.join(inferJ_options)
except subprocess.CalledProcessError as e:
logging.error('Could not find inferJ')
raise e
# Disable the use of buckd as this scripts modifies .buckconfig.local
logging.info('Disabling buckd: export NO_BUCKD=1')
os.environ['NO_BUCKD'] = '1'
# make sure INFER_ANALYSIS is set when buck is called
logging.info('Setup Infer analysis mode for Buck: export INFER_ANALYSIS=1')
os.environ['INFER_ANALYSIS'] = '1'
# Create a script to be called by buck
inferJ_script = None
with tempfile.NamedTemporaryFile(delete=False,
prefix='inferJ_',
suffix='.sh',
dir='.') as inferJ_script:
logging.info('Creating %s' % inferJ_script.name)
inferJ_script.file.write(
(INFERJ_SCRIPT.format(sys.executable, inferJ)).encode())
st = os.stat(inferJ_script.name)
os.chmod(inferJ_script.name, st.st_mode | stat.S_IEXEC)
# Backup and patch local buck config
patched_config = ''
if os.path.isfile(BUCK_CONFIG):
logging.info('Backing up %s to %s', BUCK_CONFIG, BUCK_CONFIG_BACKUP)
shutil.move(BUCK_CONFIG, BUCK_CONFIG_BACKUP)
with open(BUCK_CONFIG_BACKUP) as buckconfig:
patched_config = '\n'.join(buckconfig)
javac_section = '[tools]\n{0}javac = {1}'.format(
' ' * 4,
inferJ_script.name)
patched_config += javac_section
with open(BUCK_CONFIG, 'w') as buckconfig:
buckconfig.write(patched_config)
temp_files += [inferJ_script.name]
return temp_files
def java_targets():
target_types = [
'android_library',
'java_library',
]
try:
targets = subprocess.check_output([
'buck',
'targets',
'--type',
] + target_types).decode().strip().split('\n')
except subprocess.CalledProcessError as e:
logging.error('Could not compute java library targets')
raise e
return set(targets)
def is_alias(target):
return ':' not in target
def expand_target(target, java_targets):
if not is_alias(target):
return [target]
else:
try:
buck_audit_cmd = ['buck', 'audit', 'classpath', '--dot', target]
output = subprocess.check_output(buck_audit_cmd)
dotty = output.decode().split('\n')
except subprocess.CalledProcessError as e:
logging.error('Could not expand target {0}'.format(target))
raise e
targets = set()
edge_re = re.compile('.*"(.*)".*"(.*)".*')
for line in dotty:
match = re.match(edge_re, line)
if match:
for t in match.groups():
if t in java_targets:
targets.add(t)
return targets
def normalize_target(target):
if is_alias(target) or target.startswith('//'):
return target
else:
return '//' + target
def determine_library_targets(args):
""" Uses git and buck audit to expand aliases into the list of java or
android library targets that are parts of these aliases.
Buck targets directly passed as argument are not expanded """
args.targets = [normalize_target(t) for t in args.targets]
if any(map(is_alias, args.targets)):
all_java_targets = java_targets()
targets = set()
for t in args.targets:
targets.update(expand_target(t, all_java_targets))
args.targets = list(targets)
if args.verbose:
logging.debug('Targets to analyze:')
for target in args.targets:
logging.debug(target)
def init_stats(args, start_time):
"""Returns dictionary with target independent statistics.
"""
return {
'float': {},
'int': {
'cores': multiprocessing.cpu_count(),
'time': int(time.time()),
'start_time': int(round(start_time)),
},
'normal': {
'debug': str(args.debug),
'analyzer': args.analyzer,
'machine': platform.machine(),
'node': platform.node(),
'project': os.path.basename(os.getcwd()),
'revision': utils.vcs_revision(),
'branch': utils.vcs_branch(),
'system': platform.system(),
'infer_version': utils.infer_version(),
'infer_branch': utils.infer_branch(),
}
}
def store_performances_csv(infer_out, stats):
"""Stores the statistics about perfromances into a CSV file to be exported
to a database"""
perf_filename = os.path.join(infer_out, utils.CSV_PERF_FILENAME)
with open(perf_filename, 'w') as csv_file_out:
csv_writer = csv.writer(csv_file_out)
keys = ['infer_version', 'project', 'revision', 'files', 'lines',
'cores', 'system', 'machine', 'node', 'total_time',
'capture_time', 'analysis_time', 'reporting_time', 'time']
int_stats = list(stats['int'].items())
normal_stats = list(stats['normal'].items())
flat_stats = dict(int_stats + normal_stats)
values = []
for key in keys:
values.append(flat_stats[key])
csv_writer.writerow(keys)
csv_writer.writerow(values)
csv_file_out.flush()
def get_harness_code():
all_harness_code = '\nGenerated harness code:\n'
for filename in os.listdir(DEFAULT_BUCK_OUT_GEN):
if 'InferGeneratedHarness' in filename:
all_harness_code += '\n' + filename + ':\n'
with open(os.path.join(DEFAULT_BUCK_OUT_GEN,
filename), 'r') as file_in:
all_harness_code += file_in.read()
return all_harness_code + '\n'
def get_basic_stats(stats):
files_analyzed = '{0} files ({1} lines) analyzed in {2}s\n\n'.format(
stats['int']['files'],
stats['int']['lines'],
stats['int']['total_time'],
)
phase_times = 'Capture time: {0}s\nAnalysis time: {1}s\n\n'.format(
stats['int']['capture_time'],
stats['int']['analysis_time'],
)
to_skip = {
'files',
'lines',
'cores',
'time',
'start_time',
'capture_time',
'analysis_time',
'reporting_time',
'total_time',
}
bugs_found = 'Errors found:\n\n'
for key, value in sorted(stats['int'].items()):
if key not in to_skip:
bugs_found += ' {0:>8} {1}\n'.format(value, key)
basic_stats_message = files_analyzed + phase_times + bugs_found + '\n'
return basic_stats_message
def get_buck_stats():
trace_filename = os.path.join(
DEFAULT_BUCK_OUT,
'log',
'traces',
'build.trace'
)
ARGS = 'args'
SUCCESS_STATUS = 'success_type'
buck_stats = {}
try:
with open(trace_filename, 'r') as file_in:
trace = json.load(file_in)
for t in trace:
if SUCCESS_STATUS in t[ARGS]:
status = t[ARGS][SUCCESS_STATUS]
count = buck_stats.get(status, 0)
buck_stats[status] = count + 1
buck_stats_message = 'Buck build statistics:\n\n'
for key, value in sorted(buck_stats.items()):
buck_stats_message += ' {0:>8} {1}\n'.format(value, key)
return buck_stats_message
except IOError as e:
logging.error('Caught %s: %s' % (e.__class__.__name__, str(e)))
logging.error(traceback.format_exc())
return ''
class NotFoundInJar(Exception):
pass
def load_stats(opened_jar):
try:
return json.loads(opened_jar.read(INFER_STATS).decode())
except KeyError as e:
raise NotFoundInJar
def load_report(opened_jar):
try:
sio = io.StringIO(opened_jar.read(INFER_REPORT).decode())
return list(csv.reader(sio))
except KeyError as e:
raise NotFoundInJar
def rows_remove_duplicates(rows):
seen = {}
result = []
for row in rows:
t = tuple(row)
if t in seen:
continue
seen[t] = 1
result.append(row)
return result
def collect_results(args, start_time):
"""Walks through buck-gen, collects results for the different buck targets
and stores them in in args.infer_out/results.csv.
"""
buck_stats = get_buck_stats()
logging.info(buck_stats)
with open(os.path.join(args.infer_out, ANALYSIS_SUMMARY_OUTPUT), 'w') as f:
f.write(buck_stats)
all_rows = []
headers = []
stats = init_stats(args, start_time)
accumulation_whitelist = list(map(re.compile, [
'^cores$',
'^time$',
'^start_time$',
'.*_pc',
]))
expected_analyzer = stats['normal']['analyzer']
expected_version = stats['normal']['infer_version']
for root, _, files in os.walk(DEFAULT_BUCK_OUT_GEN):
for f in [f for f in files if f.endswith('.jar')]:
path = os.path.join(root, f)
try:
with zipfile.ZipFile(path) as jar:
# Accumulate integers and float values
target_stats = load_stats(jar)
found_analyzer = target_stats['normal']['analyzer']
found_version = target_stats['normal']['infer_version']
if (found_analyzer != expected_analyzer
or found_version != expected_version):
continue
else:
for type_k in ['int', 'float']:
items = target_stats.get(type_k, {}).items()
for key, value in items:
if not any(map(lambda r: r.match(key),
accumulation_whitelist)):
old_value = stats[type_k].get(key, 0)
stats[type_k][key] = old_value + value
rows = load_report(jar)
if len(rows) > 0:
headers.append(rows[0])
all_rows.extend(rows[1:])
# Override normals
stats['normal'].update(target_stats.get('normal', {}))
except NotFoundInJar:
pass
except zipfile.BadZipfile:
logging.warn('Bad zip file %s', path)
csv_report = os.path.join(args.infer_out, utils.CSV_REPORT_FILENAME)
bugs_out = os.path.join(args.infer_out, utils.BUGS_FILENAME)
if len(headers) == 0:
with open(csv_report, 'w'):
pass
logging.info('No reports found')
return
elif len(headers) > 1:
if any(map(lambda x: x != headers[0], headers)):
raise Exception('Inconsistent reports found')
# Convert all float values to integer values
for key, value in stats.get('float', {}).items():
stats['int'][key] = int(round(value))
# Delete the float entries before exporting the results
del(stats['float'])
with open(csv_report, 'w') as report:
writer = csv.writer(report)
writer.writerows([headers[0]] + rows_remove_duplicates(all_rows))
report.flush()
# export the CSV rows to JSON
utils.create_json_report(args.infer_out)
print('\n')
inferlib.print_errors(csv_report, bugs_out, args.analyzer)
stats['int']['total_time'] = int(round(utils.elapsed_time(start_time)))
store_performances_csv(args.infer_out, stats)
stats_filename = os.path.join(args.infer_out, utils.STATS_FILENAME)
with open(stats_filename, 'w') as stats_out:
json.dump(stats, stats_out)
basic_stats = get_basic_stats(stats)
if args.print_harness:
harness_code = get_harness_code()
basic_stats += harness_code
logging.info(basic_stats)
with open(os.path.join(args.infer_out, ANALYSIS_SUMMARY_OUTPUT), 'a') as f:
f.write(basic_stats)
def cleanup(temp_files):
"""Removes the generated .buckconfig.local and the temporary inferJ script.
"""
for file in [BUCK_CONFIG] + temp_files:
try:
logging.info('Removing %s' % file)
if os.path.isdir(file):
shutil.rmtree(file)
else:
os.unlink(file)
except IOError:
logging.error('Could not remove %s' % file)
if os.path.isfile(BUCK_CONFIG_BACKUP):
logging.info('Restoring %s', BUCK_CONFIG)
shutil.move(BUCK_CONFIG_BACKUP, BUCK_CONFIG)
if __name__ == '__main__':
parser = argparse.ArgumentParser(parents=[inferlib.base_parser])
parser.add_argument('--verbose', action='store_true',
help='Print buck compilation steps')
parser.add_argument('--no-cache', action='store_true',
help='Do not use buck distributed cache')
parser.add_argument('--print-harness', action='store_true',
help='Print generated harness code (Android only)')
parser.add_argument('targets', nargs='*', metavar='target',
help='Build targets to analyze')
args = parser.parse_args()
utils.configure_logging(args.verbose)
timer = utils.Timer(logging.info)
temp_files = []
try:
start_time = time.time()
logging.info('Starting the analysis')
subprocess.check_call(
[utils.get_cmd_in_bin_dir('InferAnalyze'), '-version'])
if not os.path.isdir(args.infer_out):
os.mkdir(args.infer_out)
timer.start('Preparing build...')
temp_files += prepare_build(args)
timer.stop('Build prepared')
# TODO(t3786463) Start buckd.
timer.start('Computing library targets')
determine_library_targets(args)
timer.stop('%d targets computed', len(args.targets))
timer.start('Running buck...')
buck_cmd = ['buck', 'build']
if args.no_cache:
buck_cmd += ['--no-cache']
if args.verbose:
buck_cmd += ['-v', '2']
subprocess.check_call(buck_cmd + args.targets)
timer.stop('Buck finished')
timer.start('Collecting results...')
collect_results(args, start_time)
timer.stop('Done')
except KeyboardInterrupt as e:
timer.stop('Exiting')
sys.exit(0)
except Exception as e:
timer.stop('Failed')
logging.error('Caught %s: %s' % (e.__class__.__name__, str(e)))
logging.error(traceback.format_exc())
sys.exit(1)
finally:
cleanup(temp_files)
# vim: set sw=4 ts=4 et:

@ -0,0 +1,137 @@
#!/usr/bin/env python
import argparse
import imp
import inferlib
import os
import sys
SCRIPT_FOLDER = os.path.dirname(__file__)
CAPTURE_PACKAGE = 'capture'
LIB_FOLDER = os.path.join(
os.path.dirname(__file__), os.path.pardir, 'lib')
# token that identifies the end of the options for infer and the beginning
# of the compilation command
CMD_MARKER = '--'
# insert here the correspondence between module name and the list of
# compiler/build-systems it handles.
# All supported commands should be listed here
MODULE_TO_COMMAND = {
'ant': ['ant'],
'analyze': ['analyze'],
'buck': ['buck'],
'gradle': ['gradle', 'gradlew'],
'javac': ['javac'],
'make': ['make', 'clang', 'clang++', 'cc', 'gcc', 'g++'],
'xcodebuild': ['xcodebuild'],
'mvn': ['mvn']
}
def get_commands():
"""Return all commands that are supported."""
#flatten and dedup the list of commands
return set(sum(MODULE_TO_COMMAND.values(), []))
def get_module_name(command):
""" Return module that is able to handle the command. None if
there is no such module."""
for module, commands in MODULE_TO_COMMAND.iteritems():
if command in commands:
return module
return None
def load_module(mod_name):
# load the 'capture' package in lib
pkg_info = imp.find_module(CAPTURE_PACKAGE, [LIB_FOLDER])
imported_pkg = imp.load_module(CAPTURE_PACKAGE, *pkg_info)
# load the requested module (e.g. make)
mod_file, mod_path, mod_descr = \
imp.find_module(mod_name, imported_pkg.__path__)
try:
return imp.load_module(
'{pkg}.{mod}'.format(pkg=imported_pkg.__name__, mod=mod_name),
mod_file, mod_path, mod_descr)
finally:
if mod_file:
mod_file.close()
def split_args_to_parse():
dd_index = \
sys.argv.index(CMD_MARKER) if CMD_MARKER in sys.argv else len(sys.argv)
return sys.argv[1:dd_index], sys.argv[dd_index + 1:]
def create_argparser(parents=[]):
parser = argparse.ArgumentParser(
parents=[inferlib.inferJ_parser] + parents,
add_help=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
group = parser.add_argument_group(
'supported compiler/build-system commands')
supported_commands = ', '.join(get_commands())
group.add_argument(
CMD_MARKER,
metavar='<cmd>',
dest='nullarg',
default=None,
help=('Command to run the compiler/build-system. '
'Supported build commands (run `infer --help -- <cmd_name>` for '
'extra help, e.g. `infer --help -- javac`): ' + supported_commands),
)
return parser
def main():
to_parse, cmd = split_args_to_parse()
# get the module name (if any), then load it
capture_module_name = os.path.basename(cmd[0]) if len(cmd) > 0 else None
mod_name = get_module_name(capture_module_name)
imported_module = None
if mod_name:
# There is module that supports the command
imported_module = load_module(mod_name)
# get the module's argparser and merge it with the global argparser
module_argparser = []
if imported_module:
module_argparser.append(
imported_module.create_argparser(capture_module_name)
)
global_argparser = create_argparser(module_argparser)
args = global_argparser.parse_args(to_parse)
if imported_module:
if capture_module_name != 'analyze' and not args.incremental:
inferlib.remove_infer_out(args.infer_out)
capture_exitcode = imported_module.gen_instance(args, cmd).capture()
if capture_exitcode != os.EX_OK:
exit(capture_exitcode)
elif capture_module_name is not None:
# There was a command, but it's not supported
print('Command "{cmd}" not recognised'.format(
cmd='' if capture_module_name is None else capture_module_name))
global_argparser.print_help()
sys.exit(1)
else:
global_argparser.print_help()
sys.exit(os.EX_OK)
if not (mod_name == 'buck' or mod_name == 'javac'):
# Something should be already captured, otherwise analysis would fail
if not os.path.exists(os.path.join(args.infer_out, 'captured')):
print('There was nothing to analyze, exiting')
exit(os.EX_USAGE)
analysis = inferlib.Infer(args, [])
analysis.analyze_and_report()
analysis.save_stats()
main()

@ -0,0 +1,28 @@
#!/usr/bin/env python
#
# Copyright (c) 2013- Facebook. All rights reserved.
#
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import logging
import sys
import inferlib
if __name__ == '__main__':
cmd_args = sys.argv[1:]
analysis = inferlib.Infer(inferlib.get_inferJ_args(cmd_args),
inferlib.get_javac_args(cmd_args))
stats = analysis.start()
if stats:
logging.info('Capture time: {0:.2f}s'.format(
stats['float']['capture_time']
))
logging.info('Analysis time: {0:.2f}s'.format(
stats['float']['analysis_time']
))

@ -0,0 +1,24 @@
#!/bin/bash -e
# Copyright (c) 2013 - Facebook.
# All rights reserved.
# This script takes a buck target and runs the respective tests.
# Arguments:
# $1 : buck target
# [$2] : "keep" or "replace". Keep will keep the temporary folders used in the tests.
# Replace will replace the saved dot files with the new created ones.
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $SCRIPT_DIR/../../
case $2 in
keep)
INFER_KEEP_FOLDER=Y buck test --no-results-cache $1 ;;
replace)
INFER_DOT_REPLACE=Y buck test --no-results-cache $1 ;;
*)
buck test --no-results-cache $1 ;;
esac

@ -0,0 +1,648 @@
#
# Copyright (c) 2013- Facebook. All rights reserved.
#
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import argparse
import csv
import glob
import json
import logging
import multiprocessing
import os
import re
import shutil
import subprocess
import sys
import tempfile
import time
import xml.etree.ElementTree as ET
# Increase the limit of the CSV parser to sys.maxlimit
csv.field_size_limit(sys.maxsize)
# Infer imports
import jwlib
import utils
# list of analysis options
INFER = 'infer'
ERADICATE = 'eradicate'
CHECKERS = 'checkers'
CAPTURE = 'capture'
COMPILE = 'compile'
TRACING = 'tracing'
MODES = [COMPILE, CAPTURE, INFER, ERADICATE, CHECKERS, TRACING]
INFER_ANALYZE_BINARY = "InferAnalyze"
class AbsolutePathAction(argparse.Action):
"""Convert a path from relative to absolute in the arg parser"""
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, os.path.abspath(values))
# https://github.com/python/cpython/blob/aa8ea3a6be22c92e774df90c6a6ee697915ca8ec/Lib/argparse.py
class VersionAction(argparse._VersionAction):
def __call__(self, parser, namespace, values, option_string=None):
# set self.version so that argparse version action knows it
self.version = self.get_infer_version()
super(VersionAction, self).__call__(parser,
namespace,
values,
option_string)
def get_infer_version(self):
try:
return subprocess.check_output([
utils.get_cmd_in_bin_dir(INFER_ANALYZE_BINARY), '-version'])
except:
print("Failed to run {0} binary, exiting".
format(INFER_ANALYZE_BINARY))
exit(2)
base_parser = argparse.ArgumentParser(add_help=False)
base_group = base_parser.add_argument_group('global arguments')
base_group.add_argument('-o', '--out', metavar='<directory>',
default=utils.DEFAULT_INFER_OUT, dest='infer_out',
action=AbsolutePathAction,
help='Set the INFER results directory')
base_group.add_argument('-i', '--incremental', action='store_true',
help='''Do not delete the results directory across
Infer runs''')
base_group.add_argument('-g', '--debug', action='store_true',
help='Generate extra debugging information')
base_group.add_argument('-a', '--analyzer',
help='Select the analyzer within: {0}'.format(
', '.join(MODES)),
default=INFER)
base_group.add_argument('-m', '--analyzer_mode', metavar='<analyzer_mode>',
help='''Select a special analyzer mode such as
graphql1 or graphql2''')
base_parser.add_argument('-v', '--version', help='Get version of the analyzer',
action=VersionAction)
inferJ_parser = argparse.ArgumentParser(parents=[base_parser])
inferJ_group = inferJ_parser.add_argument_group('backend arguments')
inferJ_group.add_argument('-j', '--multicore', metavar='n', type=int,
default=multiprocessing.cpu_count(),
dest='multicore', help='Set the number of cores to '
'be used for the analysis (default uses all cores)')
inferJ_group.add_argument('-x', '--project', metavar='<projectname>',
help='Project name, for recording purposes only')
inferJ_group.add_argument('-r', '--revision', metavar='<githash>',
help='The githash, for recording purposes only')
inferJ_group.add_argument('--buck', action='store_true', dest='buck',
help='To use when run with buck')
inferJ_group.add_argument('--infer_cache', metavar='<directory>',
help='Select a directory to contain the infer cache')
inferJ_group.add_argument('-pr', '--project_root',
dest='project_root',
default=os.getcwd(),
help='Location of the project root '
'(default is current directory)')
inferJ_group.add_argument('--objc_ml_buckets',
dest='objc_ml_buckets',
help='memory leak buckets to be checked, '
'separated by commas. The possible '
'buckets are cf (Core Foundation), '
'arc, narc (No arc)')
inferJ_group.add_argument('-nt', '--notest', action='store_true',
dest='notest',
help='Prints output of symbolic execution')
def detect_javac(args):
for index, arg in enumerate(args):
if arg == 'javac':
return index
def get_inferJ_args(args):
index = detect_javac(args)
if index is None:
cmd_args = args
else:
cmd_args = args[:index]
return inferJ_parser.parse_args(cmd_args)
def get_javac_args(args):
javac_args = args[detect_javac(args) + 1:]
if len(javac_args) == 0:
return None
else:
# replace any -g:.* flag with -g to preserve debugging symbols
return map(lambda arg: '-g' if '-g:' in arg else arg, javac_args)
def remove_infer_out(infer_out):
# it is safe to ignore errors here because recreating the infer_out
# directory will fail later
shutil.rmtree(infer_out, True)
def clean_infer_out(infer_out):
directories = ['multicore', 'classnames', 'sources']
extensions = ['.cfg', '.cg']
for root, dirs, files in os.walk(infer_out):
for d in dirs:
if d in directories:
path = os.path.join(root, d)
shutil.rmtree(path)
for f in files:
for ext in extensions:
if f.endswith(ext):
path = os.path.join(root, f)
os.remove(path)
def help_exit(message):
print(message)
inferJ_parser.print_usage()
exit(1)
def compare_rows(row_1, row_2):
filename_1 = row_1[utils.CSV_INDEX_FILENAME]
filename_2 = row_2[utils.CSV_INDEX_FILENAME]
if filename_1 < filename_2:
return -1
elif filename_1 > filename_2:
return 1
else:
line_1 = int(row_1[utils.CSV_INDEX_LINE])
line_2 = int(row_2[utils.CSV_INDEX_LINE])
return line_1 - line_2
def sort_csv(csv_report, infer_out):
collected_rows = []
with open(csv_report, 'r') as file_in:
reader = csv.reader(file_in)
rows = [row for row in reader]
if len(rows) <= 1:
return rows
else:
for row in rows[1:]:
filename = row[utils.CSV_INDEX_FILENAME]
if os.path.isfile(filename):
collected_rows.append(row)
collected_rows = sorted(
collected_rows,
cmp=compare_rows)
collected_rows = [rows[0]] + collected_rows
temporary_file = tempfile.mktemp()
with open(temporary_file, 'w') as file_out:
writer = csv.writer(file_out)
writer.writerows(collected_rows)
file_out.flush()
shutil.move(temporary_file, csv_report)
def should_print(analyzer, row):
error_kind = row[utils.CSV_INDEX_KIND]
error_type = row[utils.CSV_INDEX_TYPE]
error_bucket = '' # can be updated later once we extract it from qualifier
try:
qualifier_xml = ET.fromstring(row[utils.CSV_INDEX_QUALIFIER_TAGS])
if qualifier_xml.tag == utils.QUALIFIER_TAGS:
bucket = qualifier_xml.find(utils.BUCKET_TAGS)
if bucket is not None:
error_bucket = bucket.text
except ET.ParseError:
pass # this will skip any invalid xmls
# config what to print is listed below
error_kinds = ['ERROR', 'WARNING']
null_style_bugs = [
'NULL_DEREFERENCE',
'PARAMETER_NOT_NULL_CHECKED',
'IVAR_NOT_NULL_CHECKED',
'PREMATURE_NIL_TERMINATION_ARGUMENT',
]
null_style_buckets = ['B1', 'B2']
other_bugs = ['RESOURCE_LEAK', 'MEMORY_LEAK', 'RETAIN_CYCLE']
filter_by_type = True
if analyzer in [ERADICATE, CHECKERS]:
# report all issues for eredicate and checkers
filter_by_type = False
if error_kind not in error_kinds:
return False
if not filter_by_type:
return True
if not error_type:
return False
if error_type in null_style_bugs:
if error_bucket and error_bucket in null_style_buckets:
return True
else:
return False
elif error_type in other_bugs:
return True
else:
return False
def remove_bucket(bug_message):
""" Remove anything from the beginning if the message that
looks like a bucket """
return re.sub(r'(^\[[a-zA-Z0-9]*\])', '', bug_message, 1)
def print_and_write(file_out, message):
print(message)
file_out.write(message + '\n')
def print_errors(csv_report, bugs_out, analyzer):
with open(csv_report, 'r') as file_in:
reader = csv.reader(file_in)
reader.next() # first line is header, skip it
errors = filter(
lambda row: should_print(analyzer, row),
reader
)
with open(bugs_out, 'w') as file_out:
if not errors:
print_and_write(file_out, 'No issues found')
for row in errors:
filename = row[utils.CSV_INDEX_FILENAME]
if os.path.isfile(filename):
kind = row[utils.CSV_INDEX_KIND]
line = row[utils.CSV_INDEX_LINE]
error_type = row[utils.CSV_INDEX_TYPE]
msg = remove_bucket(row[utils.CSV_INDEX_QUALIFIER])
print_and_write(
file_out,
'{0}:{1}: {2}: {3}\n {4}\n'.format(
filename,
line,
kind.lower(),
error_type,
msg,
)
)
def run_command(cmd, debug_mode, javac_arguments, step, analyzer):
if debug_mode:
print('\n{0}\n'.format(' '.join(cmd)))
try:
return subprocess.check_call(cmd)
except subprocess.CalledProcessError as e:
error_msg = 'Failure during {0}, original command was\n\n{1}\n\n'
inferJ_cmd = ['inferJ', '-g', '-a', analyzer]
failing_cmd = inferJ_cmd + ['javac'] + javac_arguments
logging.error(error_msg.format(
step,
failing_cmd
))
raise e
class Infer:
def __init__(self, args, javac_args):
self.args = args
if self.args.analyzer not in MODES:
help_exit(
'Unknown analysis mode \"{0}\"'.format(self.args.analyzer)
)
utils.configure_logging(self.args.debug)
self.javac = jwlib.CompilerCall(javac_args)
if not self.javac.args.version:
if javac_args is None:
help_exit('No javac command detected')
if self.args.infer_out is None:
help_exit('Expect INFER results directory')
if self.args.buck:
self.args.infer_out = os.path.join(
self.javac.args.classes_out,
utils.BUCK_INFER_OUT)
self.args.infer_out = os.path.abspath(self.args.infer_out)
try:
os.mkdir(self.args.infer_out)
except OSError as e:
if not os.path.isdir(self.args.infer_out):
raise e
self.stats = {'int': {}, 'float': {}}
self.timing = {}
def clean_exit(self):
if os.path.isdir(self.args.infer_out):
print('removing', self.args.infer_out)
shutil.rmtree(self.args.infer_out)
exit(os.EX_OK)
def run_infer_frontend(self):
infer_cmd = [utils.get_cmd_in_bin_dir('InferJava')]
if self.args.buck:
infer_cmd += ['-project_root', os.getcwd()]
infer_cmd += [
'-results_dir', self.args.infer_out,
'-verbose_out', self.javac.verbose_out,
]
if os.path.isfile(utils.MODELS_JAR):
infer_cmd += ['-models', utils.MODELS_JAR]
infer_cmd.append('-no-static_final')
if self.args.debug:
infer_cmd.append('-debug')
if self.args.analyzer == TRACING:
infer_cmd.append('-tracing')
return run_command(
infer_cmd,
self.args.debug,
self.javac.original_arguments,
'frontend',
self.args.analyzer
)
def compile(self):
return self.javac.run()
def capture(self):
javac_status = self.compile()
if javac_status == os.EX_OK:
return self.run_infer_frontend()
else:
return javac_status
def analyze(self):
infer_analyze = [
utils.get_cmd_in_bin_dir(INFER_ANALYZE_BINARY),
'-results_dir',
self.args.infer_out
]
infer_options = []
# remove specs if possible so that old issues are less likely
# to be reported
infer_options += ['-allow_specs_cleanup']
if self.args.analyzer == ERADICATE:
infer_options += ['-checkers', '-eradicate']
elif self.args.analyzer == CHECKERS:
infer_options += ['-checkers']
else:
if self.args.analyzer == TRACING:
infer_options.append('-tracing')
if os.path.isfile(utils.MODELS_JAR):
infer_options += ['-models', utils.MODELS_JAR]
if self.args.analyzer_mode:
infer_options += ['-analyzer_mode', self.args.analyzer_mode]
if self.args.infer_cache:
infer_options += ['-infer_cache', self.args.infer_cache]
if self.args.objc_ml_buckets:
infer_options += ['-objc_ml_buckets', self.args.objc_ml_buckets]
if self.args.notest:
infer_options += ['-notest']
if self.args.debug:
infer_options += [
'-developer_mode',
'-html',
'-dotty',
'-print_types',
'-trace_error',
# '-notest',
]
exit_status = os.EX_OK
if self.args.buck:
infer_options += ['-project_root', os.getcwd(), '-java']
if self.javac.args.classpath is not None:
for path in self.javac.args.classpath.split(os.pathsep):
if os.path.isfile(path):
infer_options += ['-ziplib', os.path.abspath(path)]
elif self.args.project_root:
infer_options += ['-project_root', self.args.project_root]
if self.args.multicore == 1:
analyze_cmd = infer_analyze + infer_options
exit_status = run_command(
analyze_cmd,
self.args.debug,
self.javac.original_arguments,
'analysis',
self.args.analyzer
)
else:
if self.args.analyzer in [ERADICATE, CHECKERS]:
infer_analyze.append('-intraprocedural')
os.environ['INFER_OPTIONS'] = ' '.join(infer_options)
multicore_dir = os.path.join(self.args.infer_out, 'multicore')
pwd = os.getcwd()
if os.path.isdir(multicore_dir):
shutil.rmtree(multicore_dir)
os.mkdir(multicore_dir)
os.chdir(multicore_dir)
os.environ['INFER_DEVELOPER'] = 'Y'
analyze_cmd = infer_analyze + ['-makefile', 'Makefile']
analyze_cmd += infer_options
makefile_status = run_command(
analyze_cmd,
self.args.debug,
self.javac.original_arguments,
'create_makefile',
self.args.analyzer
)
exit_status += makefile_status
if makefile_status == os.EX_OK:
make_cmd = ['make', '-k', '-j', str(self.args.multicore)]
if not self.args.debug:
make_cmd += ['-s']
make_status = run_command(
make_cmd,
self.args.debug,
self.javac.original_arguments,
'run_makefile',
self.args.analyzer
)
os.chdir(pwd)
exit_status += make_status
if self.args.buck and exit_status == os.EX_OK:
clean_infer_out(self.args.infer_out)
cfgs = os.path.join(self.args.infer_out, 'captured', '*', '*.cfg')
captured_total = len(glob.glob(cfgs))
captured_plural = '' if captured_total <= 1 else 's'
print('\n%d file%s analyzed' % (captured_total, captured_plural))
return exit_status
def file_stats(self, file, stats):
if file is not None:
stats['files'] += 1
try:
with open(file, 'r') as f:
stats['lines'] += len(list(f))
except IOError:
logging.warning('File {} not found'.format(file))
def javac_stats(self):
stats = {'files': 0, 'lines': 0}
for arg in self.javac.original_arguments:
file = None
if arg.endswith('.java'):
file = arg
self.file_stats(file, stats)
if arg.startswith('@'):
with open(arg[1:], 'r') as f:
for line in f:
file = line.strip()
self.file_stats(file, stats)
return stats
def update_stats(self, csv_report):
with open(csv_report, 'r') as file_in:
reader = csv.reader(file_in)
rows = [row for row in reader][1:]
for row in rows:
key = row[utils.CSV_INDEX_TYPE]
previous_value = self.stats['int'].get(key, 0)
self.stats['int'][key] = previous_value + 1
def report_errors(self):
"""Report statistics about the computation and create a CSV file
containing the list or errors found during the analysis"""
csv_report = os.path.join(self.args.infer_out,
utils.CSV_REPORT_FILENAME)
bugs_out = os.path.join(self.args.infer_out,
utils.BUGS_FILENAME)
procs_report = os.path.join(self.args.infer_out, 'procs.csv')
infer_print_cmd = [utils.get_cmd_in_bin_dir('InferPrint')]
infer_print_options = [
'-q',
'-results_dir', self.args.infer_out,
'-bugs', csv_report,
'-procs', procs_report,
'-analyzer', self.args.analyzer
]
exit_status = subprocess.check_call(
infer_print_cmd + infer_print_options
)
if exit_status != os.EX_OK:
logging.error('Error with InferPrint with the command: '
+ infer_print_cmd)
else:
sort_csv(csv_report, self.args.infer_out)
self.update_stats(csv_report)
utils.create_json_report(self.args.infer_out)
print('\n')
if not self.args.buck:
print_errors(csv_report, bugs_out, self.args.analyzer)
return exit_status
def save_stats(self):
"""Print timing information to infer_out/stats.json"""
stats_path = os.path.join(self.args.infer_out, utils.STATS_FILENAME)
self.stats['int'].update(self.javac_stats())
self.stats['float'].update({
'capture_time': self.timing.get('capture', 0.0),
'analysis_time': self.timing.get('analysis', 0.0),
'reporting_time': self.timing.get('reporting', 0.0),
})
# Adding the analyzer and the version of Infer
self.stats['normal'] = {}
self.stats['normal']['analyzer'] = self.args.analyzer
self.stats['normal']['infer_version'] = utils.infer_version()
with open(stats_path, 'w') as stats_file:
json.dump(self.stats, stats_file)
def close(self):
if self.args.analyzer != COMPILE:
os.remove(self.javac.verbose_out)
def analyze_and_report(self):
if self.args.analyzer not in [COMPILE, CAPTURE]:
analysis_start_time = time.time()
if self.analyze() == os.EX_OK:
elapsed = utils.elapsed_time(analysis_start_time)
self.timing['analysis'] = elapsed
reporting_start_time = time.time()
self.report_errors()
elapsed = utils.elapsed_time(reporting_start_time)
self.timing['reporting'] = elapsed
def start(self):
if self.javac.args.version:
if self.args.buck:
key = self.args.analyzer
if self.args.analyzer_mode:
key += '_' + self.args.analyzer_mode
print(utils.infer_key(key), file=sys.stderr)
else:
return self.javac.run()
else:
start_time = time.time()
if self.capture() == os.EX_OK:
self.timing['capture'] = utils.elapsed_time(start_time)
self.analyze_and_report()
self.close()
elapsed = utils.elapsed_time(start_time)
self.timing['total'] = elapsed
self.save_stats()
return self.stats
else:
return dict({})
# vim: set sw=4 ts=4 et:

@ -0,0 +1,52 @@
# Copyright (c) 2009-2013 Monoidics ltd.
# Copyright (c) 2013- Facebook.
# All rights reserved.
import argparse
import logging
import tempfile
import os
import subprocess
# javac options
parser = argparse.ArgumentParser()
current_directory = os.getcwd()
parser.add_argument('-version', action='store_true')
parser.add_argument('-cp', '-classpath', type=str, dest='classpath')
parser.add_argument('-bootclasspath', type=str)
parser.add_argument('-d', dest='classes_out')
class CompilerCall:
def __init__(self, arguments):
self.original_arguments = arguments
self.args, _ = parser.parse_known_args(arguments)
self.verbose_out = None
def run(self):
if self.args.version:
return subprocess.call(['javac'] + self.original_arguments)
else:
javac_cmd = ['javac', '-verbose', '-g'] + self.original_arguments
with tempfile.NamedTemporaryFile(
mode='w',
suffix='.out',
prefix='javac_',
delete=False) as file_out:
self.verbose_out = file_out.name
try:
subprocess.check_call(javac_cmd, stderr=file_out)
return os.EX_OK
except subprocess.CalledProcessError as exc:
error_msg = 'Javac compilation error with: \n\n{}\n'
failing_cmd = [arg for arg in javac_cmd
if arg != '-verbose']
logging.error(error_msg.format(failing_cmd))
os.system(' '.join(failing_cmd))
return exc.returncode

@ -0,0 +1,345 @@
#
# Copyright (c) 2013- Facebook. All rights reserved.
#
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import csv
import fnmatch
import gzip
import json
import logging
import os
import subprocess
import sys
import tempfile
import time
BIN_DIRECTORY = os.path.dirname(os.path.realpath(__file__))
LIB_DIRECTORY = os.path.join(BIN_DIRECTORY, '..', 'lib', 'java')
TMP_DIRECTORY = tempfile.gettempdir()
MODELS_JAR = os.path.join(LIB_DIRECTORY, 'models.jar')
DEFAULT_INFER_OUT = os.path.join(os.getcwd(), 'infer-out')
CSV_PERF_FILENAME = 'performances.csv'
STATS_FILENAME = 'stats.json'
CSV_REPORT_FILENAME = 'report.csv'
JSON_REPORT_FILENAME = 'report.json'
BUGS_FILENAME = 'bugs.txt'
CSV_INDEX_KIND = 1
CSV_INDEX_TYPE = 2
CSV_INDEX_QUALIFIER = 3
CSV_INDEX_LINE = 5
CSV_INDEX_FILENAME = 8
CSV_INDEX_QUALIFIER_TAGS = 11
QUALIFIER_TAGS = 'qualifier_tags'
BUCKET_TAGS = 'bucket'
IOS_CAPTURE_ERRORS = 'errors'
IOS_BUILD_OUTPUT = 'build_output'
BUCK_INFER_OUT = 'infer'
FORMAT = '[%(levelname)s] %(message)s'
DEBUG_FORMAT = '[%(levelname)s:%(filename)s:%(lineno)03d] %(message)s'
# Monkey patching subprocess (I'm so sorry!).
if "check_output" not in dir(subprocess):
def f(*popenargs, **kwargs):
if 'stdout' in kwargs:
raise ValueError('stdout not supported')
process = subprocess.Popen(
stdout=subprocess.PIPE,
*popenargs,
**kwargs)
output, unused_err = process.communicate()
retcode = process.poll()
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
raise subprocess.CalledProcessError(retcode, cmd)
return output
subprocess.check_output = f
def configure_logging(debug, quiet=False):
"""Configures the default logger. This can be called only once and has to
be called before any logging is done.
"""
logging.TIMING = logging.ERROR + 5
logging.addLevelName(logging.TIMING, "TIMING")
def timing(msg, *args, **kwargs):
logging.log(logging.TIMING, msg, *args, **kwargs)
logging.timing = timing
if quiet:
logging.basicConfig(level=logging.TIMING, format=FORMAT)
elif not debug:
logging.basicConfig(level=logging.INFO, format=FORMAT)
else:
logging.basicConfig(level=logging.DEBUG, format=DEBUG_FORMAT)
def elapsed_time(start_time):
return time.time() - start_time
def error(msg):
print(msg, file=sys.stderr)
def get_cmd_in_bin_dir(binary_name):
# this relies on the fact that utils.py is located in infer/bin
return os.path.join(
os.path.dirname(os.path.realpath(__file__)),
binary_name)
def write_cmd_streams_to_file(logfile, cmd=None, out=None, err=None):
with open(logfile, 'w') as log_filedesc:
if cmd:
log_filedesc.write(' '.join(cmd) + '\n')
if err is not None:
errors = str(err)
log_filedesc.write('\nSTDERR:\n')
log_filedesc.write(errors)
if out is not None:
output = str(out)
log_filedesc.write('\n\nSTDOUT:\n')
log_filedesc.write(output)
def save_failed_command(
infer_out,
cmd,
message,
prefix='failed_',
out=None,
err=None):
cmd_filename = tempfile.mktemp(
'_' + message + ".txt",
prefix, infer_out
)
write_cmd_streams_to_file(cmd_filename, cmd=cmd, out=out, err=err)
logging.error('\n' + message + ' error saved in ' + cmd_filename)
def run_command(cmd, debug_mode, infer_out, message, env=os.environ):
if debug_mode:
print('\n{0}\n'.format(' '.join(cmd)))
try:
return subprocess.check_call(cmd, env=env)
except subprocess.CalledProcessError as e:
save_failed_command(infer_out, cmd, message)
raise e
def print_exit(s):
print(s)
exit(os.EX_OK)
def infer_version():
version = json.loads(subprocess.check_output([
get_cmd_in_bin_dir('InferAnalyze'),
'-version_json',
]).decode())
return version['commit']
def infer_branch():
version = json.loads(subprocess.check_output([
get_cmd_in_bin_dir('InferAnalyze'),
'-version_json',
]).decode())
return version['branch']
def infer_key(analyzer):
return os.pathsep.join([analyzer, infer_version()])
def vcs_branch(dir='.'):
cwd = os.getcwd()
try:
os.chdir(dir)
branch = subprocess.check_output([
'git',
'rev-parse',
'--abbrev-ref',
'HEAD',
]).decode().strip()
except subprocess.CalledProcessError:
try:
branch = subprocess.check_output([
'hg',
'id',
'-B',
]).decode().strip()
except subprocess.CalledProcessError:
branch = 'not-versioned'
finally:
os.chdir(cwd)
return branch
def vcs_revision(dir='.'):
cwd = os.getcwd()
try:
os.chdir(dir)
revision = subprocess.check_output([
'git',
'rev-parse',
'HEAD',
]).decode().strip()
except subprocess.CalledProcessError:
try:
revision = subprocess.check_output([
'hg',
'id',
'-i',
]).decode().strip()
except subprocess.CalledProcessError:
revision = 'not-versioned'
finally:
os.chdir(cwd)
return revision
class Timer:
"""Simple logging timer. Initialize with a printf like logging function."""
def __init__(self, logger=lambda x: None):
self._logger = logger
self._start = 0
def start(self, message=None, *args):
self._start = time.time()
if message:
self._logger(message, *args)
def stop(self, message=None, *args):
self._stop = time.time()
self._dt = self._stop - self._start
if message:
self._logger(message + ' (%.2fs)', *(args + (self._dt,)))
return self._dt
def interact():
"""Start interactive mode. Useful for debugging.
"""
import code
code.interact(local=locals())
def search_files(root_dir, extension):
# Input:
# - root directory where to start a recursive search of yjson files
# - file extension to search from the root
# Output:
# - list of absolute filepaths
files = []
if not os.path.isabs(root_dir):
root_dir = os.path.abspath(root_dir)
for dirpath, _, filenames in os.walk(root_dir):
for filename in fnmatch.filter(filenames, "*" + extension):
files.append(os.path.join(dirpath, filename))
return files
def uncompress_gzip_file(gzip_file, out_dir):
# This is python2.6 compliant, gzip.open doesn't support 'with' statement
# Input:
# - gzip file path
# - output directory where uncompress the file
# Output:
# - path of the uncompressed file
# NOTE: the file is permanently created, is responsibility of the
# caller to delete it
uncompressed_path = None
uncompressed_fd = None
compressed_fd = None
try:
# the uncompressed filename loses its final extension
# (for example abc.gz -> abc)
uncompressed_path = os.path.join(
out_dir,
os.path.splitext(gzip_file)[0],
)
uncompressed_fd = open(uncompressed_path, 'wb')
compressed_fd = gzip.open(gzip_file, 'rb')
uncompressed_fd.write(compressed_fd.read())
return uncompressed_path
except IOError as exc:
# delete the uncompressed file (if exists)
if uncompressed_path is not None and os.path.exists(uncompressed_path):
os.remove(uncompressed_path)
raise exc
finally:
if compressed_fd is not None:
compressed_fd.close()
if uncompressed_fd is not None:
uncompressed_fd.close()
def run_process(cmd, cwd=None, logfile=None):
# Input:
# - command to execute
# - current working directory to cd before running the cmd
# - logfile where to dump stdout/stderr
# Output:
# - exitcode of the executed process
p = subprocess.Popen(
cmd,
cwd=cwd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(out, err) = p.communicate()
if logfile:
write_cmd_streams_to_file(logfile, cmd=cmd, out=out, err=err)
return p.returncode
def invoke_function_with_callbacks(
func,
args,
on_terminate=None,
on_exception=None):
try:
res = func(*args)
if on_terminate:
on_terminate(res)
return res
except Exception as exc:
if on_exception:
return on_exception(exc)
raise
def create_json_report(out_dir):
csv_report_filename = os.path.join(out_dir, CSV_REPORT_FILENAME)
json_report_filename = os.path.join(out_dir, JSON_REPORT_FILENAME)
rows = []
with open(csv_report_filename, 'r') as file_in:
reader = csv.reader(file_in)
rows = [row for row in reader]
with open(json_report_filename, 'w') as file_out:
headers = rows[0]
issues = rows[1:]
json.dump([dict(zip(headers, row)) for row in issues], file_out)
# vim: set sw=4 ts=4 et:

@ -0,0 +1,24 @@
import os
import util
MODULE_NAME = __name__
MODULE_DESCRIPTION = '''Run analysis of what has already been captured:
Usage:
infer -- analyze
infer --out <capture_folder> -- analyze'''
def gen_instance(*args):
return NoCapture(*args)
# This creates an empty argparser for the module, which provides only
# description/usage information and no arguments.
create_argparser = util.base_argparser(MODULE_DESCRIPTION, MODULE_NAME)
class NoCapture:
def __init__(self, args, cmd):
self.args = args
def capture(self):
return os.EX_OK

@ -0,0 +1,69 @@
import os
import util
MODULE_NAME = __name__
MODULE_DESCRIPTION = '''Run analysis of code built with a command like:
ant [options] [target]
Analysis examples:
infer -- ant compile'''
def gen_instance(*args):
return AntCapture(*args)
# This creates an empty argparser for the module, which provides only
# description/usage information and no arguments.
create_argparser = util.base_argparser(MODULE_DESCRIPTION, MODULE_NAME)
class AntCapture:
def __init__(self, args, cmd):
self.args = args
# TODO: make the extraction of targets smarter
self.build_cmd = ['ant', '-verbose'] + cmd[1:]
def is_interesting(self, content):
return self.is_quoted(content) or content.endswith('.java')
def is_quoted(self, argument):
quote = '\''
return len(argument) > 2 and argument[0] == quote\
and argument[-1] == quote
def remove_quotes(self, argument):
if self.is_quoted(argument):
return argument[1:-1]
else:
return argument
def get_inferJ_commands(self, verbose_output):
javac_pattern = '[javac]'
argument_start_pattern = 'Compilation arguments'
calls = []
javac_arguments = []
collect = False
for line in verbose_output:
if javac_pattern in line:
if argument_start_pattern in line:
collect = True
if javac_arguments != []:
capture = util.create_inferJ_command(self.args,
javac_arguments)
calls.append(capture)
javac_arguments = []
if collect:
pos = line.index(javac_pattern) + len(javac_pattern)
content = line[pos:].strip()
if self.is_interesting(content):
arg = self.remove_quotes(content)
javac_arguments.append(arg)
if javac_arguments != []:
capture = util.create_inferJ_command(self.args, javac_arguments)
calls.append(capture)
javac_arguments = []
return calls
def capture(self):
cmds = self.get_inferJ_commands(util.get_build_output(self.build_cmd))
return util.run_commands(cmds)

@ -0,0 +1,42 @@
import os
import subprocess
import traceback
import util
import utils # this is module located in ../utils.py
MODULE_NAME = __name__
MODULE_DESCRIPTION = '''Run analysis of code built with a command like:
buck [options] [target]
Analysis examples:
infer -- buck build HelloWorld'''
def gen_instance(*args):
return BuckAnalyzer(*args)
# This creates an empty argparser for the module, which provides only
# description/usage information and no arguments.
create_argparser = util.base_argparser(MODULE_DESCRIPTION, MODULE_NAME)
class BuckAnalyzer:
def __init__(self, args, cmd):
self.args = args
self.cmd = cmd[2:] # TODO: make the extraction of targets smarter
def capture(self):
# BuckAnalyze is a special case, and we run the analysis from here
capture_cmd = [utils.get_cmd_in_bin_dir('BuckAnalyze')]
if self.args.debug:
capture_cmd.append('-g')
capture_cmd += self.cmd
capture_cmd += ['--analyzer', self.args.analyzer]
try:
subprocess.check_call(capture_cmd)
return os.EX_OK
except subprocess.CalledProcessError as exc:
if self.args.debug:
traceback.print_exc()
return exc.returncode

@ -0,0 +1,19 @@
#!/bin/bash
SCRIPT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ "${0%++}" != "$0" ]; then XX="++"; else XX=""; fi
export FCP_CLANG_COMPILER="${SCRIPT_PATH%/}/../clang/clang_wrapper$XX";
export FCP_RESULTS_DIR="${INFER_RESULTS_DIR}";
export FCP_USE_STD_CLANG_CMD="1";
if [ -z $INFER_RESULTS_DIR ]; then
# this redirects to the compiler without adding any FCP flag
# this is because xcode requires message category info from the compiler
# and invokes it without any env var set.
"$FCP_CLANG_COMPILER" "$@"
exit $?
fi
"${SCRIPT_PATH%/}/../clang/clang_general_wrapper$XX" "$@"

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save