Hi Aaron,

> 
>> - the second thing is this MaterializeTemporary advice that you gave. I 
>> don’t fully understand it (possibly due to a lack of understanding the AST 
>> and a lack of documentation of the proposed methods). Could you please flesh 
>> out your idea and why you think it is necessary? Or at least give an example 
>> where the current code does not work correctly.
> 
> 
> Consider code like:
> 
>  struct S {};
> 
>  S& g();
>  S h();
> 
>  void f() {
>    throw g(); // Should diagnose, does not currently
>    throw h(); // Should not diagnose, does not currently
>  }
> 
> "throw g();" isn't throwing a temporary because it's throwing from an lvalue 
> reference object (so the user may have a catch clause expecting the caught 
> object to be the same lvalue reference as what g() returns, except that's not 
> actually the case). If you instead check to see whether the throw expression 
> requires a temporary to be materialized, you'll find that g() will diagnose, 
> while h() still will not.
> 
> Does that help?
> 
yes. I added this to the test (you can find it here if required: 
https://github.com/iso8859-1/clang-tools-extra/blob/tobias-additional-checks/test/clang-tidy/misc-throw-by-value-catch-by-reference.cpp)
 and ran it through clang-query to check all throw statements. I found the 
following patterns:

Throw variants
y   throw->new = pointer from new
y/n throw->ImplicitCast->declrefexpr = throw named variable
n   throw->CXXConstructExpr (non-copy-constructor) = construction with normal 
parameter
n   throw->ImplicitCast->StringLiteral = throw string literal
n   throw->CXXConstructExpr (copy/move)->CallExpr (xvalue) = move
n   throw->CXXConstructExpr (copy/move)->MaterializeTemporary (xvalue)->Call
y   throw->CXXConstructExpr (copy/move)->ImplicitCast->CallExpr (lvalue)
n   throw->CXXConstructExpr (copy/move)->MaterializeTemporary (xvalue)->Call

the y or n or y/n means that we need to diagnose (the y/n depends on whether 
it’s a function parameter or catch parameter or not). When looking at the 
section with the copy construction, you’ll see that it depends on lvalue/xvalue 
(which you probably already knew). But MaterializeTemporary does not detect the 
T&& case.
My current thought is to go for “isLValue()” on Expr. It can be used for the 
CallExpr & the MaterializeTemporaryExpr alike and seems to capture the case 
where we want to diagnose for anonymous temporaries. What do you think?

Tobias

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to