| 751 | } |
| 752 | |
| 753 | void valueFlowPointerAlias() { |
| 754 | const char *code; |
| 755 | std::list<ValueFlow::Value> values; |
| 756 | |
| 757 | code = "const char * f() {\n" |
| 758 | " static const char *x;\n" |
| 759 | " static char ret[10];\n" |
| 760 | " if (a) x = &ret[0];\n" |
| 761 | " return x;\n" |
| 762 | "}"; |
| 763 | ASSERT_EQUALS(true, testValueOfX(code, 5, "& ret [ 0 ]", ValueFlow::Value::ValueType::TOK)); |
| 764 | |
| 765 | // dead pointer |
| 766 | code = "void f() {\n" |
| 767 | " int *x;\n" |
| 768 | " if (cond) { int i; x = &i; }\n" |
| 769 | " *x = 0;\n" // <- x can point at i |
| 770 | "}"; |
| 771 | ASSERT_EQUALS(true, testValueOfX(code, 4, "& i", ValueFlow::Value::ValueType::TOK)); |
| 772 | |
| 773 | code = "void f() {\n" |
| 774 | " struct X *x;\n" |
| 775 | " x = &x[1];\n" |
| 776 | "}"; |
| 777 | values = tokenValues(code, "&"); |
| 778 | values.remove_if(&isNotTokValue); |
| 779 | ASSERT_EQUALS(true, values.empty()); |
| 780 | |
| 781 | values = tokenValues(code, "x ["); |
| 782 | values.remove_if(&isNotTokValue); |
| 783 | ASSERT_EQUALS(true, values.empty()); |
| 784 | } |
| 785 | |
| 786 | void valueFlowLifetime() { |
| 787 | std::vector<std::string> lifetimes; |