This is an archive of the discontinued LLVM Phabricator instance.

Improve -Winvalid-noreturn
ClosedPublic

Authored by rtrieu on May 1 2015, 6:55 PM.

Details

Summary

No longer warn on this false positive for -Winvalid-noreturn

__attribute__((noreturn)) void fail();

struct A {
  ~A() __attribute__((noreturn)) { fail(); }
};
struct B : A {
  B() {}
};

__attribute__((noreturn)) void test_1() { A a; }  // no warning
__attribute__((noreturn)) void test_2() { B b; }  // false positive warning here

A new method CXXDesctructorDecl:isAnyDestructorNoReturn that checks if any destructor invoked from the destructor is marked no return. This includes base classes, virtual base classes, and members. Then, replace use of FunctionDecl::isNoReturn with this new method when constructing the CFG.

Diff Detail

Event Timeline

rtrieu updated this revision to Diff 24852.May 1 2015, 6:55 PM
rtrieu retitled this revision from to Improve -Winvalid-noreturn.
rtrieu updated this object.
rtrieu edited the test plan for this revision. (Show Details)
rtrieu added a subscriber: Unknown Object (MLST).
rsmith added a subscriber: rsmith.May 1 2015, 7:25 PM
rsmith added inline comments.
lib/AST/DeclCXX.cpp
1940–1946

This seems redundant -- the previous loop already checked all direct bases -- and will be expensive because you'll check every virtual base once for each direct base that inherits from it directly or indirectly.

Maybe delete this loop and only check direct bases (recursively)?

1950

You should insert a getBaseElementTypeUnsafe() call here before grabbing the CXXRecordDecl, in case it's an array of class type.

rtrieu updated this revision to Diff 25110.May 6 2015, 5:00 PM
rtrieu updated this object.

Fix test case in summary. Address comments.

rtrieu added inline comments.May 6 2015, 5:01 PM
lib/AST/DeclCXX.cpp
1940–1946

Removed loop.

1950

Added call to get base element. Added array test case.

rtrieu updated this revision to Diff 26573.May 26 2015, 8:16 PM

Aaron Ballman brought up a point on the mailing list. CXXRecordDecl::getDestructor() can return null in some places. This patch restructures the isAnyDestructorNoReturn() to be on the CXXRecordDecl instead of on the CXXDestructorDecl. If the destructor does not exist, it is safe to assume it does not have the noreturn attribute.

This revision was automatically updated to reflect the committed changes.