From 4b46e0ec630531fa85d742706272525bebea49d2 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Tue, 12 Mar 2019 17:27:15 +0100 Subject: [PATCH] Handle corner case for abstract decls sometimes abstract decls in parameter lists left the returned name uninitialized potentially leading to segfaults, like in int f(int ()) { return 0; } Deal with this. --- tccgen.c | 4 +++- tests/tests2/60_errors_and_warnings.c | 11 +++++++++++ tests/tests2/60_errors_and_warnings.expect | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/tccgen.c b/tccgen.c index 84d4e851..6c3f0c70 100644 --- a/tccgen.c +++ b/tccgen.c @@ -4591,12 +4591,14 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) parse_attribute(ad); post = type_decl(type, ad, v, td); skip(')'); - } + } else + goto abstract; } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { /* type identifier */ *v = tok; next(); } else { + abstract: if (!(td & TYPE_ABSTRACT)) expect("identifier"); *v = 0; diff --git a/tests/tests2/60_errors_and_warnings.c b/tests/tests2/60_errors_and_warnings.c index cefaf73f..fa891af5 100644 --- a/tests/tests2/60_errors_and_warnings.c +++ b/tests/tests2/60_errors_and_warnings.c @@ -130,4 +130,15 @@ static enum myenum { L = -1 } L; void foo(void) { static enum myenum { L = -1 } L; } +#elif defined test_abstract_decls +int bar(const char *()); // abstract declarator here is okay +int bar (const char *(*g)()) // should match this 'g' argument +{ + g(); + return 42; +} +int foo(int ()) // abstract decl is wrong in definitions +{ + return 0; +} #endif diff --git a/tests/tests2/60_errors_and_warnings.expect b/tests/tests2/60_errors_and_warnings.expect index eaad7b9e..8fa6e998 100644 --- a/tests/tests2/60_errors_and_warnings.expect +++ b/tests/tests2/60_errors_and_warnings.expect @@ -59,3 +59,6 @@ [test_duplicate_def_2] 60_errors_and_warnings.c:131: error: redeclaration of 'L' + +[test_abstract_decls] +60_errors_and_warnings.c:141: error: identifier expected