Generate an error when a function is redefined

Use one more bit in AttributeDef to differenciate between declared
function (only its prototype is known) and defined function (its body is
also known). This allows to generate an error in cases like:

int f(){return 0;}
int f(){return 1;}
master
Thomas Preud'homme 2013-09-16 14:48:33 +02:00
parent 13b997668e
commit 76cb1144ef
2 changed files with 9 additions and 1 deletions

4
tcc.h
View File

@ -389,9 +389,10 @@ typedef struct AttributeDef {
func_export : 1,
func_import : 1,
func_args : 5,
func_proto : 1,
mode : 4,
weak : 1,
fill : 11;
fill : 10;
struct Section *section;
int alias_target; /* token */
} AttributeDef;
@ -401,6 +402,7 @@ typedef struct AttributeDef {
#define FUNC_EXPORT(r) (((AttributeDef*)&(r))->func_export)
#define FUNC_IMPORT(r) (((AttributeDef*)&(r))->func_import)
#define FUNC_ARGS(r) (((AttributeDef*)&(r))->func_args)
#define FUNC_PROTO(r) (((AttributeDef*)&(r))->func_proto)
#define FUNC_ALIGN(r) (((AttributeDef*)&(r))->aligned)
#define FUNC_PACKED(r) (((AttributeDef*)&(r))->packed)
#define ATTR_MODE(r) (((AttributeDef*)&(r))->mode)

View File

@ -5818,6 +5818,10 @@ static int decl0(int l, int is_for_loop_init)
goto func_error1;
r = sym->type.ref->r;
if (!FUNC_PROTO(r))
tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
/* use func_call from prototype if not defined */
if (FUNC_CALL(r) != FUNC_CDECL
&& FUNC_CALL(type.ref->r) == FUNC_CDECL)
@ -5836,6 +5840,7 @@ static int decl0(int l, int is_for_loop_init)
tcc_error("incompatible types for redefinition of '%s'",
get_tok_str(v, NULL));
}
FUNC_PROTO(type.ref->r) = 0;
/* if symbol is already defined, then put complete type */
sym->type = type;
} else {
@ -5901,6 +5906,7 @@ static int decl0(int l, int is_for_loop_init)
if ((type.t & VT_BTYPE) == VT_FUNC) {
/* external function definition */
/* specific case for func_call attribute */
ad.func_proto = 1;
type.ref->r = INT_ATTR(&ad);
} else if (!(type.t & VT_ARRAY)) {
/* not lvalue if array */