This is an archive of the discontinued LLVM Phabricator instance.

[PATCH] Add clang-tidy check for static or thread_local objects where construction may throw
ClosedPublic

Authored by aaron.ballman on Nov 19 2015, 9:01 AM.

Details

Reviewers
alexfh
sbenza
Summary

Throwing an exception from the constructor of an object being used with static or thread_local storage duration is a dangerous operation. The exception thrown for an object with static storage duration cannot be caught, even by function-try-blocks in main, and the exception thrown for an object with thread_local storage duration cannot be caught by a function-try-block of the initial thread. This patch adds a checker to flag such constructs.

This check corresponds to the CERT secure coding rule: https://www.securecoding.cert.org/confluence/display/cplusplus/ERR58-CPP.+Constructors+of+objects+with+static+or+thread+storage+duration+must+not+throw+exceptions

Diff Detail

Event Timeline

aaron.ballman retitled this revision from to [PATCH] Add clang-tidy check for static or thread_local objects where construction may throw.
aaron.ballman updated this object.
aaron.ballman added reviewers: alexfh, sbenza.
aaron.ballman added a subscriber: cfe-commits.

Ensuring unresolved exception specifications are properly handled.

Btw, here are some statistics as to the rate at which this diagnostic is triggered:

LLVM: 21255 warnings (about 18000 warnings were due to two AST matcher constructors; adding noexcept to those brings the count to 2895 warnings, most of which are cl::opt-related and can be similarly silenced) (2.1MM LoC)
Qt: 0 warnings (4.4MM LoC)
rethinkdb: 44 warnings (5.7MM LoC)
cocos2d: 1339 warnings (984k LoC)
opencv: 203 warnings (657k LoC)

As best I can tell from random sampling, all of the diagnostics are true positives in that the compiler is unaware of whether the constructor will throw or not. However, many of these true positives come from user-provided constructors where the initializer list does all the work, and the constructor body is empty. In the samples I looked at, the constructors do not throw and can be marked noexcept to silence the warning. However, a few of the constructors can throw and this is a definite true positive instead of a practical false positive.

One possible heuristic to silence more of the warnings is to not warn when the constructor called is the default constructor accepting no arguments and the constructor body is trivial, with the belief that default initialization generally does not throw. However, I don't think this diagnostic is chatty enough to warrant that measure when the user can simply add noexcept to the constructor in the event it truly does not throw.

alexfh edited edge metadata.Nov 25 2015, 6:56 AM

Sorry for the delay, I was sick last week.

Looks mostly fine.

clang-tidy/cert/CERTTidyModule.cpp
19

Please sort includes.

clang-tidy/cert/StaticObjectExceptionCheck.cpp
19

ThrownExceptionTypeCheck.cpp defines a similar matcher. Looks like we need to move the isNothrow part to the ASTMatchers.h already.

clang-tidy/cert/StaticObjectExceptionCheck.h
19

Maybe address the FIXME right away? ;)

aaron.ballman edited edge metadata.
aaron.ballman marked 3 inline comments as done.

Updating patch based on review comments.

Sorry for the delay, I was sick last week.

No worries on the delay, I was sick the last two weeks as well. I hope you are feeling better!

clang-tidy/cert/StaticObjectExceptionCheck.cpp
19

Agreed; implemented.

clang-tidy/cert/StaticObjectExceptionCheck.h
19

LOL! Good catch. :-)

alexfh accepted this revision.Nov 30 2015, 4:04 PM
alexfh edited edge metadata.

LG

clang-tidy/utils/Matchers.h
26

Anything wrong with putting this to the astmatchers library?

This revision is now accepted and ready to land.Nov 30 2015, 4:04 PM
aaron.ballman closed this revision.Dec 1 2015, 6:09 AM

Commit in r254415.

clang-tidy/utils/Matchers.h
26

I may move that there post-commit because it seems general-purpose enough for that.