2007-10-11
2007-10-11 15:46:57 by Henrik Grubbström (Grubba) <grubba@grubba.org>
-
1f7f1720f35dafd43ad1963097f9ab9db3926da4
(157 lines)
(+118/-39)
[
Show
| Annotate
]
Branch: 7.9
Added some warnings for overloading symbols with nonmatching types.
Rev: src/program.c:1.622
2:
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
- || $Id: program.c,v 1.621 2007/09/29 15:09:02 grubba Exp $
+ || $Id: program.c,v 1.622 2007/10/11 15:46:57 grubba Exp $
*/
#include "global.h"
1931:
}
#endif
- int override_identifier (struct reference *ref, struct pike_string *name)
+ int override_identifier (struct reference *new_ref, struct pike_string *name)
{
- int id = -1, cur_id = 0;
+ int id = -1, cur_id = 0, is_used = 0;
int new_is_variable =
IDENTIFIER_IS_VARIABLE(ID_FROM_PTR(Pike_compiler->new_program,
- ref)->identifier_flags);
+ new_ref)->identifier_flags);
/* This loop could possibly be optimized by looping over
* each inherit and looking up 'name' in each inherit
1947:
for(;cur_id<Pike_compiler->new_program->num_identifier_references;cur_id++)
{
+ struct reference *ref =
+ Pike_compiler->new_program->identifier_references + cur_id;
+ struct identifier *i;
+
+ /* No need to do anything for ourselves. */
+ if (ref == new_ref) continue;
+
/* Do not zapp hidden identifiers */
- if(Pike_compiler->new_program->identifier_references[cur_id].id_flags & ID_HIDDEN)
- continue;
+ if(ref->id_flags & ID_HIDDEN) continue;
/* Do not zapp inherited inline ('local') identifiers */
- if((Pike_compiler->new_program->identifier_references[cur_id].id_flags &
- (ID_INLINE|ID_INHERITED)) == (ID_INLINE|ID_INHERITED))
+ if((ref->id_flags & (ID_INLINE|ID_INHERITED)) == (ID_INLINE|ID_INHERITED))
continue;
/* Do not zapp functions with the wrong name... */
- if(ID_FROM_INT(Pike_compiler->new_program, cur_id)->name != name)
+ if((i = ID_FROM_PTR(Pike_compiler->new_program, ref))->name != name)
continue;
#ifdef PROGRAM_BUILD_DEBUG
fprintf(stderr, "%.*soverloaded reference %d (id_flags:0x%04x)\n",
- compilation_depth, " ", cur_id,
- Pike_compiler->new_program->identifier_references[cur_id].id_flags);
+ compilation_depth, " ", cur_id, ref->id_flags);
#endif
- if (!new_is_variable &&
- IDENTIFIER_IS_VARIABLE(ID_FROM_INT(Pike_compiler->new_program,
- cur_id)->identifier_flags)) {
+ if (!new_is_variable && IDENTIFIER_IS_VARIABLE(i->identifier_flags)) {
/* Overloading a variable with a constant or a function.
* This is generally a bad idea.
*/
- Pike_compiler->new_program->identifier_references[cur_id].id_flags |=
- ID_INLINE|ID_HIDDEN;
+ ref->id_flags |= ID_INLINE|ID_HIDDEN;
yywarning("Attempt to override a non local variable %S "
- "with a non variable.", name);
+ "with a non-variable.", name);
continue;
}
- Pike_compiler->new_program->identifier_references[cur_id]=*ref;
+ if ((ref->id_flags & (ID_INHERITED|ID_USED)) == (ID_INHERITED|ID_USED)) {
+ struct inherit *inh = INHERIT_FROM_PTR(Pike_compiler->new_program, ref);
+ struct reference *sub_ref;
+
+ /* Find the inherit one level away. */
+ while (inh->inherit_level > 1) inh--;
+
+ #ifdef PIKE_DEBUG
+ if (!inh->inherit_level) {
+ Pike_fatal("Inherit without intermediate levels.\n");
+ }
+ #endif
+
+ sub_ref = PTR_FROM_INT(inh->prog, cur_id - inh->identifier_level);
+
+ /* Check if the symbol was used before it was inherited. */
+ if (sub_ref->id_flags & ID_USED) {
+ if (!pike_types_le(ID_FROM_PTR(inh->prog, sub_ref)->type,
+ ID_FROM_PTR(Pike_compiler->new_program,
+ new_ref)->type)) {
+ yywarning("Type mismatch when overloading %S.", name);
+ yytype_error(NULL,
+ ID_FROM_PTR(inh->prog, sub_ref)->type,
+ ID_FROM_PTR(Pike_compiler->new_program, new_ref)->type,
+ YYTE_IS_WARNING);
+ }
+ }
+ }
+ is_used = ref->id_flags & ID_USED;
+
+ *ref=*new_ref;
+ ref->id_flags |= is_used;
id = cur_id;
}
2017:
if (ref->id_flags & ID_HIDDEN) continue;
if (ref->inherit_offset != 0) continue;
override_identifier (ref, ID_FROM_PTR (p, ref)->name);
+
+ if ((ref->id_flags & (ID_HIDDEN|ID_PRIVATE|ID_USED)) == ID_PRIVATE) {
+ yywarning("%S is private but not used anywhere.",
+ ID_FROM_PTR(p, ref)->name);
}
-
+ }
/* Ok, sort for binsearch */
for(e=i=0;i<(int)p->num_identifier_references;i++)
2059:
if(funa_is_prototype && (funb->func.offset != -1) &&
!(funp->id_flags & ID_INLINE))
{
+ if (funp->id_flags & ID_USED) {
+ /* Verify that the types are compatible. */
+ if (!pike_types_le(fun->type, funb->type)) {
+ yywarning("Type mismatch when overloading %S.", fun->name);
+ yytype_error(NULL, fun->type, funb->type, YYTE_IS_WARNING);
+ }
+ }
funp->inherit_offset = funpb->inherit_offset;
funp->identifier_offset = funpb->identifier_offset;
}
if(!funa_is_prototype && funb->func.offset == -1)
{
-
+ if (funpb->id_flags & ID_USED) {
+ /* Verify that the types are compatible. */
+ if (!pike_types_le(funb->type, fun->type)) {
+ yywarning("Type mismatch when overloading %S.", fun->name);
+ yytype_error(NULL, funb->type, fun->type, YYTE_IS_WARNING);
+ }
+ }
funpb->inherit_offset = funp->inherit_offset;
funpb->identifier_offset = funp->identifier_offset;
}
3672:
struct reference *refp;
refp = np->identifier_references + d;
- if(!MEMCMP((char *)refp,(char *)&funp,sizeof funp)) return d;
+ if ((refp->inherit_offset == funp.inherit_offset) &&
+ (refp->identifier_offset == funp.identifier_offset) &&
+ ((refp->id_flags | ID_USED) == (funp.id_flags | ID_USED)))
+ return d;
}
if(q)
4576:
n=make_shared_string(name);
t=parse_type(type);
- ret=low_define_variable(n,t,flags,offset,run_time_type);
+ ret=low_define_variable(n,t,flags|ID_USED,offset,run_time_type);
free_string(n);
free_type(t);
return ret;
4609:
}
#endif
- ret=low_define_variable(n,t,flags,offset,run_time_type);
+ ret=low_define_variable(n,t,flags|ID_USED,offset,run_time_type);
free_string(n);
free_type(t);
return ret;
4988:
/* override */
if ((overridden = override_identifier (&ref, name)) >= 0) {
#ifdef PIKE_DEBUG
- if(MEMCMP(Pike_compiler->new_program->identifier_references+n, &ref,sizeof(ref)))
+ struct reference *oref =
+ Pike_compiler->new_program->identifier_references+overridden;
+ if((oref->inherit_offset != ref.inherit_offset) ||
+ (oref->identifier_offset != ref.identifier_offset) ||
+ ((oref->id_flags | ID_USED) != (ref.id_flags | ID_USED))) {
Pike_fatal("New constant overriding algorithm failed!\n");
-
+ }
#endif
return overridden;
}
5257:
my_yyerror("Illegal to redefine a current variable with a getter/setter: %S.", symbol);
getter_setter_offset = -1;
} else {
- if (ref->id_flags != flags) {
+ if ((ref->id_flags | ID_USED) != (flags | ID_USED)) {
if (Pike_compiler->compiler_pass == 1) {
yywarning("Modifier mismatch for variable %S.", symbol);
}
- ref->id_flags &= flags;
+ ref->id_flags &= flags | ID_USED;
}
getter_setter_offset += id->func.offset;
}
5422:
ref.id_flags = flags;
if ((overridden = override_identifier (&ref, name)) >= 0) {
#ifdef PIKE_DEBUG
- if(MEMCMP(Pike_compiler->new_program->identifier_references+i, &ref,sizeof(ref)))
+ struct reference *oref =
+ Pike_compiler->new_program->identifier_references+overridden;
+ if((oref->inherit_offset != ref.inherit_offset) ||
+ (oref->identifier_offset != ref.identifier_offset) ||
+ ((oref->id_flags | ID_USED) != (ref.id_flags | ID_USED))) {
+ fprintf(stderr,
+ "ref: %d:%d 0x%04x\n"
+ "got: %d:%d 0x%04x (%d)\n",
+ ref.inherit_offset, ref.identifier_offset,
+ ref.id_flags,
+ oref->inherit_offset,
+ oref->identifier_offset,
+ oref->id_flags,
+ overridden);
Pike_fatal("New function overloading algorithm failed!\n");
-
+ }
#endif
if (getter_setter_offset >= 0) {
5513: Inside #if 0
for (r = state->new_program->identifier_references, j = 0;
j < state->new_program->num_identifier_references;
j++, r++) {
- if (((r->id_flags & ID_PARENT_REF|ID_STATIC|ID_PRIVATE|ID_HIDDEN) ==
+ if (((r->id_flags & (ID_PARENT_REF|ID_STATIC|ID_PRIVATE|ID_HIDDEN)) ==
ID_PARENT_REF|ID_STATIC|ID_PRIVATE|ID_HIDDEN) &&
(r->identifier_offset == i) &&
(!(r->inherit_offset))) {
6244: Inside #if defined(PIKE_DEBUG)
if(Pike_compiler->last_line != line ||
Pike_compiler->last_pc != off ||
(Pike_compiler->last_file && file &&
- memcmp(Pike_compiler->last_file->str, file, len<<shift)))
+ MEMCMP(Pike_compiler->last_file->str, file, len<<shift)))
{
Pike_fatal("Line numbering out of whack\n"
" (line : %d ?= %d)!\n"
8306:
void yywarning(char *fmt, ...)
{
+ struct string_builder s;
+ struct pike_string *msg;
+ va_list args;
+
/* If we have parse errors we might get erroneous warnings,
* so don't print them.
* This has the additional benefit of making it easier to
8313:
*/
if (Pike_compiler->num_parse_error) return;
- /* Don't bother generating the warning message if we don't have
- * anywhere to report it...
- */
- if ((error_handler && error_handler->prog) || get_master()) {
- struct string_builder s;
- va_list args;
-
+
init_string_builder(&s, 0);
va_start(args,fmt);
string_builder_vsprintf(&s, fmt, args);
va_end(args);
-
+ msg = finish_string_builder(&s);
-
+ if (master_object) {
ref_push_string(lex.current_file);
push_int(lex.current_line);
- push_string(finish_string_builder(&s));
+ push_string(msg);
low_safe_apply_handler("compile_warning",
error_handler, compat_handler, 3);
pop_stack();
-
+ } else {
+ if (!msg->size_shift) {
+ fprintf(stderr, "%s:%d: Warning: %s\n",
+ lex.current_file->str, lex.current_line, msg->str);
}
-
+ free_string(msg);
}
-
+ }