| 1914 | } |
| 1915 | |
| 1916 | const Token* ValueFlow::getEndOfExprScope(const Token* tok, const Scope* defaultScope, bool smallest) |
| 1917 | { |
| 1918 | const Token* end = nullptr; |
| 1919 | bool local = false; |
| 1920 | visitAstNodes(tok, [&](const Token* child) { |
| 1921 | if (const Variable* var = child->variable()) { |
| 1922 | local |= var->isLocal(); |
| 1923 | if (var->isLocal() || var->isArgument()) { |
| 1924 | const Token* varEnd = getEndOfVarScope(var); |
| 1925 | if (!end || (smallest ? precedes(varEnd, end) : succeeds(varEnd, end))) |
| 1926 | end = varEnd; |
| 1927 | |
| 1928 | const Token* top = var->nameToken()->astTop(); |
| 1929 | if (Token::simpleMatch(top->tokAt(-1), "if (")) { // variable declared in if (...) |
| 1930 | const Token* elseTok = top->link()->linkAt(1); |
| 1931 | if (Token::simpleMatch(elseTok, "} else {") && tok->scope()->isNestedIn(elseTok->tokAt(2)->scope())) |
| 1932 | end = tok->scope()->bodyEnd; |
| 1933 | } |
| 1934 | } |
| 1935 | } |
| 1936 | return ChildrenToVisit::op1_and_op2; |
| 1937 | }); |
| 1938 | if (!end && defaultScope) |
| 1939 | end = defaultScope->bodyEnd; |
| 1940 | if (!end) { |
| 1941 | const Scope* scope = tok->scope(); |
| 1942 | if (scope) |
| 1943 | end = scope->bodyEnd; |
| 1944 | // If there is no local variables then pick the function scope |
| 1945 | if (!local) { |
| 1946 | while (scope && scope->isLocal()) |
| 1947 | scope = scope->nestedIn; |
| 1948 | if (scope && scope->isExecutable()) |
| 1949 | end = scope->bodyEnd; |
| 1950 | } |
| 1951 | } |
| 1952 | return end; |
| 1953 | } |
| 1954 | |
| 1955 | static void valueFlowForwardLifetime(Token * tok, const TokenList &tokenlist, ErrorLogger &errorLogger, const Settings &settings) |
| 1956 | { |
nothing calls this directly
no test coverage detected