[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 Jan 10 13:47:11 PST 2023


lebedev.ri marked 2 inline comments as done.
lebedev.ri added inline comments.


================
Comment at: clang/include/clang/Basic/Attr.td:4138
+                             "functions and statements">;
+  let SimpleHandler = 1;
+}
----------------
aaron.ballman wrote:
> lebedev.ri wrote:
> > aaron.ballman wrote:
> > > lebedev.ri wrote:
> > > > aaron.ballman wrote:
> > > > > I would have guessed we'd want to help the user out in a case like: `[[clang::nounwind]] void func() noexcept(false);`, given that this stuff can creep in via macros?
> > > > Could you please clarify, what do you mean by "help the user" in this case?
> > > > Given
> > > > ```
> > > > [[clang::nounwind]] void func() noexcept(false);
> > > > 
> > > > void qqq();
> > > > 
> > > > void foo() {
> > > >   try {
> > > >     func();
> > > >   } catch (...) {
> > > >     qqq();
> > > >   }
> > > > }
> > > > ```
> > > > we already end up with
> > > > ```
> > > > ; Function Attrs: mustprogress noinline nounwind optnone uwtable
> > > > define dso_local void @_Z3foov() #0 {
> > > > entry:
> > > >   call void @_Z4funcv() #2
> > > >   ret void
> > > > }
> > > > 
> > > > ; Function Attrs: nounwind
> > > > declare void @_Z4funcv() #1
> > > > 
> > > > attributes #0 = { mustprogress noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
> > > > attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
> > > > attributes #2 = { nounwind }
> > > > ```
> > > > and if i drop `[[clang::nounwind]]`, `landingpad` is back.
> > > > Could you please clarify, what do you mean by "help the user" in this case?
> > > 
> > > The user has said "this function throws exceptions" (`noexcept(false)`) and it's also said "this function never unwinds to its caller" (the attribute) and these statements are in conflict with one another and likely signify user confusion. I would have expected a warning diagnostic here.
> > Ah. This is effectively intentional. This attribute, effectively,
> > specifies the behavior in case the exception does get thrown, as being UB.
> > If we diagnose that case, should we also disallow the stmt case?
> > ```
> > void i_will_throw() noexcept(false);
> > 
> > void foo() {
> >   [[clang::nounwind]] i_will_throw(); // Should this be diagnosed?
> > }
> > ```
> > Presumably not, because that immediately limits usefulness of the attribute.
> > 
> > What we *DO* want, is diagnostics (and more importantly, a sanitizer!)
> > in the case the exception *does* reach this UB boundary.
> Sorry if this is a dumb question, but is the goal of this attribute basically to insert UB where there is well-defined behavior per spec? Throwing an exception that escapes from a function marked `noexcept(false)` is guaranteed to call `std::terminate()`: http://eel.is/c++draft/except#spec-5
> Sorry if this is a dumb question, but is the goal of this attribute basically to insert UB where there is well-defined behavior per spec? 

Precisely! I was under impression i did call that out in the RFC/description, but guess not explicitly enough?
This is consistent with the existing (accidental) behavior of `const`/`pure` attirbutes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D138958/new/

https://reviews.llvm.org/D138958



More information about the llvm-commits mailing list