CPP: Fix handling of ternary operators in tempory queries and add tests.

This commit is contained in:
Alex Eyers-Taylor
2023-12-15 11:03:23 +00:00
parent 236a6a1bce
commit 49e1467581
5 changed files with 20 additions and 3 deletions

View File

@@ -41,12 +41,21 @@ predicate isStoredInContainer(Expr e) {
)
}
/**
* Holds if `e` or a conversion of `e` has an lvalue-to-rvalue conversion.
*/
predicate hasLValueToRValueConversion(Expr e) {
e.getConversion*().hasLValueToRValueConversion() and
not e instanceof ConditionalExpr // ConditionalExpr may be spuriously reported as having an lvalue-to-rvalue conversion
}
/**
* Holds if the value of `e` outlives the enclosing full expression. For
* example, because the value is stored in a local variable.
*/
predicate outlivesFullExpr(Expr e) {
not e.getConversion*().hasLValueToRValueConversion() and
not hasLValueToRValueConversion(e) and
(
any(Assignment assign).getRValue() = e
or

View File

@@ -9,4 +9,5 @@
| test.cpp:188:39:188:42 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
| test.cpp:189:44:189:47 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
| test.cpp:191:29:191:32 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
| test.cpp:193:31:193:35 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
| test.cpp:193:47:193:51 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
| test.cpp:195:31:195:35 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |

View File

@@ -190,6 +190,8 @@ const char* test1(bool b1, bool b2) {
char* s9;
s9 = std::string("hello").data(); // BAD
const char* s13 = b1 ? std::string("hello").c_str() : s1; // BAD
return std::string("hello").c_str(); // BAD
}

View File

@@ -6,4 +6,6 @@
| test.cpp:163:25:163:27 | call to get | The underlying unique pointer object is destroyed after the call to 'get' returns. |
| test.cpp:172:33:172:35 | call to get | The underlying unique pointer object is destroyed after the call to 'get' returns. |
| test.cpp:174:32:174:34 | call to get | The underlying unique pointer object is destroyed after the call to 'get' returns. |
| test.cpp:176:11:176:11 | call to operator* | The underlying unique pointer object is destroyed after the call to 'operator*' returns. |
| test.cpp:177:16:177:16 | call to operator* | The underlying unique pointer object is destroyed after the call to 'operator*' returns. |
| test.cpp:177:36:177:36 | call to operator* | The underlying unique pointer object is destroyed after the call to 'operator*' returns. |
| test.cpp:179:11:179:11 | call to operator* | The underlying unique pointer object is destroyed after the call to 'operator*' returns. |

View File

@@ -173,6 +173,9 @@ const S* test1(bool b1, bool b2) {
S* s5[] = { get_unique_ptr().get() }; // BAD
S s6 = b1 ? *get_unique_ptr() : *get_unique_ptr(); // GOOD
S& s7 = b1 ? *get_unique_ptr() : *get_unique_ptr(); // BAD
return &*get_unique_ptr(); // BAD
}