Skip to content

Commit 94d2e79

Browse files
committed
fixup! Fully support aarch64 ABI's va_list struct
1 parent 132fabb commit 94d2e79

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -543,18 +543,26 @@ void c_typecheck_baset::typecheck_expr_builtin_va_arg(exprt &expr)
543543
// The first parameter is the va_list, and the second
544544
// is the type, which will need to be fixed and checked.
545545
// The type is given by the parser as type of the expression.
546-
547-
exprt arg = to_unary_expr(expr).op();
548-
auto typedef_id = arg.type().get(ID_C_typedef);
549-
if(
550-
typedef_id != "__builtin_va_list" && typedef_id != "__builtin_ms_va_list" &&
551-
typedef_id != "va_list")
546+
auto type_not_permitted = [this](const exprt &expr)
552547
{
548+
const exprt &arg = to_unary_expr(expr).op();
553549
error().source_location = expr.source_location();
554550
error() << "argument of type '" << to_string(arg.type())
555551
<< "' not permitted for va_arg" << eom;
556552
throw 0;
553+
};
554+
555+
exprt arg = to_unary_expr(expr).op();
556+
if(auto struct_tag_type = type_try_dynamic_cast<struct_tag_typet>(arg.type()))
557+
{
558+
// aarch64 ABI mandates that va_list has struct type with member names as
559+
// specified
560+
const auto &components = follow_tag(*struct_tag_type).components();
561+
if(components.size() != 5)
562+
type_not_permitted(expr);
557563
}
564+
else if(arg.type().id() != ID_pointer && arg.type().id() != ID_array)
565+
type_not_permitted(expr);
558566

559567
typet arg_type = expr.type();
560568
typecheck_type(arg_type);

0 commit comments

Comments
 (0)