[PATCH] D138958: [clang] Better UX for Clang’s unwind-affecting attributes

Roman Lebedev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 29 15:53:40 PST 2022


lebedev.ri created this revision.
lebedev.ri added reviewers: aaron.ballman, erichkeane, rjmccall.
lebedev.ri added a project: LLVM.
Herald added subscribers: carlosgalvezp, jdoerfert.
Herald added a reviewer: NoQ.
Herald added a reviewer: njames93.
Herald added a project: All.
lebedev.ri requested review of this revision.
Herald added projects: clang, clang-tools-extra.
Herald added a subscriber: cfe-commits.

This is an implementation of the following RFC:
https://discourse.llvm.org/t/rfc-better-ux-for-clangs-unwind-affecting-attributes/66890

In C++, there are 3 possible behaviors when the
exception escapes out an function that can not unwind:

1. exception propagates into function's caller
2. defined behavior of immediate program termination
3. the wild UB case, behavior is undefined.

Let's look at obvious examples:

1. exception propagates into caller, is caught there, and all is good: https://godbolt.org/z/MbTW9rofn
2. exception can not exit `noexcept` function, program is terminated: https://godbolt.org/z/ffeaPz1dK

Now, the third case, the wild UB case, is the most interesting one.
There are 3 clang/gcc attributes that are relevant here, let's look at them:

1. `__attribute__((pure))`: https://godbolt.org/z/PY3KrETb7, there the fun begins. In clang, we get UB, in gcc we get "exception propagates into function's caller"
2. `__attribute__((const))`: https://godbolt.org/z/ozxoW16e9, same as `__attribute__((pure))`
3. `__attribute__((nothrow))`: https://godbolt.org/z/YMf4sTcfa, the behavior is consistently defined as immediate program termination. I do not understand why it was defined as such, in the sense of how is that different from plain `noexcept`, but at least we are consistent.

Now, there are 3 problems:

1. Our modelling of `__attribute__((const))`/`__attribute__((pure))` differs from that of GCC, we add UB.
2. We can not ask for `__attribute__((const))`/`__attribute__((pure))` behavior, without it acting as exception barrier.
3. We can not separately ask for the exception propagation to be UB. This would be a handy optimization tool, especially given how brittle our IRGen for the case 2. (program termination) is.

Therefore, this patch does two things:

1. Match GCC's implementation-defined behavior on `__attribute__((pure))`/`__attribute__((const))`
  - they should not cause UB on exception escape, nor should they cause immediate program termination, exceptions should be free to escape into their caller.
2. Introduce `__attribute__((nounwind))`, which would be lowered into LLVM IR's `nounwind` attribute, and if an exception escapes out of an function marked with such an attribute, wild UB happens.

Please note, while currently such an UB is indeed not sanitized,
i have a patch in progress to handle it:
https://reviews.llvm.org/D137381,
so we would not be introducing something that is impossible to deal with.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D138958

Files:
  clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/Builtins.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Analysis/CFG.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/Sema/AnalysisBasedWarnings.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaStmtAttr.cpp
  clang/test/CodeGen/function-attributes.c
  clang/test/CodeGen/struct-passing.c
  clang/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp
  clang/test/CodeGenCXX/exception-escape-RAII-codegen.cpp
  clang/test/CodeGenCXX/exception-escape-codegen.cpp
  clang/test/CodeGenCXX/pr58798.cpp
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/SemaCXX/warn-throw-out-noexcept-func.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D138958.478746.patch
Type: text/x-patch
Size: 86807 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221129/84bd8430/attachment.bin>


More information about the llvm-commits mailing list