[headerizer] Make the ASSERT_ARGS declaration look like the declaration From: Mark Glines of a local variable. This means we can put it at the very top of every function, for maximum usefulness. --- include/parrot/exceptions.h | 10 ++++++++++ tools/build/headerizer.pl | 8 ++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/parrot/exceptions.h b/include/parrot/exceptions.h index eb6f494..f46b404 100644 --- a/include/parrot/exceptions.h +++ b/include/parrot/exceptions.h @@ -259,6 +259,16 @@ void Parrot_print_backtrace(void); # define PARROT_ASSERT(x) (x) ? ((void)0) : Parrot_confess(#x, __FILE__, __LINE__) #endif +/* having a function version of this lets us put ASSERT_ARGS() at the top + * of the list of local variables. Thus, we can catch bad pointers before + * any of the local initialization logic is run. And it always returns 0, + * so headerizer can define the ASSERT_ARGS_* macros like: + * int _ASSERT_ARGS = PARROT_ASSERT_ARG(a) || PARROT_ASSERT_ARG(b) || ... + */ +static inline int PARROT_ASSERT_ARG(const void *x) { + PARROT_ASSERT(x); + return 0; +} #define ASSERT_ARGS(a) ASSERT_ARGS_ ## a diff --git a/tools/build/headerizer.pl b/tools/build/headerizer.pl index 8f7413b..a58ab8c 100644 --- a/tools/build/headerizer.pl +++ b/tools/build/headerizer.pl @@ -311,10 +311,10 @@ sub asserts_from_args { # strip off everything before the final space or asterisk. $var =~ s[.+[* ]([^* ]+)$][$1]; } - push( @asserts, "assert($var);" ); + push( @asserts, "PARROT_ASSERT_ARG($var)" ); } if( $arg eq 'PARROT_INTERP' ) { - push( @asserts, "assert(interp);" ); + push( @asserts, "PARROT_ASSERT_ARG(interp)" ); } } @@ -380,8 +380,8 @@ sub make_function_decls { my $assert = "#define ASSERT_ARGS_" . $func->{name}; if(@asserts) { - $assert .= ' '; - $assert .= join(" \\\n" . ' ' x length($assert), @asserts); + $assert .= " __attribute__unused__ int _ASSERT_ARGS_CHECK = \\\n "; + $assert .= join(" \\\n || ", @asserts); } push(@decls, $assert); }