From 6f96674cc0ce9c148d864fa69550e7c44d68d188 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Tue, 28 Jun 2022 09:14:37 +0000 Subject: [PATCH] C entry point generator: no unconditional conversion to pointer type Do not try to create a pointer_typet when the type might not actually be a pointer type. This was triggerable by syntactically well-formed C input and should instead be handled by a user-facing error message. Fixes: #6975 --- regression/ansi-c/main1/main.c | 4 ++++ regression/ansi-c/main1/test.desc | 11 +++++++++++ src/ansi-c/ansi_c_entry_point.cpp | 11 ++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 regression/ansi-c/main1/main.c create mode 100644 regression/ansi-c/main1/test.desc diff --git a/regression/ansi-c/main1/main.c b/regression/ansi-c/main1/main.c new file mode 100644 index 00000000000..1b685efc386 --- /dev/null +++ b/regression/ansi-c/main1/main.c @@ -0,0 +1,4 @@ +int main(char *argv, int arc) +{ + return 0; +} diff --git a/regression/ansi-c/main1/test.desc b/regression/ansi-c/main1/test.desc new file mode 100644 index 00000000000..a381531029f --- /dev/null +++ b/regression/ansi-c/main1/test.desc @@ -0,0 +1,11 @@ +CORE test-c++-front-end +main.c + +'main' with signature 'signed int \(char \*argv, signed int arc\)' found +^EXIT=(64|1)$ +^SIGNAL=0$ +-- +Invariant check failed +-- +This test is to ensure that non-standard C entry points are handled gracefully +and with a message to the user. diff --git a/src/ansi-c/ansi_c_entry_point.cpp b/src/ansi-c/ansi_c_entry_point.cpp index 62afc6c2ca5..9e1fd973bec 100644 --- a/src/ansi-c/ansi_c_entry_point.cpp +++ b/src/ansi-c/ansi_c_entry_point.cpp @@ -248,7 +248,16 @@ bool generate_ansi_c_start_function( { // ok } - else if(parameters.size()==2 || parameters.size()==3) + // The C standard (and any related architecture descriptions) enforces an + // order of parameters. The user, however, may supply arbitrary + // (syntactically valid) C code, even one that does not respect the calling + // conventions set out in the C standard. If the user does supply such code, + // then we can only tell them that they got it wrong, which is what we do + // via the error message in the else branch of this code. + else if( + parameters.size() >= 2 && parameters[1].type().id() == ID_pointer && + (parameters.size() == 2 || + (parameters.size() == 3 && parameters[2].type().id() == ID_pointer))) { namespacet ns(symbol_table);