-
Michael Tautschnig authored
As discussed in the (virtual) community meeting on 2020-09-18, unreach-call may be turned into plain assertion checking. As first step, make the body of reach_error() `assert(0);`. For preprocessed files, the result of assert(0) expansion is what we get on Ubuntu 18.04 with glibc and GCC 7.5.0. This change was previously made in 7341f59b, which did not properly handle the case of reach_error not being defined in the main source file. This commit now only handle files that do define it in the main source file. Other tasks will be handled in a separate commit. The changes were done using the following command: ``` for f in c/*/*.c do export bn=$(basename $f .c) dn=$(dirname $f) test -e $dn/$bn.i export p=$? perl -i -e \ '$p = $ENV{p}; $i = 0; $e = 0; while(<>) { $i++; if(p == 0 && /^#include\s*<assert.h>/) { $p = 2; } elsif(p == 1 && /^extern void __assert_fail/) { $p = 3; } elsif(/^void reach_error\(\)\s*\{\}\s*$/) { if($p == 0) { print "#include <assert.h>\n"; $i++; $p = 2; } elsif($p == 1) { print "extern void __assert_fail(const char *, const char *, "; print "unsigned int, const char *) "; print "__attribute__ ((__nothrow__ , __leaf__)) "; print "__attribute__ ((__noreturn__));\n"; $i++; $p = 3; } if($p == 2) { print "void reach_error() { assert(0); }\n"; } elsif($p == 3) { print "void reach_error() { __assert_fail(\"0\", \""; print $ENV{bn}; print ".c\", $i, \"reach_error\"); }\n"; } $e = 1; next; } print; } exit $e;' \ $f && continue [ $p -eq 0 ] || continue export i=$(grep -n '^void reach_error' $f | cut -f1 -d:) perl -i -e \ '$p = 1; $i = $ENV{i} != "" ? $ENV{i} : 0; while(<>) { if(/^extern void __assert_fail/) { $p = 3; } elsif(/^void reach_error\(\)\s*\{\}\s*$/) { if($p == 1) { print <<'END_ASSERT'; extern void __assert_fail (const char *__assertion, const char *__file, unsigned int __line, const char *__function) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__)); extern void __assert_perror_fail (int __errnum, const char *__file, unsigned int __line, const char *__function) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__)); extern void __assert (const char *__assertion, const char *__file, int __line) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__)); END_ASSERT $p = 3; } if($p == 3) { print "void reach_error() { ((void) sizeof ((0) ? 1 : 0), "; print "__extension__ ({ if (0) ; else __assert_fail (\"0\", \""; print $ENV{bn}; print ".c\", $i, __extension__ __PRETTY_FUNCTION__); })); }\n"; } next; } print; }' \ $dn/$bn.i done ```
07dd9f37