зеркало из https://github.com/mozilla/gecko-dev.git
Fix to 54913. Add check against 'const unsigned long = -4', and centralize many const checks in xpidl_util.c from the various xpidl backends.
This'll cause the tree to rebuild. sr=jband.
This commit is contained in:
Родитель
98ea682e03
Коммит
54b6fe9784
|
@ -204,6 +204,13 @@ xpidl_parse_iid(nsID *id, const char *str);
|
|||
IDL_tree /* IDL_TYPE_DCL */
|
||||
find_underlying_type(IDL_tree typedef_ident);
|
||||
|
||||
/*
|
||||
* Check that const declarations match their stated sign and are of the
|
||||
* appropriate types.
|
||||
*/
|
||||
gboolean
|
||||
verify_const_declaration(IDL_tree const_tree);
|
||||
|
||||
/*
|
||||
* Check that scriptable attributes in scriptable interfaces actually are.
|
||||
*/
|
||||
|
|
|
@ -728,53 +728,30 @@ do_const_dcl(TreeState *state)
|
|||
{
|
||||
struct _IDL_CONST_DCL *dcl = &IDL_CONST_DCL(state->tree);
|
||||
const char *name = IDL_IDENT(dcl->ident).str;
|
||||
gboolean success, is_signed;
|
||||
gboolean is_signed;
|
||||
GSList *doc_comments = IDL_IDENT(dcl->ident).comments;
|
||||
IDL_tree real_type;
|
||||
const char *const_format;
|
||||
|
||||
/* const -> list -> interface */
|
||||
if (!IDL_NODE_UP(IDL_NODE_UP(state->tree)) ||
|
||||
IDL_NODE_TYPE(IDL_NODE_UP(IDL_NODE_UP(state->tree)))
|
||||
!= IDLN_INTERFACE) {
|
||||
XPIDL_WARNING((state->tree, IDL_WARNING1,
|
||||
"const decl \'%s\' not inside interface, ignored",
|
||||
name));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Could be a typedef; try to map it to the real type. */
|
||||
real_type = find_underlying_type(dcl->const_type);
|
||||
real_type = real_type ? real_type : dcl->const_type;
|
||||
success = (IDLN_TYPE_INTEGER == IDL_NODE_TYPE(real_type));
|
||||
if (success) {
|
||||
switch(IDL_TYPE_INTEGER(real_type).f_type) {
|
||||
case IDL_INTEGER_TYPE_SHORT:
|
||||
case IDL_INTEGER_TYPE_LONG:
|
||||
break;
|
||||
default:
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
is_signed = IDL_TYPE_INTEGER(real_type).f_signed;
|
||||
}
|
||||
if (!verify_const_declaration(state->tree))
|
||||
return FALSE;
|
||||
|
||||
if (doc_comments != NULL) {
|
||||
write_indent(state->file);
|
||||
printlist(state->file, doc_comments);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
const char *const_format = is_signed ? "%" IDL_LL "d" : "%" IDL_LL "uU";
|
||||
write_indent(state->file);
|
||||
fprintf(state->file, "enum { %s = ", name);
|
||||
fprintf(state->file, const_format, IDL_INTEGER(dcl->const_exp).value);
|
||||
fprintf(state->file, " };\n\n");
|
||||
} else {
|
||||
IDL_tree_error(state->tree,
|
||||
"const declaration \'%s\' must be of type short or long",
|
||||
name);
|
||||
return FALSE;
|
||||
}
|
||||
/* Could be a typedef; try to map it to the real type. */
|
||||
real_type = find_underlying_type(dcl->const_type);
|
||||
real_type = real_type ? real_type : dcl->const_type;
|
||||
is_signed = IDL_TYPE_INTEGER(real_type).f_signed;
|
||||
|
||||
const_format = is_signed ? "%" IDL_LL "d" : "%" IDL_LL "uU";
|
||||
write_indent(state->file);
|
||||
fprintf(state->file, "enum { %s = ", name);
|
||||
fprintf(state->file, const_format, IDL_INTEGER(dcl->const_exp).value);
|
||||
fprintf(state->file, " };\n\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -559,80 +559,25 @@ method_declaration(TreeState *state)
|
|||
static gboolean
|
||||
constant_declaration(TreeState *state)
|
||||
{
|
||||
/*
|
||||
* The C++ header XPIDL module only allows for shorts and longs (ints)
|
||||
* to be constants, so we will follow the same convention
|
||||
*/
|
||||
|
||||
struct _IDL_CONST_DCL *declaration = &IDL_CONST_DCL(state->tree);
|
||||
const char *name = IDL_IDENT(declaration->ident).str;
|
||||
IDL_tree real_type;
|
||||
const char *const_format;
|
||||
|
||||
gboolean success;
|
||||
gboolean isshort = FALSE;
|
||||
if (!verify_const_declaration(state->tree))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Consts must be in an interface
|
||||
*/
|
||||
/* Could be a typedef; try to map it to the real type. */
|
||||
real_type = find_underlying_type(declaration->const_type);
|
||||
real_type = real_type ? real_type : declaration->const_type;
|
||||
|
||||
if (!IDL_NODE_UP(IDL_NODE_UP(state->tree)) ||
|
||||
IDL_NODE_TYPE(IDL_NODE_UP(IDL_NODE_UP(state->tree))) !=
|
||||
IDLN_INTERFACE) {
|
||||
fputc('\n', state->file);
|
||||
xpidl_write_comment(state, 4);
|
||||
|
||||
XPIDL_WARNING((state->tree, IDL_WARNING1,
|
||||
"A constant \"%s\" was declared outside an interface."
|
||||
" It was ignored.", name));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure this is a numeric short or long constant.
|
||||
*/
|
||||
|
||||
success = (IDLN_TYPE_INTEGER == IDL_NODE_TYPE(declaration->const_type));
|
||||
|
||||
if (success) {
|
||||
/*
|
||||
* We aren't successful yet, we know it's an integer, but what *kind*
|
||||
* of integer?
|
||||
*/
|
||||
|
||||
switch(IDL_TYPE_INTEGER(declaration->const_type).f_type) {
|
||||
|
||||
case IDL_INTEGER_TYPE_SHORT:
|
||||
/*
|
||||
* We're OK
|
||||
*/
|
||||
isshort = TRUE;
|
||||
break;
|
||||
|
||||
case IDL_INTEGER_TYPE_LONG:
|
||||
/*
|
||||
* We're OK
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* Whoops, it's some other kind of number
|
||||
*/
|
||||
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
fputc('\n', state->file);
|
||||
xpidl_write_comment(state, 4);
|
||||
|
||||
fprintf(state->file, " public static final %s %s = %d;\n",
|
||||
(isshort ? "short" : "int"),
|
||||
name, (int) IDL_INTEGER(declaration->const_exp).value);
|
||||
} else {
|
||||
XPIDL_WARNING((state->tree, IDL_WARNING1,
|
||||
"A constant \"%s\" was not of type short or long."
|
||||
" It was ignored.", name));
|
||||
}
|
||||
fprintf(state->file, " public static final %s %s = %d;\n",
|
||||
(IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG
|
||||
? "long" : "short"),
|
||||
name, (int) IDL_INTEGER(declaration->const_exp).value);
|
||||
|
||||
return TRUE;
|
||||
|
||||
|
|
|
@ -1105,76 +1105,47 @@ typelib_const_dcl(TreeState *state)
|
|||
{
|
||||
struct _IDL_CONST_DCL *dcl = &IDL_CONST_DCL(state->tree);
|
||||
const char *name = IDL_IDENT(dcl->ident).str;
|
||||
gboolean success;
|
||||
gboolean is_long;
|
||||
gboolean sign;
|
||||
IDL_tree real_type;
|
||||
XPTInterfaceDescriptor *id;
|
||||
XPTConstDescriptor *cd;
|
||||
IDL_longlong_t value;
|
||||
|
||||
/* const -> list -> interface */
|
||||
if (!IDL_NODE_UP(IDL_NODE_UP(state->tree)) ||
|
||||
IDL_NODE_TYPE(IDL_NODE_UP(IDL_NODE_UP(state->tree)))
|
||||
!= IDLN_INTERFACE) {
|
||||
XPIDL_WARNING((state->tree, IDL_WARNING1,
|
||||
"const decl \'%s\' not inside interface, ignored",
|
||||
name));
|
||||
return TRUE;
|
||||
}
|
||||
if (!verify_const_declaration(state->tree))
|
||||
return FALSE;
|
||||
|
||||
/* Could be a typedef; try to map it to the real type. */
|
||||
real_type = find_underlying_type(dcl->const_type);
|
||||
real_type = real_type ? real_type : dcl->const_type;
|
||||
success = (IDLN_TYPE_INTEGER == IDL_NODE_TYPE(real_type));
|
||||
if(success) {
|
||||
switch(IDL_TYPE_INTEGER(real_type).f_type) {
|
||||
case IDL_INTEGER_TYPE_SHORT:
|
||||
is_long = FALSE;
|
||||
break;
|
||||
case IDL_INTEGER_TYPE_LONG:
|
||||
is_long = TRUE;
|
||||
break;
|
||||
default:
|
||||
is_long = FALSE; /* quell warning. */
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
is_long = (IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG);
|
||||
|
||||
if(success) {
|
||||
XPTInterfaceDescriptor *id;
|
||||
XPTConstDescriptor *cd;
|
||||
IDL_longlong_t value;
|
||||
gboolean sign;
|
||||
|
||||
id = CURRENT(state);
|
||||
if (!XPT_InterfaceDescriptorAddConsts(ARENA(state), id, 1))
|
||||
return FALSE;
|
||||
cd = &id->const_descriptors[NEXT_CONST(state)];
|
||||
|
||||
cd->name = IDL_IDENT(dcl->ident).str;
|
||||
#ifdef DEBUG_shaver_const
|
||||
fprintf(stderr, "DBG: adding const %s\n", cd->name);
|
||||
#endif
|
||||
if (!fill_td_from_type(state, &cd->type, dcl->const_type))
|
||||
return FALSE;
|
||||
|
||||
value = IDL_INTEGER(dcl->const_exp).value;
|
||||
sign = IDL_TYPE_INTEGER(dcl->const_type).f_signed;
|
||||
if (is_long) {
|
||||
if(sign)
|
||||
cd->value.i32 = value;
|
||||
else
|
||||
cd->value.ui32 = value;
|
||||
} else {
|
||||
if(sign)
|
||||
cd->value.i16 = value;
|
||||
else
|
||||
cd->value.ui16 = value;
|
||||
}
|
||||
NEXT_CONST(state)++;
|
||||
} else {
|
||||
IDL_tree_error(state->tree,
|
||||
"const declaration \'%s\' must be of type short or long",
|
||||
name);
|
||||
id = CURRENT(state);
|
||||
if (!XPT_InterfaceDescriptorAddConsts(ARENA(state), id, 1))
|
||||
return FALSE;
|
||||
cd = &id->const_descriptors[NEXT_CONST(state)];
|
||||
|
||||
cd->name = IDL_IDENT(dcl->ident).str;
|
||||
#ifdef DEBUG_shaver_const
|
||||
fprintf(stderr, "DBG: adding const %s\n", cd->name);
|
||||
#endif
|
||||
if (!fill_td_from_type(state, &cd->type, dcl->const_type))
|
||||
return FALSE;
|
||||
|
||||
value = IDL_INTEGER(dcl->const_exp).value;
|
||||
sign = IDL_TYPE_INTEGER(dcl->const_type).f_signed;
|
||||
if (is_long) {
|
||||
if(sign)
|
||||
cd->value.i32 = value;
|
||||
else
|
||||
cd->value.ui32 = value;
|
||||
} else {
|
||||
if(sign)
|
||||
cd->value.i16 = value;
|
||||
else
|
||||
cd->value.ui16 = value;
|
||||
}
|
||||
NEXT_CONST(state)++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,49 @@ xpidl_parse_iid(nsID *id, const char *str)
|
|||
return (gboolean)(count == 11);
|
||||
}
|
||||
|
||||
gboolean
|
||||
verify_const_declaration(IDL_tree const_tree) {
|
||||
struct _IDL_CONST_DCL *dcl = &IDL_CONST_DCL(const_tree);
|
||||
const char *name = IDL_IDENT(dcl->ident).str;
|
||||
IDL_tree real_type;
|
||||
|
||||
/* const -> list -> interface */
|
||||
if (!IDL_NODE_UP(IDL_NODE_UP(const_tree)) ||
|
||||
IDL_NODE_TYPE(IDL_NODE_UP(IDL_NODE_UP(const_tree)))
|
||||
!= IDLN_INTERFACE) {
|
||||
IDL_tree_error(const_tree,
|
||||
"const declaration \'%s\' outside interface",
|
||||
name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Could be a typedef; try to map it to the real type. */
|
||||
real_type = find_underlying_type(dcl->const_type);
|
||||
real_type = real_type ? real_type : dcl->const_type;
|
||||
if (IDL_NODE_TYPE(real_type) == IDLN_TYPE_INTEGER &&
|
||||
(IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_SHORT ||
|
||||
IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG))
|
||||
{
|
||||
if (!IDL_TYPE_INTEGER(real_type).f_signed &&
|
||||
IDL_INTEGER(dcl->const_exp).value < 0)
|
||||
{
|
||||
IDL_tree_error(const_tree,
|
||||
"unsigned const declaration \'%s\' initialized with "
|
||||
"negative constant",
|
||||
name);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
IDL_tree_error(const_tree,
|
||||
"const declaration \'%s\' must be of type short or long",
|
||||
name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
verify_attribute_declaration(IDL_tree attr_tree)
|
||||
{
|
||||
|
@ -206,7 +249,6 @@ verify_attribute_declaration(IDL_tree attr_tree)
|
|||
*
|
||||
* All the needed tree-walking seems pretty shaky; isn't there something in
|
||||
* libIDL to automate this?
|
||||
* Might want to export this to handle the bug against no typedef'd const.
|
||||
*/
|
||||
IDL_tree /* IDL_TYPE_DCL */
|
||||
find_underlying_type(IDL_tree typedef_ident)
|
||||
|
|
Загрузка…
Ссылка в новой задаче