This is an archive of the discontinued LLVM Phabricator instance.

-fsanitize=noreturn sanitization
Needs RevisionPublic

Authored by jakubjelinek on Oct 17 2017, 12:42 PM.

Details

Reviewers
kcc
dvyukov
Summary

While both compilers have warnings when noreturn functions return or fall through to the end of function, the actual UB happens only if that actually happens at runtime,
so I think it makes sense to sanitize that (though, it is even worse UB than -fsanitize=return and it doesn't make any sense to try to recover from that, after all the compilers
won't do anything meaningful in the caller usually, it can end up in a different function or unrelated code etc.

No tests included, as this is just the library side, somebody from the LLVM camp would need to add (very simple) compiler changes.

Diff Detail

Repository
rL LLVM

Event Timeline

jakubjelinek created this revision.Oct 17 2017, 12:42 PM
kcc requested changes to this revision.Oct 17 2017, 3:57 PM
  • please CC llvm-dev for any sanitizer changes
  • please CC cfe-dev for any changes that need to be done in clang
  • we can't accepts a patch like this w/o tests and w/o clang part.

somebody from the LLVM camp would need to add (very simple) compiler changes.

Agree, but we'll need to find that somebody :)

This revision now requires changes to proceed.Oct 17 2017, 3:57 PM

I have no idea how to CC those mailing lists (Change Subscribers doesn't seem to allow those) in this tool (or shall I just mail them normally)?
As for tests, the ones I have for GCC are:

/* { dg-do run } */
/* { dg-shouldfail "ubsan" } */
/* { dg-options "-fsanitize=undefined" } */

#if __cplusplus >= 201103L
[[noreturn]]
#elif __STDC_VERSION__ >= 201112L
_Noreturn
#else
__attribute__((noreturn))
#endif
void
foo (int x)
{
}       /* { dg-warning "function does return" } */

int
main ()
{
  foo (2);
}

/* { dg-output "\.c:15:\[0-9]*:\[^\n\r]*return from function declared to never return" } */

and

/* { dg-do run } */
/* { dg-shouldfail "ubsan" } */
/* { dg-options "-fsanitize=noreturn" } */

#if __cplusplus >= 201103L
[[noreturn]]
#elif __STDC_VERSION__ >= 201112L
_Noreturn
#else
__attribute__((noreturn))
#endif
void
foo (int x)
{
  if (x < 2)
    __builtin_exit (0);
  return;	/* { dg-warning "function does return" } */
}		/* { dg-warning "function declared 'noreturn' has a 'return' statement" "" { target *-*-* } 17 } */

int
main ()
{
  foo (2);
}

/* { dg-output "\.c:17:\[0-9]*:\[^\n\r]*return from function declared to never return" } */