This is an archive of the discontinued LLVM Phabricator instance.

Add nonnull; use it for atomics
ClosedPublic

Authored by jfb on May 22 2018, 1:39 PM.

Details

Summary

The atomic non-member functions accept pointers to std::atomic / std::atomic_flag as well as to the non-atomic value. These are all dereferenced unconditionally when lowered, and therefore will fault if null. It's a tiny gotcha for new users, especially when they pass in NULL as expected value (instead of passing a pointer to a NULL value). We can therefore use the nonnull attribute to denote that:

  • A warning should be generated if the argument is null
  • It is undefined behavior if the argument is null (because a dereference will segfault)

This patch adds support for this attribute for clang and GCC, and sticks to the subset of the syntax both supports. In particular, work around this GCC oddity:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60625

The attributes are documented:

I've authored a companion clang patch for the c11_* and atomic_* builtins, which currently only warn on a subset of the pointer parameters. https://reviews.llvm.org/D47229

In all cases the check needs to be explicit and not use the empty nonnull list, because some of the overloads are for atomic<T*> and the values themselves are allowed to be null.

rdar://problem/18473124

Event Timeline

jfb created this revision.May 22 2018, 1:39 PM
jfb edited the summary of this revision. (Show Details)May 22 2018, 2:43 PM
arphaman accepted this revision.May 25 2018, 2:34 PM

LGTM

(FYI, Please use a weekly frequency for Pings).

This revision is now accepted and ready to land.May 25 2018, 2:34 PM
This revision was automatically updated to reflect the committed changes.
jfb added a comment.May 25 2018, 5:15 PM

GCC in libcxx-libcxxabi-x86_64-linux-ubuntu-cxx03 seems to mis-handle ATOMIC_VAR_INIT:

File /home/llvm-builder/llvm-buildslave-root/libcxx-libcxxabi-x86_64-linux-ubuntu-cxx03/llvm/projects/libcxx/test/libcxx/atomics/diagnose_nonnull.fail.cpp Line 20: non-aggregate type 'std::atomic<int>' cannot be initialized with an initializer list
File /home/llvm-builder/llvm-buildslave-root/libcxx-libcxxabi-x86_64-linux-ubuntu-cxx03/llvm/projects/libcxx/test/libcxx/atomics/diagnose_nonnull.fail.cpp Line 21: non-aggregate type 'volatile std::atomic<int>' cannot be initialized with an initializer list

I'll drop the initialization for now, it's not required anyways.