From 3f55707b303154676c2d5030a20ace034475d76a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 11 Nov 2018 12:47:27 +0100 Subject: [PATCH] Fixed #8064 (Taking the address of a moved variable is not accessing it) --- lib/checkother.cpp | 4 +++- test/testother.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 89f0bf5f7..0b27eac60 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -19,6 +19,7 @@ //--------------------------------------------------------------------------- #include "checkother.h" +#include "checkuninitvar.h" // CheckUninitVar::isVariableUsage #include "astutils.h" #include "errorlogger.h" @@ -2772,6 +2773,7 @@ void CheckOther::checkAccessOfMovedVariable() { if (!mTokenizer->isCPP() || mSettings->standards.cpp < Standards::CPP11 || !mSettings->isEnabled(Settings::WARNING)) return; + CheckUninitVar checkUninitVar(mTokenizer, mSettings, mErrorLogger); const bool reportInconclusive = mSettings->inconclusive; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { @@ -2797,7 +2799,7 @@ void CheckOther::checkAccessOfMovedVariable() inconclusive = true; } else { const bool isVariableChanged = isVariableChangedByFunctionCall(tok, mSettings, &inconclusive); - accessOfMoved = !isVariableChanged; + accessOfMoved = !isVariableChanged && checkUninitVar.isVariableUsage(tok, false, CheckUninitVar::NO_ALLOC); if (inconclusive) { accessOfMoved = !isMovedParameterAllowedForInconclusiveFunction(tok); if (accessOfMoved) diff --git a/test/testother.cpp b/test/testother.cpp index a4b716e5f..4cb1e3f06 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -208,6 +208,7 @@ private: TEST_CASE(moveAndReturn); TEST_CASE(moveAndClear); TEST_CASE(movedPointer); + TEST_CASE(moveAndAddressOf); TEST_CASE(partiallyMoved); TEST_CASE(moveAndLambda); TEST_CASE(forwardAndUsed); @@ -7334,6 +7335,15 @@ private: "[test.cpp:5]: (warning) Access of moved variable 'p'.\n", errout.str()); } + void moveAndAddressOf() { + check("void f() {\n" + " std::string s1 = x;\n" + " std::string s2 = std::move(s1);\n" + " p = &s1;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void partiallyMoved() { check("void f() {\n" " A a;\n"