| Issue |
177802
|
| Summary |
[LifetimeSafety] False-negative for non-trivially view types
|
| Labels |
false-negative,
clang:temporal-safety
|
| Assignees |
|
| Reporter |
usx95
|
No error in both the following cases:
```cpp
#include <string>
struct [[gsl::Pointer]] View {
View(const std::string&);
~View(); // Forces a CXXBindTemporaryExpr.
};
View foo(std::string a) {
return View(a);
}
View bar(std::string a) {
View b = View(a);
return b;
}
```
https://godbolt.org/z/GojcnrKEs
We did some work on the loans to temporaries but missed to handle `CXXBindTemporaryExpr` and `MaterializeTemporaryExpr` for propagating the view's origins.
AST:
```
TranslationUnitDecl
|-CXXRecordDecl <line:3:1, line:6:1> line:3:25 referenced struct View definition
| |-DefinitionData empty standard_layout has_user_declared_ctor can_const_default_init
| | |-DefaultConstructor defaulted_is_constexpr
| | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
| | |-MoveConstructor
| | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
| | |-MoveAssignment
| | `-Destructor non_trivial user_declared
| |-PointerAttr <col:10, col:15>
| |-CXXRecordDecl <col:1, col:25> col:25 implicit referenced struct View
| |-CXXConstructorDecl <line:4:5, col:28> col:5 used View 'void (const std::string &)'
| | `-ParmVarDecl <col:10, col:27> col:28 'const std::string &'
| |-CXXDestructorDecl <line:5:5, col:11> col:5 used ~View 'void () noexcept'
| `-CXXConstructorDecl <line:3:25> col:25 implicit used constexpr View 'void (const View &) noexcept' inline default trivial
| |-ParmVarDecl <col:25> col:25 'const View &'
| `-CompoundStmt <col:25>
|-FunctionDecl <line:8:1, line:10:1> line:8:6 foo 'View (std::string)'
| |-ParmVarDecl <col:10, col:22> col:22 used a 'std::string':'std::basic_string<char>' destroyed
| `-CompoundStmt <col:25, line:10:1>
| `-ReturnStmt <line:9:5, col:18>
| `-ExprWithCleanups <col:12, col:18> 'View'
| `-CXXFunctionalCastExpr <col:12, col:18> 'View' functional cast to View <ConstructorConversion>
| `-CXXBindTemporaryExpr <col:12, col:18> 'View' (CXXTemporary 0x3f784878)
| `-CXXConstructExpr <col:12, col:18> 'View' 'void (const std::string &)'
| `-ImplicitCastExpr <col:17> 'const std::string':'const std::basic_string<char>' lvalue <NoOp>
| `-DeclRefExpr <col:17> 'std::string':'std::basic_string<char>' lvalue ParmVar 0x3f7842c8 'a' 'std::string':'std::basic_string<char>'
`-FunctionDecl <line:12:1, line:15:1> line:12:6 bar 'View (std::string)'
|-ParmVarDecl <col:10, col:22> col:22 used a 'std::string':'std::basic_string<char>' destroyed
`-CompoundStmt <col:25, line:15:1>
|-DeclStmt <line:13:5, col:21>
| `-VarDecl <col:5, col:20> col:10 used b 'View' nrvo cinit destroyed
| `-ExprWithCleanups <col:14, col:20> 'View'
| `-CXXFunctionalCastExpr <col:14, col:20> 'View' functional cast to View <ConstructorConversion>
| `-CXXBindTemporaryExpr <col:14, col:20> 'View' (CXXTemporary 0x3f784bb8)
| `-CXXConstructExpr <col:14, col:20> 'View' 'void (const std::string &)'
| `-ImplicitCastExpr <col:19> 'const std::string':'const std::basic_string<char>' lvalue <NoOp>
| `-DeclRefExpr <col:19> 'std::string':'std::basic_string<char>' lvalue ParmVar 0x3f784938 'a' 'std::string':'std::basic_string<char>'
`-ReturnStmt <line:14:5, col:12> nrvo_candidate(Var 0x3f784ab0 'b' 'View')
`-CXXConstructExpr <col:12> 'View' 'void (const View &) noexcept'
`-ImplicitCastExpr <col:12> 'const View' xvalue <NoOp>
`-DeclRefExpr <col:12> 'View' lvalue Var 0x3f784ab0 'b' 'View'
```
Facts:
```
==========================================
Lifetime Analysis Facts:
==========================================
Function: bar
Block B2:
End of Block
Block B1:
Issue (0 (Path: a), ToOrigin: 0 (Expr: DeclRefExpr, Decl: a))
OriginFlow:
Dest: 1 (Expr: ImplicitCastExpr, Type : const std::string &)
Src: 0 (Expr: DeclRefExpr, Decl: a)
OriginFlow:
Dest: 2 (Expr: CXXConstructExpr, Type : View)
Src: 1 (Expr: ImplicitCastExpr, Type : const std::string &)
OriginFlow:
Dest: 4 (Expr: CXXFunctionalCastExpr, Type : View)
Src: 3 (Expr: CXXBindTemporaryExpr, Type : View)
OriginFlow:
Dest: 5 (Decl: b, Type : View)
Src: 4 (Expr: CXXFunctionalCastExpr, Type : View)
Use (5 (Decl: b, Type : View), Read)
Issue (1 (Path: b), ToOrigin: 6 (Expr: DeclRefExpr, Decl: b))
OriginFlow:
Dest: 7 (Expr: ImplicitCastExpr, Type : const View &)
Src: 6 (Expr: DeclRefExpr, Decl: b)
OriginFlow:
Dest: 8 (Expr: ImplicitCastExpr, Type : View)
Src: 5 (Decl: b, Type : View)
OriginFlow:
Dest: 9 (Expr: CXXConstructExpr, Type : View)
Src: 8 (Expr: ImplicitCastExpr, Type : View)
Expire (1 (Path: b))
Expire (0 (Path: a))
OriginEscapes (9 (Expr: CXXConstructExpr, Type : View))
End of Block
Block B0:
End of Block
Compiler returned: 0
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs