aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@celest.fr>2013-09-16 14:48:33 +0200
committerThomas Preud'homme <robotux@celest.fr>2013-09-16 14:48:33 +0200
commit76cb1144ef91924c53c57ea71e6f67ce73ce1cc6 (patch)
tree9df80e9c6e5ed94a7753e1cc3c92334ec0994e8a
parent13b997668e32a4b451783fd80525cf221149c5b3 (diff)
downloadtinycc-76cb1144ef91924c53c57ea71e6f67ce73ce1cc6.tar.gz
tinycc-76cb1144ef91924c53c57ea71e6f67ce73ce1cc6.tar.bz2
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;}
-rw-r--r--tcc.h4
-rw-r--r--tccgen.c6
2 files changed, 9 insertions, 1 deletions
diff --git a/tcc.h b/tcc.h
index 98f28db..5ed3e21 100644
--- a/tcc.h
+++ b/tcc.h
@@ -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)
diff --git a/tccgen.c b/tccgen.c
index 4849b6c..a937358 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -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 */