Skip to content

Commit 4802191

Browse files
committed
GCC asm function calls: fix number of arguments
An inline asm statement may include multiple commands that take a varying number of inputs or outputs. When we replace a command by a function call, we need to use the correct number of arguments. Fixes: #8165
1 parent b6f5506 commit 4802191

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

src/assembler/remove_asm.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class remove_asmt
6262
void gcc_asm_function_call(
6363
const irep_idt &function_base_name,
6464
const code_asm_gcct &code,
65+
std::size_t n_args,
6566
goto_programt &dest);
6667

6768
void msc_asm_function_call(
@@ -77,10 +78,12 @@ class remove_asmt
7778
/// \param function_base_name: Name of the function to call
7879
/// \param code: gcc-style inline assembly statement to translate to function
7980
/// call
81+
/// \param n_args: Number of arguments required by \p function_base_name
8082
/// \param dest: Goto program to append the function call to
8183
void remove_asmt::gcc_asm_function_call(
8284
const irep_idt &function_base_name,
8385
const code_asm_gcct &code,
86+
std::size_t n_args,
8487
goto_programt &dest)
8588
{
8689
irep_idt function_identifier = function_base_name;
@@ -109,6 +112,16 @@ void remove_asmt::gcc_asm_function_call(
109112
}
110113
}
111114

115+
// An inline asm statement may consist of multiple commands, not all of which
116+
// use all of the inputs/outputs of the inline asm statement.
117+
DATA_INVARIANT_WITH_DIAGNOSTICS(
118+
arguments.size() >= n_args,
119+
"insufficient number of arguments for calling " +
120+
id2string(function_identifier),
121+
"required arguments: " + std::to_string(n_args),
122+
code.pretty());
123+
arguments.resize(n_args);
124+
112125
code_typet fkt_type{
113126
code_typet::parameterst{
114127
arguments.size(), code_typet::parametert{void_pointer}},
@@ -133,9 +146,12 @@ void remove_asmt::gcc_asm_function_call(
133146
}
134147
else
135148
{
136-
DATA_INVARIANT(
149+
DATA_INVARIANT_WITH_DIAGNOSTICS(
137150
symbol_table.lookup_ref(function_identifier).type == fkt_type,
138-
"function types should match");
151+
"types of function " + id2string(function_identifier) + " should match",
152+
code.pretty(),
153+
symbol_table.lookup_ref(function_identifier).type.pretty(),
154+
fkt_type.pretty());
139155
}
140156
}
141157

@@ -293,12 +309,12 @@ void remove_asmt::process_instruction_gcc(
293309

294310
if(command == "fstcw" || command == "fnstcw" || command == "fldcw") // x86
295311
{
296-
gcc_asm_function_call("__asm_" + id2string(command), code, tmp_dest);
312+
gcc_asm_function_call("__asm_" + id2string(command), code, 1, tmp_dest);
297313
}
298314
else if(
299315
command == "mfence" || command == "lfence" || command == "sfence") // x86
300316
{
301-
gcc_asm_function_call("__asm_" + id2string(command), code, tmp_dest);
317+
gcc_asm_function_call("__asm_" + id2string(command), code, 0, tmp_dest);
302318
}
303319
else if(command == ID_sync) // Power
304320
{

0 commit comments

Comments
 (0)