Bug 468717 - enable static analysis for js/src, r=jorendorff

--HG--
rename : xpcom/analysis/static-checking.js => config/static-checking.js
rename : xpcom/analysis/string-format.js => config/string-format.js
rename : xpcom/analysis/static-checking.js => js/src/config/static-checking.js
rename : xpcom/analysis/string-format.js => js/src/config/string-format.js
rename : xpcom/analysis/jsstack.js => js/src/jsstack.js
This commit is contained in:
Benjamin Smedberg 2008-12-11 11:40:04 -05:00
parent 23836bf5df
commit e930891ad0
8 changed files with 161 additions and 13 deletions

View File

@ -1,7 +1,7 @@
# The entire tree should be subject to static analysis using the XPCOM
# script. Additional scripts may be added by specific subdirectories.
DEHYDRA_SCRIPT = $(topsrcdir)/xpcom/analysis/static-checking.js
DEHYDRA_SCRIPT = $(topsrcdir)/config/static-checking.js
DEHYDRA_MODULES = \
$(topsrcdir)/xpcom/analysis/final.js \
@ -11,7 +11,7 @@ TREEHYDRA_MODULES = \
$(topsrcdir)/xpcom/analysis/outparams.js \
$(topsrcdir)/xpcom/analysis/stack.js \
$(topsrcdir)/xpcom/analysis/flow.js \
$(topsrcdir)/xpcom/analysis/jsstack.js \
$(topsrcdir)/js/src/jsstack.js \
$(NULL)
DEHYDRA_ARGS = \

View File

@ -13,8 +13,6 @@ function treehydra_enabled() {
include('unstable/getopt.js');
[options, args] = getopt();
// XXXbugfix: when you pass arguments to -fplugin-arg, include_path[0] is bad
sys.include_path[0] = options.topsrcdir + "/xpcom/analysis";
sys.include_path.push(options.topsrcdir);
include('string-format.js');

View File

@ -1,13 +1,10 @@
# Currently spidermonkey has no static checking infrastructure, but it will...
# This is all dummy values now: see the Mozilla version of this file for
# an example with real data.
DEHYDRA_SCRIPT = $(error No Spidermonkey static-checking.js yet!)
DEHYDRA_SCRIPT = $(topsrcdir)/config/static-checking.js
DEHYDRA_MODULES = \
$(NULL)
TREEHYDRA_MODULES = \
$(topsrcdir)/jsstack.js \
$(NULL)
DEHYDRA_ARGS = \
@ -19,6 +16,6 @@ DEHYDRA_ARGS = \
DEHYDRA_FLAGS = -fplugin=$(DEHYDRA_PATH) -fplugin-arg='$(DEHYDRA_SCRIPT) $(DEHYDRA_ARGS)'
# ifdef DEHYDRA_PATH
# OS_CXXFLAGS += $(DEHYDRA_FLAGS)
# endif
ifdef DEHYDRA_PATH
OS_CXXFLAGS += $(DEHYDRA_FLAGS)
endif

View File

@ -0,0 +1,92 @@
/**
* A script for GCC-dehydra to analyze the Mozilla codebase and catch
* patterns that are incorrect, but which cannot be detected by a compiler. */
/**
* Activate Treehydra outparams analysis if running in Treehydra.
*/
function treehydra_enabled() {
return this.hasOwnProperty('TREE_CODE');
}
include('unstable/getopt.js');
[options, args] = getopt();
sys.include_path.push(options.topsrcdir);
include('string-format.js');
let modules = [];
function LoadModules(modulelist)
{
if (modulelist == "")
return;
let modulenames = modulelist.split(',');
for each (let modulename in modulenames) {
let module = { __proto__: this };
include(modulename, module);
modules.push(module);
}
}
LoadModules(options['dehydra-modules']);
if (treehydra_enabled())
LoadModules(options['treehydra-modules']);
function process_type(c)
{
for each (let module in modules)
if (module.hasOwnProperty('process_type'))
module.process_type(c);
}
function hasAttribute(c, attrname)
{
var attr;
if (c.attributes === undefined)
return false;
for each (attr in c.attributes)
if (attr.name == 'user' && attr.value[0] == attrname)
return true;
return false;
}
function process_function(f, stmts)
{
for each (let module in modules)
if (module.hasOwnProperty('process_function'))
module.process_function(f, stmts);
}
function process_tree(fndecl)
{
for each (let module in modules)
if (module.hasOwnProperty('process_tree'))
module.process_tree(fndecl);
}
function process_decl(decl)
{
for each (let module in modules)
if (module.hasOwnProperty('process_var'))
module.process_decl(decl);
}
function process_cp_pre_genericize(fndecl)
{
for each (let module in modules)
if (module.hasOwnProperty('process_cp_pre_genericize'))
module.process_cp_pre_genericize(fndecl);
}
function input_end()
{
for each (let module in modules)
if (module.hasOwnProperty('input_end'))
module.input_end();
}

View File

@ -0,0 +1,61 @@
String.prototype.format = function string_format() {
// there are two modes of operation... unnamed indices are read in order;
// named indices using %(name)s. The two styles cannot be mixed.
// Unnamed indices can be passed as either a single argument to this function,
// multiple arguments to this function, or as a single array argument
let curindex = 0;
let d;
if (arguments.length > 1) {
d = arguments;
}
else
d = arguments[0];
function r(s, key, type) {
if (type == '%')
return '%';
let v;
if (key == "") {
if (curindex == -1)
throw Error("Cannot mix named and positional indices in string formatting.");
if (curindex == 0 && (!(d instanceof Object) || !(0 in d))) {
v = d;
}
else if (!(curindex in d))
throw Error("Insufficient number of items in format, requesting item %i".format(curindex));
else {
v = d[curindex];
}
++curindex;
}
else {
key = key.slice(1, -1);
if (curindex > 0)
throw Error("Cannot mix named and positional indices in string formatting.");
curindex = -1;
if (!(key in d))
throw Error("Key '%s' not present during string substitution.".format(key));
v = d[key];
}
switch (type) {
case "s":
if (v === undefined)
return "<undefined>";
return v.toString();
case "r":
return uneval(v);
case "i":
return parseInt(v);
case "f":
return Number(v);
default:
throw Error("Unexpected format character '%s'.".format(type));
}
}
return this.replace(/%(\([^)]+\))?(.)/g, r);
};

View File

@ -12,7 +12,7 @@ include('unstable/esp.js');
let Zero_NonZero = {};
include('unstable/zero_nonzero.js', Zero_NonZero);
include('mayreturn.js');
include('xpcom/analysis/mayreturn.js');
function safe_location_of(t) {
if (t === undefined)