зеркало из https://github.com/mozilla/pjs.git
Bug 431832: NS_inparams attr for outparams checker, r=bsmedberg, a=bsmedberg
This commit is contained in:
Родитель
0ab845c8f3
Коммит
ffb7f62c86
|
@ -642,45 +642,48 @@ let ps = {
|
||||||
// Return the param semantics of a FUNCTION_DECL or VAR_DECL representing
|
// Return the param semantics of a FUNCTION_DECL or VAR_DECL representing
|
||||||
// a function pointer.
|
// a function pointer.
|
||||||
OutparamCheck.prototype.func_param_semantics = function(callable) {
|
OutparamCheck.prototype.func_param_semantics = function(callable) {
|
||||||
let ans = [];
|
|
||||||
let ftype = TREE_TYPE(callable);
|
let ftype = TREE_TYPE(callable);
|
||||||
if (TREE_CODE(ftype) == POINTER_TYPE) ftype = TREE_TYPE(ftype);
|
if (TREE_CODE(ftype) == POINTER_TYPE) ftype = TREE_TYPE(ftype);
|
||||||
let is_func = TREE_CODE(callable) == FUNCTION_DECL;
|
// What failure semantics to use for outparams
|
||||||
if (is_func) {
|
let nofail = TREE_TYPE(TREE_TYPE(ftype)) == VOID_TYPE;
|
||||||
ans = [ param_semantics(p) for (p in function_decl_params(callable)) ];
|
|
||||||
}
|
// Set up param lists for analysis
|
||||||
//if (array_all(ans, function (p) p == ps.CONST)) {
|
let params; // param decls, if available
|
||||||
if (ans.every(function (p) p == ps.CONST)) {
|
let types; // param types
|
||||||
if (is_func) {
|
let string_mutator = false;
|
||||||
ans = [ param_semantics_by_type(TREE_TYPE(p))
|
if (TREE_CODE(callable) == FUNCTION_DECL) {
|
||||||
for (p in function_decl_params(callable)) ];
|
params = [ p for (p in function_decl_params(callable)) ];
|
||||||
} else {
|
types = [ TREE_TYPE(p) for each (p in params) ];
|
||||||
ans = [ param_semantics_by_type(p)
|
string_mutator = is_string_mutator(callable);
|
||||||
for (p in function_type_args(ftype))
|
} else {
|
||||||
|
types = [ p for (p in function_type_args(ftype))
|
||||||
if (TREE_CODE(p) != VOID_TYPE) ];
|
if (TREE_CODE(p) != VOID_TYPE) ];
|
||||||
}
|
|
||||||
// Params other than the last should be maybes instead of out.
|
|
||||||
for (let i = 0; i < ans.length - 1; ++i) {
|
|
||||||
if (ans[i] == ps.OUT) ans[i] = ps.MAYBE;
|
|
||||||
}
|
|
||||||
//print("BYTYPE " + ans);
|
|
||||||
}
|
|
||||||
// Special case to catch string mutators. Note that they will never
|
|
||||||
// be so annotated in attributes.
|
|
||||||
if (is_func && is_string_mutator(callable)) {
|
|
||||||
ans[0] = ps.OUTNOFAIL;
|
|
||||||
}
|
|
||||||
// Special case for methods that return void.
|
|
||||||
if (TREE_CODE(TREE_TYPE(ftype)) == VOID_TYPE) {
|
|
||||||
for (let i = 0; i < ans.length; ++i) {
|
|
||||||
if (ans[i] == ps.OUT) ans[i] = ps.OUTNOFAIL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Analyze params
|
||||||
|
let ans = [];
|
||||||
|
for (let i = 0; i < types.length; ++i) {
|
||||||
|
let sem;
|
||||||
|
if (i == 0 && string_mutator) {
|
||||||
|
// Special case: string mutator receiver is an no-fail outparams
|
||||||
|
sem = ps.OUTNOFAIL;
|
||||||
|
} else {
|
||||||
|
if (params) sem = param_semantics(params[i]);
|
||||||
|
if (sem == undefined) {
|
||||||
|
sem = param_semantics_by_type(types[i]);
|
||||||
|
// Params other than last are guessed as MAYBE
|
||||||
|
if (i < types.length - 1 && sem == ps.OUT) sem = ps.MAYBE;
|
||||||
|
}
|
||||||
|
if (sem == ps.OUT && nofail) sem = ps.OUTNOFAIL;
|
||||||
|
}
|
||||||
|
if (ans == undefined) throw new Error("assert");
|
||||||
|
ans.push(sem);
|
||||||
|
}
|
||||||
return ans;
|
return ans;
|
||||||
};
|
}
|
||||||
|
|
||||||
// Return the param semantics as indicated by the attributes.
|
// Return the param semantics as indicated by the attributes, or
|
||||||
|
// undefined if no param attribute is present.
|
||||||
function param_semantics(decl) {
|
function param_semantics(decl) {
|
||||||
for each (let attr in rectify_attributes(DECL_ATTRIBUTES(decl))) {
|
for each (let attr in rectify_attributes(DECL_ATTRIBUTES(decl))) {
|
||||||
if (attr.name == 'user') {
|
if (attr.name == 'user') {
|
||||||
|
@ -689,14 +692,16 @@ function param_semantics(decl) {
|
||||||
return ps.OUT;
|
return ps.OUT;
|
||||||
} else if (arg == 'NS_inoutparam') {
|
} else if (arg == 'NS_inoutparam') {
|
||||||
return ps.INOUT;
|
return ps.INOUT;
|
||||||
|
} else if (arg == 'NS_inparam') {
|
||||||
|
return ps.CONST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ps.CONST;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return param semantics as guessed from types.
|
// Return param semantics as guessed from types. Never returns undefined.
|
||||||
function param_semantics_by_type(type) {
|
function param_semantics_by_type(type) {
|
||||||
switch (TREE_CODE(type)) {
|
switch (TREE_CODE(type)) {
|
||||||
case POINTER_TYPE:
|
case POINTER_TYPE:
|
||||||
|
|
|
@ -501,10 +501,12 @@ typedef PRUint32 nsrefcnt;
|
||||||
*/
|
*/
|
||||||
#ifdef NS_STATIC_CHECKING
|
#ifdef NS_STATIC_CHECKING
|
||||||
# define NS_SCRIPTABLE __attribute__((user("NS_script")))
|
# define NS_SCRIPTABLE __attribute__((user("NS_script")))
|
||||||
|
# define NS_INPARAM __attribute__((user("NS_inparam")))
|
||||||
# define NS_OUTPARAM __attribute__((user("NS_outparam")))
|
# define NS_OUTPARAM __attribute__((user("NS_outparam")))
|
||||||
# define NS_INOUTPARAM __attribute__((user("NS_inoutparam")))
|
# define NS_INOUTPARAM __attribute__((user("NS_inoutparam")))
|
||||||
#else
|
#else
|
||||||
# define NS_SCRIPTABLE
|
# define NS_SCRIPTABLE
|
||||||
|
# define NS_INPARAM
|
||||||
# define NS_OUTPARAM
|
# define NS_OUTPARAM
|
||||||
# define NS_INOUTPARAM
|
# define NS_INOUTPARAM
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -179,7 +179,7 @@ nsStringEnumerator::GetNext(nsACString& aResult)
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static inline nsresult
|
static inline nsresult
|
||||||
StringEnumeratorTail(T** aResult)
|
StringEnumeratorTail(T** aResult NS_INPARAM)
|
||||||
{
|
{
|
||||||
if (!*aResult)
|
if (!*aResult)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
|
@ -79,6 +79,7 @@ OUTPARAMS_PASS_TESTCASES = \
|
||||||
o8.cpp \
|
o8.cpp \
|
||||||
o9.cpp \
|
o9.cpp \
|
||||||
o10.cpp \
|
o10.cpp \
|
||||||
|
o11.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
typedef int PRUint32;
|
||||||
|
typedef int PRInt32;
|
||||||
|
|
||||||
|
typedef PRUint32 nsresult;
|
||||||
|
typedef short PRUnichar;
|
||||||
|
|
||||||
|
nsresult foo(int *p __attribute__((user("NS_inparam")))) {
|
||||||
|
return 0;
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче