Hello,

Recently I found that Address Sanitizer reports wrong line information for the
code using try-finally blocks:

 1 #include <memory>
 2 char *get_str() { return (char *) malloc(10); }
 3 int main() {
 4  std::unique_ptr<char> l(new char);
 5  l.reset(get_str());
 6  get_str();
 7 }

ASan report tells

 #2 0x400d27 in std::unique_ptr<char, std::default_delete<char> 
>::~unique_ptr() include/g++-v6/bits/unique_ptr.h:239
 #3 0x400ac3 in main testcase.cxx:4

as if destructor was called from the line with constructor, such reports cause
misunderstandings of ASan users.

I tried to investigate the issue and found that end of "finally" block location
is intentionally set to UNKNOWN_LOCATION, there is a comment in
gcc/gimplify.c:11645 describing this behavior.

But then, after lowering on the eh pass (gcc/tree-eh.c:1161), the "finally"
location is set up to the `gimple_location (tf->try_finally_expr)' which
actually expands to "testcase.cxx:4", a place where the "try" block starts.

The dump testcase.cxx.009t.ehopt shows no location info for destructor:
 std::unique_ptr<char>::~unique_ptr (&lang);

And next testcase.cxx.010t.eh dump shows equal location for constructor and
destructor:
 [testcase.cxx:4:38] std::unique_ptr<char>::unique_ptr ([testcase.cxx:4:38] 
&lang, D.42272);
 [testcase.cxx:4:38] std::unique_ptr<char>::~unique_ptr (&lang);

I performed several experiments trying to get information about gimple_block
around the try_finally_expr statement right in `lower_try_finally_onedest', but
unsuccessfully. And also, as far as I understand, this issue should be fixed in
all the lowering functions, not only this one.

Where should I dig in order to fix the issue?

Best Regards,
Vyacheslav Barinov

Reply via email to