Remove support for SuppressWarnings annotations

Summary:
SuppressWarnings annotations are hardly used and add considerable
complexity due to requiring recompilation with an annotation processor.

Reviewed By: jvillard

Differential Revision: D4312193

fbshipit-source-id: c4fc07e
master
Josh Berdine 8 years ago committed by Facebook Github Bot
parent 00f3c4227b
commit 3dfaa9ed7b

1
.gitignore vendored

@ -124,7 +124,6 @@ buck-out/
/infer/annotations/annot_classes/ /infer/annotations/annot_classes/
/infer/annotations/annotations.jar /infer/annotations/annotations.jar
/infer/annotations/processor_classes/ /infer/annotations/processor_classes/
/infer/lib/java/processor.jar
infer/src/.project infer/src/.project
/dependencies/ocamldot/ocamldot /dependencies/ocamldot/ocamldot
/dependencies/ocamldot/ocamldot.ml /dependencies/ocamldot/ocamldot.ml

@ -9,6 +9,7 @@
package infer.other; package infer.other;
import android.annotation.SuppressLint;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarActivity;
import android.os.Bundle; import android.os.Bundle;
@ -23,7 +24,7 @@ public class MainActivity extends ActionBarActivity {
source().toString(); source().toString();
} }
@SuppressWarnings("infer") @SuppressLint("NULL_DEREFERENCE")
void shouldNotBeReported() { void shouldNotBeReported() {
source().toString(); source().toString();
} }

@ -16,23 +16,15 @@ ANNOT_CLASSES = 'annot_classes'
PROCESSOR_CLASSES = 'processor_classes' PROCESSOR_CLASSES = 'processor_classes'
ANNOTATIONS_JAR = $(CWD)/annotations.jar ANNOTATIONS_JAR = $(CWD)/annotations.jar
PROCESSOR_JAR = $(JAVA_LIB_DIR)/processor.jar
all: $(ANNOTATIONS_JAR) $(PROCESSOR_JAR) all: $(ANNOTATIONS_JAR)
$(ANNOTATIONS_JAR): $(ANNOT_SOURCES) $(ANNOTATIONS_JAR): $(ANNOT_SOURCES)
mkdir -p $(ANNOT_CLASSES) mkdir -p $(ANNOT_CLASSES)
javac -cp $(JSR_JAR) $(ANNOT_SOURCES) -d $(ANNOT_CLASSES) javac -cp $(JSR_JAR) $(ANNOT_SOURCES) -d $(ANNOT_CLASSES)
cd $(ANNOT_CLASSES) && jar cvf $(ANNOTATIONS_JAR) com cd $(ANNOT_CLASSES) && jar cvf $(ANNOTATIONS_JAR) com
$(PROCESSOR_JAR): $(PROCESSOR_SOURCES)
mkdir -p $(PROCESSOR_CLASSES)
javac $(PROCESSOR_SOURCES) -cp .:$(JAVA_HOME)/lib/tools.jar -d $(PROCESSOR_CLASSES)
jar cvMf processor.jar -C resources META-INF -C $(PROCESSOR_CLASSES) com
mv processor.jar $(PROCESSOR_JAR)
clean: clean:
@rm -rf $(ANNOT_CLASSES) @rm -rf $(ANNOT_CLASSES)
@rm -f $(ANNOTATIONS_JAR) @rm -f $(ANNOTATIONS_JAR)
@rm -rf $(PROCESSOR_CLASSES) @rm -rf $(PROCESSOR_CLASSES)
@rm -f $(PROCESSOR_JAR)

@ -1,123 +0,0 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.infer.annotprocess;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
@SupportedOptions({ "SuppressWarningsOutputFilename" })
@SupportedAnnotationTypes({ "java.lang.SuppressWarnings" })
public class CollectSuppressWarnings extends AbstractProcessor {
private static final String OUTPUT_FILENAME_OPTION = "SuppressWarningsOutputFilename";
// map of (classes -> methods in class). an empty set means suppress all warnings on class
public Map<String, Set<String>> mSuppressMap = new LinkedHashMap<String, Set<String>>();
// total number of classes/methods with a SuppressWarnings annotation
private int mNumToSuppress = 0;
// write the methods/classes to suppress to .inferconfig-style JSON
private void exportSuppressMap() throws IOException {
Map<String, String> options = processingEnv.getOptions();
String mOutputFilename =
Preconditions.checkNotNull(options.get(OUTPUT_FILENAME_OPTION),
"The filename should be passed from the Infer top-level script");
// output .inferconfig format file in JSON
try (PrintWriter out = new PrintWriter(mOutputFilename)) {
int elemCount = 0;
out.println("{ \"suppress_warnings\": [");
for (Map.Entry<String, Set<String>> entry : mSuppressMap.entrySet()) {
String clazz = entry.getKey();
Set<String> methods = entry.getValue();
if (methods.isEmpty()) { // empty set of methods means annotation is on class
JSONOutputUtils.outputClass(out, clazz, ++elemCount, mNumToSuppress);
} else {
for (String method : methods) {
JSONOutputUtils.outputMethod(out, clazz, method, ++elemCount, mNumToSuppress);
}
}
}
out.println("] }");
}
}
// we only care about @SuppressWarnings("null") and @SuppressWarnings("infer"); ignore otherwise
private boolean shouldProcess(SuppressWarnings annot) {
for (String value : annot.value()) {
if (value.equals("null") || value.equals("infer")) return true;
}
return false;
}
// collect all of the SuppressWarnings annotations from the Java source files being compiled
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Elements elements = processingEnv.getElementUtils();
for (TypeElement te : annotations) {
for (Element e : roundEnv.getElementsAnnotatedWith(te)) {
SuppressWarnings annot = e.getAnnotation(SuppressWarnings.class);
if (annot != null && shouldProcess(annot)) {
if (e instanceof TypeElement) { // class
String className = elements.getBinaryName((TypeElement) e).toString();
mSuppressMap.put(className, Collections.EMPTY_SET);
mNumToSuppress++;
} else if (e instanceof ExecutableElement) { // method
String classname = e.getEnclosingElement().toString();
java.util.Set<String> suppressMethods = mSuppressMap.get(classname);
if (suppressMethods != null && suppressMethods.isEmpty()) {
// empty set means suppress warnings on all methods in class; do nothing
continue;
}
if (suppressMethods == null) {
suppressMethods = new LinkedHashSet<String>();
}
suppressMethods.add(e.getSimpleName().toString());
mSuppressMap.put(classname, suppressMethods);
mNumToSuppress++;
}
}
}
}
if (roundEnv.processingOver() && mNumToSuppress > 0) {
try {
exportSuppressMap();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return false;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
}

@ -1 +0,0 @@
com.facebook.infer.annotprocess.CollectSuppressWarnings

@ -34,9 +34,6 @@ LIB_DIRECTORY = os.path.join(INFER_INFER_DIRECTORY, 'lib')
BIN_DIRECTORY = os.path.join(INFER_INFER_DIRECTORY, 'bin') BIN_DIRECTORY = os.path.join(INFER_INFER_DIRECTORY, 'bin')
JAVA_LIB_DIRECTORY = os.path.join(LIB_DIRECTORY, 'java') JAVA_LIB_DIRECTORY = os.path.join(LIB_DIRECTORY, 'java')
MODELS_JAR = os.path.join(JAVA_LIB_DIRECTORY, 'models.jar') MODELS_JAR = os.path.join(JAVA_LIB_DIRECTORY, 'models.jar')
ANNOT_PROCESSOR_JAR = os.path.join(JAVA_LIB_DIRECTORY, 'processor.jar')
ANNOT_PROCESSOR_NAMES = \
'com.facebook.infer.annotprocess.CollectSuppressWarnings'
WRAPPERS_DIRECTORY = os.path.join(LIB_DIRECTORY, 'wrappers') WRAPPERS_DIRECTORY = os.path.join(LIB_DIRECTORY, 'wrappers')
XCODE_WRAPPERS_DIRECTORY = os.path.join(LIB_DIRECTORY, 'xcode_wrappers') XCODE_WRAPPERS_DIRECTORY = os.path.join(LIB_DIRECTORY, 'xcode_wrappers')
@ -58,8 +55,6 @@ LOG_FILE = 'toplevel.log'
BUCK_INFER_OUT = 'infer' BUCK_INFER_OUT = 'infer'
SUPRESS_WARNINGS_OUTPUT_FILENAME_OPTION = 'SuppressWarningsOutputFilename'
# list of possible analyzers # list of possible analyzers
ANALYZER_INFER = 'infer' ANALYZER_INFER = 'infer'

@ -26,11 +26,7 @@ parser = argparse.ArgumentParser()
current_directory = utils.decode(os.getcwd()) current_directory = utils.decode(os.getcwd())
parser.add_argument('-version', action='store_true') parser.add_argument('-version', action='store_true')
parser.add_argument('-cp', '-classpath', type=utils.decode,
dest='classpath', default=os.getcwd())
parser.add_argument('-d', dest='classes_out', default=current_directory) parser.add_argument('-d', dest='classes_out', default=current_directory)
parser.add_argument('-processorpath', type=utils.decode, dest='processorpath')
parser.add_argument('-processor', type=utils.decode, dest='processor')
def _get_javac_args(args): def _get_javac_args(args):
@ -62,26 +58,6 @@ def create_infer_command(args, javac_arguments):
) )
# return True if string is empty or an escaped variant of empty
def _is_empty_classpath(string):
stripped = string.strip("'").strip('"')
if stripped == '':
return True
elif stripped == string:
return False
else:
return _is_empty_classpath(stripped)
class AnnotationProcessorNotFound(Exception):
def __init__(self, path):
self.path = path
def __str__(self):
return repr(self.path + ' not found')
class CompilerCall(object): class CompilerCall(object):
def __init__(self, javac_cmd, arguments): def __init__(self, javac_cmd, arguments):
@ -103,85 +79,11 @@ class CompilerCall(object):
else: else:
javac_args = ['-verbose', '-g'] javac_args = ['-verbose', '-g']
if not os.path.isfile(config.ANNOT_PROCESSOR_JAR):
raise AnnotationProcessorNotFound(config.ANNOT_PROCESSOR_JAR)
if self.args.classes_out is not None: if self.args.classes_out is not None:
javac_args += ['-d', self.args.classes_out] javac_args += ['-d', self.args.classes_out]
classpath = self.args.classpath
# the -processorpath option precludes searching the classpath for
# annotation processors, so we don't want to use it unless the
# javac command does
if self.args.processorpath is not None:
processorpath = os.pathsep.join([config.ANNOT_PROCESSOR_JAR,
self.args.processorpath])
javac_args += ['-processorpath', processorpath]
else:
classpath = os.pathsep.join([config.ANNOT_PROCESSOR_JAR,
classpath])
at_args = [
arg for arg in self.remaining_args if arg.startswith('@')]
found_classpath = False
for at_arg in at_args:
# remove @ character
args_file_name = at_arg[1:]
with codecs.open(args_file_name, 'r',
encoding=config.CODESET) as args_file:
args_file_contents = args_file.read()
prefix_suffix = args_file_contents.split('-classpath\n', 1)
if len(prefix_suffix) == 2:
prefix, suffix = prefix_suffix
with tempfile.NamedTemporaryFile(
dir=self.args.infer_out,
suffix='_cp',
delete=False) as args_file_cp:
cp_line, _, after_cp = suffix.partition('\n')
# avoid errors the happen when we get -classpath '"',
# -classpath '', or similar from the args file
if _is_empty_classpath(cp_line):
cp_line = '\n'
else:
cp_line = ':{}\n'.format(cp_line)
cp_line = prefix + '-classpath\n' + classpath + cp_line
cp_line += after_cp
args_file_cp.write(cp_line)
at_arg_cp = '@' + args_file_cp.name
self.remaining_args = [
at_arg_cp if arg == at_arg else arg
for arg in self.remaining_args]
found_classpath = True
break
javac_args += self.remaining_args javac_args += self.remaining_args
if not found_classpath:
# -classpath option not found in any args file
javac_args += ['-classpath', classpath]
# this overrides the default mechanism for discovering annotation
# processors (checking the manifest of the annotation processor
# JAR), so we don't want to use it unless the javac command does
if self.args.processor is not None:
processor = '{infer_processors},{original_processors}'.format(
infer_processors=config.ANNOT_PROCESSOR_NAMES,
original_processors=self.args.processor
)
javac_args += ['-processor', processor]
with tempfile.NamedTemporaryFile(
mode='w',
suffix='.out',
prefix='annotations_',
delete=False) as annot_out:
# Initialize the contents of the file to a valid empty
# json object.
annot_out.write('{}')
self.suppress_warnings_out = annot_out.name
javac_args += ['-A%s=%s' %
(config.SUPRESS_WARNINGS_OUTPUT_FILENAME_OPTION,
self.suppress_warnings_out)]
def arg_must_go_on_cli(arg): def arg_must_go_on_cli(arg):
# as mandated by javac, argument files must not contain # as mandated by javac, argument files must not contain
# arguments # arguments
@ -281,7 +183,6 @@ class AnalyzerWithFrontendWrapper(analyze.AnalyzerWrapper):
infer_cmd += [ infer_cmd += [
'-verbose_out', self.javac.verbose_out, '-verbose_out', self.javac.verbose_out,
'-suppress_warnings_out', self.javac.suppress_warnings_out,
] ]
if self.args.debug: if self.args.debug:
@ -304,7 +205,6 @@ class AnalyzerWithFrontendWrapper(analyze.AnalyzerWrapper):
def _close(self): def _close(self):
os.remove(self.javac.verbose_out) os.remove(self.javac.verbose_out)
os.remove(self.javac.suppress_warnings_out)
class AnalyzerWithJavac(AnalyzerWithFrontendWrapper): class AnalyzerWithJavac(AnalyzerWithFrontendWrapper):

@ -310,33 +310,6 @@ let never_return_null_matcher =
let skip_translation_matcher = let skip_translation_matcher =
FileOrProcMatcher.load_matcher (patterns_of_json_with_key Config.patterns_skip_translation) FileOrProcMatcher.load_matcher (patterns_of_json_with_key Config.patterns_skip_translation)
let suppress_warnings_matcher =
let error msg =
F.eprintf
"There was an issue reading the option %s.@\n\
If you did not call %s directly, this is likely a bug in Infer.@\n\
%s@."
Config.suppress_warnings_annotations_long
(Filename.basename Sys.executable_name)
msg ;
[] in
let patterns =
match Config.suppress_warnings_out with
| Some path -> (
match Utils.read_optional_json_file path with
| Ok json -> (
let json_key = "suppress_warnings" in
match Yojson.Basic.Util.member json_key json with
| `Null -> []
| json -> patterns_of_json_with_key (json_key, json))
| Error msg -> error ("Could not read or parse the supplied " ^ path ^ ":\n" ^ msg)
)
| None when Config.current_exe <> CLOpt.Java -> []
| None when Option.is_some Config.generated_classes -> []
| None ->
error ("The option " ^ Config.suppress_warnings_annotations_long ^ " was not provided") in
FileOrProcMatcher.load_matcher patterns
let load_filters analyzer = let load_filters analyzer =
{ {
whitelist = Config.analysis_path_regex_whitelist analyzer; whitelist = Config.analysis_path_regex_whitelist analyzer;

@ -32,7 +32,6 @@ val do_not_filter : filters
val create_filters : Config.analyzer -> filters val create_filters : Config.analyzer -> filters
val never_return_null_matcher : SourceFile.t -> Procname.t -> bool val never_return_null_matcher : SourceFile.t -> Procname.t -> bool
val suppress_warnings_matcher : SourceFile.t -> Procname.t -> bool
val skip_translation_matcher : SourceFile.t -> Procname.t -> bool val skip_translation_matcher : SourceFile.t -> Procname.t -> bool
val modeled_expensive_matcher : (string -> bool) -> Procname.t -> bool val modeled_expensive_matcher : (string -> bool) -> Procname.t -> bool

@ -52,14 +52,14 @@ let log_issue
?session ?session
?ltr ?ltr
exn = exn =
let should_suppress_warnings summary = let should_suppress_lint summary =
!Config.curr_language = Config.Java && !Config.curr_language = Config.Java &&
let annotated_signature = let annotated_signature =
Annotations.get_annotated_signature summary.Specs.attributes in Annotations.get_annotated_signature summary.Specs.attributes in
let ret_annotation, _ = annotated_signature.Annotations.ret in let ret_annotation, _ = annotated_signature.Annotations.ret in
Annotations.ia_is_suppress_warnings ret_annotation in Annotations.ia_is_suppress_lint ret_annotation in
match Specs.get_summary proc_name with match Specs.get_summary proc_name with
| Some summary when should_suppress_warnings summary -> () | Some summary when should_suppress_lint summary -> ()
| Some summary -> | Some summary ->
let err_log = summary.Specs.attributes.ProcAttributes.err_log in let err_log = summary.Specs.attributes.ProcAttributes.err_log in
log_issue_from_errlog err_kind err_log ?loc ?node_id ?session ?ltr exn log_issue_from_errlog err_kind err_log ?loc ?node_id ?session ?ltr exn

@ -183,8 +183,6 @@ let specs_files_suffix = ".specs"
let start_filename = ".start" let start_filename = ".start"
let suppress_warnings_annotations_long = "suppress-warnings-annotations"
(** If true performs taint analysis *) (** If true performs taint analysis *)
let taint_analysis = true let taint_analysis = true
@ -1123,11 +1121,6 @@ and subtype_multirange =
CLOpt.mk_bool ~deprecated:["subtype_multirange"] ~long:"subtype-multirange" ~default:true CLOpt.mk_bool ~deprecated:["subtype_multirange"] ~long:"subtype-multirange" ~default:true
"Use the multirange subtyping domain" "Use the multirange subtyping domain"
(* Path to list of collected @SuppressWarnings annotations *)
and suppress_warnings_out =
CLOpt.mk_path_opt ~deprecated:["suppress_warnings_out"] ~long:suppress_warnings_annotations_long
~meta:"path" ""
and svg = and svg =
CLOpt.mk_bool ~deprecated:["svg"] ~long:"svg" CLOpt.mk_bool ~deprecated:["svg"] ~long:"svg"
"Generate .dot and .svg files from specs" "Generate .dot and .svg files from specs"
@ -1483,7 +1476,6 @@ and stacktrace = !stacktrace
and stacktraces_dir = !stacktraces_dir and stacktraces_dir = !stacktraces_dir
and stats_mode = !stats and stats_mode = !stats
and subtype_multirange = !subtype_multirange and subtype_multirange = !subtype_multirange
and suppress_warnings_out = !suppress_warnings_out
and svg = !svg and svg = !svg
and symops_per_iteration = !symops_per_iteration and symops_per_iteration = !symops_per_iteration
and test = !test and test = !test

@ -107,7 +107,6 @@ val sources : string list
val sourcepath : string option val sourcepath : string option
val specs_dir_name : string val specs_dir_name : string
val specs_files_suffix : string val specs_files_suffix : string
val suppress_warnings_annotations_long : string
val start_filename : string val start_filename : string
val taint_analysis : bool val taint_analysis : bool
val trace_absarray : bool val trace_absarray : bool
@ -249,7 +248,6 @@ val stacktrace : string option
val stacktraces_dir : string option val stacktraces_dir : string option
val stats_mode : bool val stats_mode : bool
val subtype_multirange : bool val subtype_multirange : bool
val suppress_warnings_out : string option
val svg : bool val svg : bool
val symops_per_iteration : int option val symops_per_iteration : int option
val test : bool val test : bool

@ -106,7 +106,6 @@ let performance_critical = "PerformanceCritical"
let no_allocation = "NoAllocation" let no_allocation = "NoAllocation"
let ignore_allocations = "IgnoreAllocations" let ignore_allocations = "IgnoreAllocations"
let suppress_warnings = "SuppressWarnings"
let suppress_lint = "SuppressLint" let suppress_lint = "SuppressLint"
let privacy_source = "PrivacySource" let privacy_source = "PrivacySource"
let privacy_sink = "PrivacySink" let privacy_sink = "PrivacySink"
@ -193,8 +192,8 @@ let ia_is_no_allocation ia =
let ia_is_ignore_allocations ia = let ia_is_ignore_allocations ia =
ia_ends_with ia ignore_allocations ia_ends_with ia ignore_allocations
let ia_is_suppress_warnings ia = let ia_is_suppress_lint ia =
ia_ends_with ia suppress_warnings ia_ends_with ia suppress_lint
let ia_is_privacy_source ia = let ia_is_privacy_source ia =
ia_ends_with ia privacy_source ia_ends_with ia privacy_source

@ -17,7 +17,6 @@ val expensive : string
val performance_critical : string val performance_critical : string
val no_allocation : string val no_allocation : string
val on_bind : string val on_bind : string
val suppress_warnings : string
type annotation = type annotation =
| Nullable | Nullable
@ -88,7 +87,7 @@ val ia_is_expensive : Annot.Item.t -> bool
val ia_is_performance_critical : Annot.Item.t -> bool val ia_is_performance_critical : Annot.Item.t -> bool
val ia_is_no_allocation : Annot.Item.t -> bool val ia_is_no_allocation : Annot.Item.t -> bool
val ia_is_ignore_allocations : Annot.Item.t -> bool val ia_is_ignore_allocations : Annot.Item.t -> bool
val ia_is_suppress_warnings : Annot.Item.t -> bool val ia_is_suppress_lint : Annot.Item.t -> bool
val ia_is_privacy_source : Annot.Item.t -> bool val ia_is_privacy_source : Annot.Item.t -> bool
val ia_is_privacy_sink : Annot.Item.t -> bool val ia_is_privacy_sink : Annot.Item.t -> bool
val ia_is_integrity_source : Annot.Item.t -> bool val ia_is_integrity_source : Annot.Item.t -> bool

@ -13,15 +13,6 @@ open! IStd
open Javalib_pack open Javalib_pack
let is_suppress_warnings_annotated =
Inferconfig.suppress_warnings_matcher SourceFile.empty
let suppress_warnings =
({ Annot.
class_name = Annotations.suppress_warnings;
parameters = ["infer"] },
true)
(** Translate an annotation. *) (** Translate an annotation. *)
let translate a : Annot.t = let translate a : Annot.t =
let class_name = JBasics.cn_name a.JBasics.kind in let class_name = JBasics.cn_name a.JBasics.kind in
@ -48,13 +39,9 @@ let translate_item avlist : Annot.Item.t =
(** Translate a method annotation. *) (** Translate a method annotation. *)
let translate_method proc_name ann : Annot.Method.t = let translate_method ann : Annot.Method.t =
let global_ann = ann.Javalib.ma_global in let global_ann = ann.Javalib.ma_global in
let param_ann = ann.Javalib.ma_parameters in let param_ann = ann.Javalib.ma_parameters in
let ret_item = let ret_item = translate_item global_ann in
let base_annotations = translate_item global_ann in
if is_suppress_warnings_annotated proc_name then
suppress_warnings :: base_annotations
else base_annotations in
let param_items = IList.map translate_item param_ann in let param_items = IList.map translate_item param_ann in
ret_item, param_items ret_item, param_items

@ -17,4 +17,4 @@ open Javalib_pack
val translate_item : (JBasics.annotation * Javalib.visibility) list -> Annot.Item.t val translate_item : (JBasics.annotation * Javalib.visibility) list -> Annot.Item.t
(** Translate a method annotation. *) (** Translate a method annotation. *)
val translate_method : Procname.t -> Javalib.method_annotations -> Annot.Method.t val translate_method : Javalib.method_annotations -> Annot.Method.t

@ -281,7 +281,7 @@ let create_am_procdesc program icfg am proc_name : Procdesc.t =
let formals = let formals =
formals_from_signature program tenv cn ms (JTransType.get_method_kind m) in formals_from_signature program tenv cn ms (JTransType.get_method_kind m) in
let method_annotation = let method_annotation =
JAnnotation.translate_method proc_name am.Javalib.am_annotations in JAnnotation.translate_method am.Javalib.am_annotations in
let procdesc = let procdesc =
let proc_attributes = let proc_attributes =
{ (ProcAttributes.default proc_name Config.Java) with { (ProcAttributes.default proc_name Config.Java) with
@ -313,7 +313,7 @@ let create_native_procdesc program icfg cm proc_name =
let formals = let formals =
formals_from_signature program tenv cn ms (JTransType.get_method_kind m) in formals_from_signature program tenv cn ms (JTransType.get_method_kind m) in
let method_annotation = let method_annotation =
JAnnotation.translate_method proc_name cm.Javalib.cm_annotations in JAnnotation.translate_method cm.Javalib.cm_annotations in
let proc_attributes = let proc_attributes =
{ (ProcAttributes.default proc_name Config.Java) with { (ProcAttributes.default proc_name Config.Java) with
ProcAttributes.access = trans_access cm.Javalib.cm_access; ProcAttributes.access = trans_access cm.Javalib.cm_access;
@ -343,7 +343,7 @@ let create_cm_procdesc source_file program linereader icfg cm proc_name =
let loc_exit = let loc_exit =
get_location source_file jbir_code (Array.length (JBir.code jbir_code) - 1) in get_location source_file jbir_code (Array.length (JBir.code jbir_code) - 1) in
let method_annotation = let method_annotation =
JAnnotation.translate_method proc_name cm.Javalib.cm_annotations in JAnnotation.translate_method cm.Javalib.cm_annotations in
update_constr_loc cn ms loc_start; update_constr_loc cn ms loc_start;
update_init_loc cn ms loc_exit; update_init_loc cn ms loc_exit;
let proc_attributes = let proc_attributes =

@ -56,7 +56,6 @@ codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.guardedByT
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.guardedByTypeSyntaxBad(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure guardedByTypeSyntaxBad()] codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.guardedByTypeSyntaxBad(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure guardedByTypeSyntaxBad()]
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFAfterBlockBad(), 3, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFAfterBlockBad()] codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFAfterBlockBad(), 3, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFAfterBlockBad()]
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBad(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBad()] codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBad(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBad()]
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadButSuppressedOther(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadButSuppressedOther()]
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadWrongAnnotation(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadWrongAnnotation()] codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadWrongAnnotation(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadWrongAnnotation()]
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadWrongLock(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadWrongLock()] codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadWrongLock(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadWrongLock()]
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readHBad(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readHBad()] codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readHBad(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readHBad()]

@ -56,7 +56,6 @@ infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExampl
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.guardedByTypeSyntaxBad(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure guardedByTypeSyntaxBad()] infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.guardedByTypeSyntaxBad(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure guardedByTypeSyntaxBad()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFAfterBlockBad(), 3, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFAfterBlockBad()] infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFAfterBlockBad(), 3, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFAfterBlockBad()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBad(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBad()] infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBad(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBad()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadButSuppressedOther(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadButSuppressedOther()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadWrongAnnotation(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadWrongAnnotation()] infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadWrongAnnotation(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadWrongAnnotation()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadWrongLock(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadWrongLock()] infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadWrongLock(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadWrongLock()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readHBad(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readHBad()] infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readHBad(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readHBad()]

@ -9,6 +9,8 @@
package codetoanalyze.java.checkers; package codetoanalyze.java.checkers;
import android.annotation.SuppressLint;
import com.facebook.infer.annotation.Expensive; import com.facebook.infer.annotation.Expensive;
import com.facebook.infer.annotation.PerformanceCritical; import com.facebook.infer.annotation.PerformanceCritical;
@ -18,7 +20,7 @@ interface I {
class A implements I { class A implements I {
@SuppressWarnings("infer") @SuppressLint("CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED")
// Suppressing the sub-typing violation warning here as foo() is not annotated as @Expensive // Suppressing the sub-typing violation warning here as foo() is not annotated as @Expensive
// in the interface. This report is legit but is not relevant for the current test. // in the interface. This report is legit but is not relevant for the current test.
@Expensive @Expensive

@ -29,7 +29,6 @@ codetoanalyze/java/checkers/ImmutableCast.java, List ImmutableCast.badCastFromFi
codetoanalyze/java/checkers/NoAllocationExample.java, void NoAllocationExample.directlyAllocatingMethod(), 1, CHECKERS_ALLOCATES_MEMORY, [] codetoanalyze/java/checkers/NoAllocationExample.java, void NoAllocationExample.directlyAllocatingMethod(), 1, CHECKERS_ALLOCATES_MEMORY, []
codetoanalyze/java/checkers/NoAllocationExample.java, void NoAllocationExample.indirectlyAllocatingMethod(), 1, CHECKERS_ALLOCATES_MEMORY, [] codetoanalyze/java/checkers/NoAllocationExample.java, void NoAllocationExample.indirectlyAllocatingMethod(), 1, CHECKERS_ALLOCATES_MEMORY, []
codetoanalyze/java/checkers/PrintfArgsChecker.java, void PrintfArgsChecker.formatStringIsNotLiteral(PrintStream), 2, CHECKERS_PRINTF_ARGS, [Format string must be string literal] codetoanalyze/java/checkers/PrintfArgsChecker.java, void PrintfArgsChecker.formatStringIsNotLiteral(PrintStream), 2, CHECKERS_PRINTF_ARGS, [Format string must be string literal]
codetoanalyze/java/checkers/PrintfArgsChecker.java, void PrintfArgsChecker.notSuppressed(PrintStream), 1, CHECKERS_PRINTF_ARGS, [printf(...) at line 36: parameter 2 is expected to be of type java.lang.Integer but java.lang.String was given.]
codetoanalyze/java/checkers/PrintfArgsChecker.java, void PrintfArgsChecker.stringInsteadOfInteger(PrintStream), 1, CHECKERS_PRINTF_ARGS, [printf(...) at line 40: parameter 2 is expected to be of type java.lang.Integer but java.lang.String was given.] codetoanalyze/java/checkers/PrintfArgsChecker.java, void PrintfArgsChecker.stringInsteadOfInteger(PrintStream), 1, CHECKERS_PRINTF_ARGS, [printf(...) at line 40: parameter 2 is expected to be of type java.lang.Integer but java.lang.String was given.]
codetoanalyze/java/checkers/PrintfArgsChecker.java, void PrintfArgsChecker.wrongNumberOfArguments(PrintStream), 1, CHECKERS_PRINTF_ARGS, [format string arguments don't mach provided arguments in printf(...) at line 44] codetoanalyze/java/checkers/PrintfArgsChecker.java, void PrintfArgsChecker.wrongNumberOfArguments(PrintStream), 1, CHECKERS_PRINTF_ARGS, [format string arguments don't mach provided arguments in printf(...) at line 44]
codetoanalyze/java/checkers/TwoCheckersExample.java, List TwoCheckersExample.shouldRaiseImmutableCastError(), 0, CHECKERS_IMMUTABLE_CAST, [Method shouldRaiseImmutableCastError() returns class com.google.common.collect.ImmutableList but the return type is class java.util.List. Make sure that users of this method do not try to modify the collection.] codetoanalyze/java/checkers/TwoCheckersExample.java, List TwoCheckersExample.shouldRaiseImmutableCastError(), 0, CHECKERS_IMMUTABLE_CAST, [Method shouldRaiseImmutableCastError() returns class com.google.common.collect.ImmutableList but the return type is class java.util.List. Make sure that users of this method do not try to modify the collection.]

@ -1,51 +0,0 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package codetoanalyze.java.eradicate;
import java.lang.SuppressWarnings;
import javax.annotation.Nullable;
public class SuppressWarningsExample {
@SuppressWarnings("null")
static class DoSuppress {
@Nullable Object mFld;
void doSuppress1(@Nullable Object o) {
o.toString();
}
void doSuppress2() {
mFld.toString();
}
}
@SuppressWarnings("null")
public void doSuppress(@Nullable Object o) {
o.toString();
}
@SuppressWarnings("infer")
public void doSuppressInferAnnot(@Nullable Object o) {
o.toString();
}
@SuppressWarnings("unchecked")
public void doNotSuppressWrongAnnot(@Nullable Object o) {
o.toString();
}
public void doNotSuppressNoAnnot(@Nullable Object o) {
o.toString();
}
}

@ -47,5 +47,3 @@ codetoanalyze/java/eradicate/ReturnNotNullable.java, String ReturnNotNullable.re
codetoanalyze/java/eradicate/ReturnNotNullable.java, String ReturnNotNullable.return_null_in_catch(), 0, ERADICATE_RETURN_NOT_NULLABLE, [origin,Method `return_null_in_catch()` may return null but it is not annotated with `@Nullable`. (Origin: null constant at line 110)] codetoanalyze/java/eradicate/ReturnNotNullable.java, String ReturnNotNullable.return_null_in_catch(), 0, ERADICATE_RETURN_NOT_NULLABLE, [origin,Method `return_null_in_catch()` may return null but it is not annotated with `@Nullable`. (Origin: null constant at line 110)]
codetoanalyze/java/eradicate/ReturnNotNullable.java, String ReturnNotNullable.return_null_in_catch_after_throw(), 0, ERADICATE_RETURN_NOT_NULLABLE, [origin,Method `return_null_in_catch_after_throw()` may return null but it is not annotated with `@Nullable`. (Origin: null constant at line 122)] codetoanalyze/java/eradicate/ReturnNotNullable.java, String ReturnNotNullable.return_null_in_catch_after_throw(), 0, ERADICATE_RETURN_NOT_NULLABLE, [origin,Method `return_null_in_catch_after_throw()` may return null but it is not annotated with `@Nullable`. (Origin: null constant at line 122)]
codetoanalyze/java/eradicate/ReturnNotNullable.java, URL ReturnNotNullable.getResourceNullable(Class,String), 0, ERADICATE_RETURN_NOT_NULLABLE, [origin,Method `getResourceNullable(...)` may return null but it is not annotated with `@Nullable`. (Origin: call to getResource(...) modelled in eradicate/modelTables.ml at line 127)] codetoanalyze/java/eradicate/ReturnNotNullable.java, URL ReturnNotNullable.getResourceNullable(Class,String), 0, ERADICATE_RETURN_NOT_NULLABLE, [origin,Method `getResourceNullable(...)` may return null but it is not annotated with `@Nullable`. (Origin: call to getResource(...) modelled in eradicate/modelTables.ml at line 127)]
codetoanalyze/java/eradicate/SuppressWarningsExample.java, void SuppressWarningsExample.doNotSuppressNoAnnot(Object), 1, ERADICATE_NULL_METHOD_CALL, [The value of `o` in the call to `toString()` could be null. (Origin: method parameter o)]
codetoanalyze/java/eradicate/SuppressWarningsExample.java, void SuppressWarningsExample.doNotSuppressWrongAnnot(Object), 1, ERADICATE_NULL_METHOD_CALL, [The value of `o` in the call to `toString()` could be null. (Origin: method parameter o)]

@ -9,6 +9,7 @@
package codetoanalyze.java.infer; package codetoanalyze.java.infer;
import android.annotation.SuppressLint;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
@ -479,7 +480,7 @@ public class NullPointerExceptions {
derefUndefinedCallee().toString(); derefUndefinedCallee().toString();
} }
@SuppressWarnings("null") // TODO(#8647398): Add support for @SuppressWarnings with Ant @SuppressLint("NULL_DEREFERENCE")
void shouldNotReportNPE() { void shouldNotReportNPE() {
Object o = null; Object o = null;
o.toString(); o.toString();

@ -121,7 +121,6 @@ codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.guardedByT
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.guardedByTypeSyntaxBad(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure guardedByTypeSyntaxBad()] codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.guardedByTypeSyntaxBad(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure guardedByTypeSyntaxBad()]
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFAfterBlockBad(), 3, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFAfterBlockBad()] codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFAfterBlockBad(), 3, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFAfterBlockBad()]
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBad(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBad()] codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBad(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBad()]
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadButSuppressedOther(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadButSuppressedOther()]
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadWrongAnnotation(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadWrongAnnotation()] codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadWrongAnnotation(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadWrongAnnotation()]
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadWrongLock(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadWrongLock()] codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadWrongLock(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadWrongLock()]
codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readHBad(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readHBad()] codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readHBad(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readHBad()]

Loading…
Cancel
Save