mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
Bug 1227388 - Finish removing dehydra support. r=mshal
Dehydra/Treehydra is unmaintained, broken (iirc), and obsoleted by clang static analysis. We've removed parts of the build system support for it, but not all. This is meant to remove the remains.
This commit is contained in:
parent
1044711983
commit
70a5b9589d
@ -5,43 +5,6 @@
|
||||
# The entire tree should be subject to static analysis using the XPCOM
|
||||
# script. Additional scripts may be added by specific subdirectories.
|
||||
|
||||
DEHYDRA_SCRIPT = $(topsrcdir)/config/static-checking.js
|
||||
|
||||
ifndef JS_STANDALONE
|
||||
DEHYDRA_MODULES = \
|
||||
$(topsrcdir)/xpcom/analysis/final.js \
|
||||
$(topsrcdir)/xpcom/analysis/must-override.js \
|
||||
$(NULL)
|
||||
|
||||
TREEHYDRA_MODULES = \
|
||||
$(topsrcdir)/xpcom/analysis/outparams.js \
|
||||
$(topsrcdir)/xpcom/analysis/stack.js \
|
||||
$(topsrcdir)/xpcom/analysis/flow.js \
|
||||
$(topsrcdir)/xpcom/analysis/static-init.js \
|
||||
$(topsrcdir)/layout/generic/frame-verify.js \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
TREEHYDRA_MODULES += \
|
||||
$(topsrcdir)/js/src/jsstack.js \
|
||||
$(NULL)
|
||||
|
||||
DEHYDRA_ARG_PREFIX=-fplugin-arg-gcc_treehydra-
|
||||
|
||||
DEHYDRA_ARGS = \
|
||||
$(DEHYDRA_ARG_PREFIX)script=$(DEHYDRA_SCRIPT) \
|
||||
$(DEHYDRA_ARG_PREFIX)topsrcdir=$(topsrcdir) \
|
||||
$(DEHYDRA_ARG_PREFIX)objdir=$(DEPTH) \
|
||||
$(DEHYDRA_ARG_PREFIX)dehydra-modules=$(subst $(NULL) ,$(COMMA),$(strip $(DEHYDRA_MODULES))) \
|
||||
$(DEHYDRA_ARG_PREFIX)treehydra-modules=$(subst $(NULL) ,$(COMMA),$(strip $(TREEHYDRA_MODULES))) \
|
||||
$(NULL)
|
||||
|
||||
DEHYDRA_FLAGS = -fplugin=$(DEHYDRA_PATH) $(DEHYDRA_ARGS)
|
||||
|
||||
ifdef DEHYDRA_PATH
|
||||
OS_CXXFLAGS += $(DEHYDRA_FLAGS)
|
||||
endif
|
||||
|
||||
ifdef ENABLE_CLANG_PLUGIN
|
||||
CLANG_PLUGIN := $(DEPTH)/build/clang-plugin/$(DLL_PREFIX)clang-plugin$(DLL_SUFFIX)
|
||||
OS_CXXFLAGS += -Xclang -load -Xclang $(CLANG_PLUGIN) -Xclang -add-plugin -Xclang moz-check
|
||||
|
@ -1,149 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* 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');
|
||||
}
|
||||
|
||||
sys.include_path.push(options.topsrcdir);
|
||||
|
||||
include('string-format.js');
|
||||
|
||||
var modules = [];
|
||||
|
||||
function LoadModules(modulelist)
|
||||
{
|
||||
if (modulelist == "")
|
||||
return;
|
||||
|
||||
let modulenames = modulelist.split(',');
|
||||
for (let modulename of 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 (let module of modules)
|
||||
if (module.hasOwnProperty('process_type'))
|
||||
module.process_type(c);
|
||||
}
|
||||
|
||||
function hasAttribute(c, attrname)
|
||||
{
|
||||
var attr;
|
||||
|
||||
if (c.attributes === undefined)
|
||||
return false;
|
||||
|
||||
for (var key in c.attributes) {
|
||||
attr = c.attributes[key];
|
||||
if (attr.name == 'user' && attr.value[0] == attrname)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is useful for detecting method overrides
|
||||
function signaturesMatch(m1, m2)
|
||||
{
|
||||
if (m1.shortName != m2.shortName)
|
||||
return false;
|
||||
|
||||
if ((!!m1.isVirtual) != (!!m2.isVirtual))
|
||||
return false;
|
||||
|
||||
if (m1.isStatic != m2.isStatic)
|
||||
return false;
|
||||
|
||||
let p1 = m1.type.parameters;
|
||||
let p2 = m2.type.parameters;
|
||||
|
||||
if (p1.length != p2.length)
|
||||
return false;
|
||||
|
||||
for (let i = 0; i < p1.length; ++i)
|
||||
if (!params_match(p1[i], p2[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function params_match(p1, p2)
|
||||
{
|
||||
[p1, p2] = unwrap_types(p1, p2);
|
||||
|
||||
for (let i in p1)
|
||||
if (i == "type" && !types_match(p1.type, p2.type))
|
||||
return false;
|
||||
else if (i != "type" && p1[i] !== p2[i])
|
||||
return false;
|
||||
|
||||
for (let i in p2)
|
||||
if (!(i in p1))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function types_match(t1, t2)
|
||||
{
|
||||
if (!t1 || !t2)
|
||||
return false;
|
||||
|
||||
[t1, t2] = unwrap_types(t1, t2);
|
||||
|
||||
return t1 === t2;
|
||||
}
|
||||
|
||||
function unwrap_types(t1, t2)
|
||||
{
|
||||
while (t1.variantOf)
|
||||
t1 = t1.variantOf;
|
||||
|
||||
while (t2.variantOf)
|
||||
t2 = t2.variantOf;
|
||||
|
||||
return [t1, t2];
|
||||
}
|
||||
|
||||
const forward_functions = [
|
||||
'process_type',
|
||||
'process_tree_type',
|
||||
'process_decl',
|
||||
'process_tree_decl',
|
||||
'process_function',
|
||||
'process_tree',
|
||||
'process_cp_pre_genericize',
|
||||
'input_end'
|
||||
];
|
||||
|
||||
function setup_forwarding(n)
|
||||
{
|
||||
this[n] = function() {
|
||||
for (let module of modules) {
|
||||
if (module.hasOwnProperty(n)) {
|
||||
module[n].apply(this, arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let n of forward_functions)
|
||||
setup_forwarding(n);
|
18
configure.in
18
configure.in
@ -7337,24 +7337,6 @@ fi
|
||||
AC_SUBST_LIST(MOZ_GLUE_WRAP_LDFLAGS)
|
||||
export MOZ_GLUE_WRAP_LDFLAGS
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable static checking using gcc-dehydra
|
||||
dnl ========================================================
|
||||
|
||||
MOZ_ARG_WITH_STRING(static-checking,
|
||||
[ --with-static-checking=path/to/gcc_dehydra.so
|
||||
Enable static checking of code using GCC-dehydra],
|
||||
DEHYDRA_PATH=$withval,
|
||||
DEHYDRA_PATH= )
|
||||
|
||||
if test -n "$DEHYDRA_PATH"; then
|
||||
if test ! -f "$DEHYDRA_PATH"; then
|
||||
AC_MSG_ERROR([The dehydra plugin is not at the specified path.])
|
||||
fi
|
||||
AC_DEFINE(NS_STATIC_CHECKING)
|
||||
fi
|
||||
AC_SUBST(DEHYDRA_PATH)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable using the clang plugin to build
|
||||
dnl ========================================================
|
||||
|
@ -3293,24 +3293,6 @@ if test -n "$JS_OOM_BREAKPOINT"; then
|
||||
AC_DEFINE(JS_OOM_BREAKPOINT)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable static checking using gcc-dehydra
|
||||
dnl ========================================================
|
||||
|
||||
MOZ_ARG_WITH_STRING(static-checking,
|
||||
[ --with-static-checking=path/to/gcc_dehydra.so
|
||||
Enable static checking of code using GCC-dehydra],
|
||||
DEHYDRA_PATH=$withval,
|
||||
DEHYDRA_PATH= )
|
||||
|
||||
if test -n "$DEHYDRA_PATH"; then
|
||||
if test ! -f "$DEHYDRA_PATH"; then
|
||||
AC_MSG_ERROR([The dehydra plugin is not at the specified path.])
|
||||
fi
|
||||
AC_DEFINE(NS_STATIC_CHECKING)
|
||||
fi
|
||||
AC_SUBST(DEHYDRA_PATH)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable using the clang plugin to build
|
||||
dnl ========================================================
|
||||
|
@ -50,9 +50,6 @@ with Files('../public/TrackedOptimizationInfo.h'):
|
||||
BUG_COMPONENT = component_jit
|
||||
|
||||
|
||||
if CONFIG['DEHYDRA_PATH']:
|
||||
DIRS += ['analysis-tests']
|
||||
|
||||
if CONFIG['JS_BUNDLED_EDITLINE']:
|
||||
DIRS += ['editline']
|
||||
|
||||
|
@ -1,95 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* graph-frameclasses.js: a dehydra script to collect information about
|
||||
* the class hierarchy of frame types.
|
||||
*/
|
||||
|
||||
function inheritsFrom(t, baseName)
|
||||
{
|
||||
let name = t.name;
|
||||
if (name == baseName)
|
||||
return true;
|
||||
|
||||
for (let base of t.bases)
|
||||
if (inheritsFrom(base.type, baseName))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var output = [];
|
||||
|
||||
function process_type(t)
|
||||
{
|
||||
if ((t.kind == "class" || t.kind == "struct")) {
|
||||
if (!t.isIncomplete && inheritsFrom(t, 'nsIFrame')) {
|
||||
if (inheritsFrom(t, 'nsISupports'))
|
||||
warning("nsIFrame derivative %s inherits from nsISupports but is not refcounted.".format(t.name), t.loc);
|
||||
|
||||
let nonFrameBases = [];
|
||||
|
||||
output.push('CLASS-DEF: %s'.format(t.name));
|
||||
|
||||
for (let base of t.bases) {
|
||||
if (inheritsFrom(base.type, 'nsIFrame')) {
|
||||
output.push('%s -> %s;'.format(base.type.name, t.name));
|
||||
}
|
||||
else if (base.type.name != 'nsQueryFrame') {
|
||||
nonFrameBases.push(base.type.name);
|
||||
}
|
||||
}
|
||||
|
||||
output.push('%s [label="%s%s"];'.format(t.name, t.name,
|
||||
nonFrameBases.map(b => "\\n(%s)".format(b)).join('')));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var frameIIDRE = /::kFrameIID$/;
|
||||
var queryFrameRE = /^do_QueryFrame::operator/;
|
||||
|
||||
/* A list of class names T that have do_QueryFrame<T> used */
|
||||
var needIDs = [];
|
||||
|
||||
/* A map of class names that have a kFrameIID declared */
|
||||
var haveIDs = {};
|
||||
|
||||
// We match up needIDs with haveIDs at the end because static variables are
|
||||
// not present in the .members array of a type
|
||||
|
||||
function process_tree_decl(d)
|
||||
{
|
||||
d = dehydra_convert(d);
|
||||
|
||||
if (d.name && frameIIDRE.exec(d.name)) {
|
||||
haveIDs[d.memberOf.name] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
function process_cp_pre_genericize(d)
|
||||
{
|
||||
d = dehydra_convert(d);
|
||||
if (queryFrameRE.exec(d.name) && d.template === undefined) {
|
||||
let templtype = d.type.type.type;
|
||||
while (templtype.typedef !== undefined)
|
||||
templtype = templtype.typedef;
|
||||
|
||||
needIDs.push([templtype.name, d.loc]);
|
||||
}
|
||||
}
|
||||
|
||||
function input_end()
|
||||
{
|
||||
for (let [name, loc] of needIDs) {
|
||||
if (!haveIDs.hasOwnProperty(name)) {
|
||||
error("nsQueryFrame<%s> found, but %s::kFrameIID is not declared".format(name, name), loc);
|
||||
}
|
||||
}
|
||||
|
||||
if (output.length > 0) {
|
||||
write_file(sys.aux_base_name + '.framedata', output.join('\n'));
|
||||
}
|
||||
}
|
@ -15,9 +15,6 @@ TEST_DIRS += [
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
TEST_DIRS += ['windows']
|
||||
|
||||
if CONFIG['DEHYDRA_PATH']:
|
||||
TEST_DIRS += ['static-checker']
|
||||
|
||||
EXPORTS.testing += [
|
||||
'TestHarness.h',
|
||||
]
|
||||
|
@ -1,146 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
OUTPARAMS_WARNING_TESTCASES = \
|
||||
e1.cpp \
|
||||
e4.cpp \
|
||||
e6.cpp \
|
||||
e7.cpp \
|
||||
e8.cpp \
|
||||
e9.cpp \
|
||||
e10.cpp \
|
||||
e11.cpp \
|
||||
e12.cpp \
|
||||
e13.cpp \
|
||||
$(NULL)
|
||||
|
||||
OUTPARAMS_NS_FAILED_TESTCASES = \
|
||||
e2.cpp \
|
||||
e5.cpp \
|
||||
$(NULL)
|
||||
|
||||
OUTPARAMS_PASS_TESTCASES = \
|
||||
o1.cpp \
|
||||
o2.cpp \
|
||||
o3.cpp \
|
||||
o4.cpp \
|
||||
o5.cpp \
|
||||
o6.cpp \
|
||||
o7.cpp \
|
||||
o8.cpp \
|
||||
o9.cpp \
|
||||
o10.cpp \
|
||||
o11.cpp \
|
||||
o12.cpp \
|
||||
o13.cpp \
|
||||
o14.cpp \
|
||||
o15.cpp \
|
||||
o16.cpp \
|
||||
onull.cpp \
|
||||
onull2.cpp \
|
||||
opmember.cpp \
|
||||
$(NULL)
|
||||
|
||||
FLOW_PASS_TESTCASES = \
|
||||
flow_through_pass.cpp
|
||||
|
||||
FLOW_FAILURE_TESTCASES = \
|
||||
flow_through_fail.cpp
|
||||
|
||||
MUST_OVERRIDE_PASS_TESTCASES = \
|
||||
OverrideOK1.cpp \
|
||||
OverrideOK2.cpp \
|
||||
OverrideOK3-NamespaceTypedef.cpp \
|
||||
$(NULL)
|
||||
|
||||
MUST_OVERRIDE_FAILURE_TESTCASES = \
|
||||
OverrideFail1.cpp \
|
||||
OverrideFail2.cpp \
|
||||
OverrideFail3.cpp \
|
||||
OverrideFail4.cpp \
|
||||
$(NULL)
|
||||
|
||||
OVERRIDE_PASS_TESTCASES = \
|
||||
override-pass.cpp \
|
||||
override-namespace-typedef.cpp \
|
||||
$(NULL)
|
||||
|
||||
OVERRIDE_FAILURE_TESTCASES = \
|
||||
override-global.cpp \
|
||||
override-signature.cpp \
|
||||
override-static.cpp \
|
||||
override-virtual.cpp \
|
||||
$(NULL)
|
||||
|
||||
STATIC_INIT_PASS_TESTCASES = \
|
||||
TestStaticInitStructOK.cpp \
|
||||
$(NULL)
|
||||
|
||||
STATIC_INIT_WARNING_TESTCASES = \
|
||||
TestStaticInitAttr.cpp \
|
||||
TestStaticInitConstructor.cpp \
|
||||
TestStaticInitGlobal.cpp \
|
||||
TestStaticInitGlobalConst.cpp \
|
||||
$(NULL)
|
||||
|
||||
STATIC_FAILURE_TESTCASES = \
|
||||
$(FLOW_FAILURE_TESTCASES) \
|
||||
$(MUST_OVERRIDE_FAILURE_TESTCASES) \
|
||||
$(OVERRIDE_FAILURE_TESTCASES) \
|
||||
$(NULL)
|
||||
|
||||
STATIC_WARNING_TESTCASES = \
|
||||
$(OUTPARAMS_WARNING_TESTCASES) \
|
||||
$(STATIC_INIT_WARNING_TESTCASES) \
|
||||
$(NULL)
|
||||
|
||||
STATIC_PASS_TESTCASES = \
|
||||
$(OUTPARAMS_NS_FAILED_TESTCASES) \
|
||||
$(OUTPARAMS_PASS_TESTCASES) \
|
||||
$(FLOW_PASS_TESTCASES) \
|
||||
$(MUST_OVERRIDE_PASS_TESTCASES) \
|
||||
$(OVERRIDE_PASS_TESTCASES) \
|
||||
$(STATIC_INIT_PASS_TESTCASES) \
|
||||
$(NULL)
|
||||
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
# We want to compile each file and invert the result to ensure that
|
||||
# compilation failed.
|
||||
check:: \
|
||||
$(STATIC_FAILURE_TESTCASES:.cpp=.s-fail) \
|
||||
$(STATIC_WARNING_TESTCASES:.cpp=.s-warn) \
|
||||
$(STATIC_PASS_TESTCASES:.cpp=.s-pass)
|
||||
|
||||
%.s-fail: %.cpp $(GLOBAL_DEPS) $(DEHYDRA_SCRIPTS) $(call mkdir_deps,$(MDDEPDIR))
|
||||
@printf 'Compiling $(<F) to check that the static-analysis script is checking properly...'
|
||||
@if $(CCC) $(OUTOPTION)/dev/null -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS) >$(*F).errlog 2>&1; then \
|
||||
printf 'fail:\nerror: compilation of $(<F) succeeded. It shouldn't have!\n'; \
|
||||
exit 1; \
|
||||
else \
|
||||
printf 'ok.\n'; \
|
||||
fi
|
||||
|
||||
%.s-warn: %.cpp $(GLOBAL_DEPS) $(DEHYDRA_SCRIPTS) $(call mkdir_deps,$(MDDEPDIR))
|
||||
@printf 'Compiling $(<F) to check that the static-analysis script is checking properly...'
|
||||
@if $(CCC) -Werror $(OUTOPTION)/dev/null -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS) >$(*F).errlog 2>&1; then \
|
||||
printf 'fail:\nerror: compilation of $(<F) succeeded with -Werror. It shouldn't have!\n'; \
|
||||
exit 1; \
|
||||
fi
|
||||
@if $(CCC) $(OUTOPTION)/dev/null -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS) >$(*F).werrlog 2>&1; then \
|
||||
printf 'ok.\n'; \
|
||||
else \
|
||||
printf 'fail:\nerror: compilation of $(<F) without -Werror failed. A warning should have been issued.\n'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
%.s-pass: %.cpp $(GLOBAL_DEPS) $(DEHYDRA_SCRIPTS) $(call mkdir_deps,$(MDDEPDIR))
|
||||
@printf 'Compiling $(<F) to check that the static-analysis script is checking properly...'
|
||||
@if $(CCC) -Werror $(OUTOPTION)/dev/null -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS) >$(*F).errlog 2>&1; then \
|
||||
printf 'ok.\n'; \
|
||||
else \
|
||||
printf 'fail:\nerror: compilation of $(<F) failed. It shouldn't have!\n'; \
|
||||
exit 1; \
|
||||
fi
|
@ -1,5 +0,0 @@
|
||||
int foo() __attribute__((constructor));
|
||||
|
||||
int foo() {
|
||||
return 0;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
struct Blah {
|
||||
public:
|
||||
Blah() { }
|
||||
~Blah() { } // raises call to __cxa_atexit
|
||||
};
|
||||
|
||||
Blah b;
|
@ -1,5 +0,0 @@
|
||||
int foo() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int x = foo();
|
@ -1,5 +0,0 @@
|
||||
int foo() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const static int x = foo();
|
@ -1,5 +0,0 @@
|
||||
struct Blah {
|
||||
int i;
|
||||
};
|
||||
|
||||
Blah b = { 3 };
|
@ -1,16 +0,0 @@
|
||||
static void MUST_FLOW_THROUGH(const char *label) {
|
||||
}
|
||||
|
||||
int test(int x, int y) {
|
||||
MUST_FLOW_THROUGH("out");
|
||||
|
||||
if (!x) {
|
||||
x = y;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return y;
|
||||
out:
|
||||
x--;
|
||||
return x;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
static void MUST_FLOW_THROUGH(const char *label) {
|
||||
}
|
||||
|
||||
int test(int x, int y) {
|
||||
if (x == 3)
|
||||
return 0;
|
||||
|
||||
if(x)
|
||||
MUST_FLOW_THROUGH("out");
|
||||
|
||||
if (x) {
|
||||
x = y;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return y;
|
||||
out:
|
||||
x--;
|
||||
return x;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
Loading…
Reference in New Issue
Block a user