From 474c7fe5cc6f851f14e5491cbb028f8e285743a3 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Tue, 26 Apr 2022 10:57:06 -0500 Subject: [PATCH] Fix 10953: False positive: Possible null pointer dereference when calling derived function (#4044) --- lib/valueflow.cpp | 3 +++ test/testvalueflow.cpp | 45 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index bb5d0daaa..4bb98c250 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -7008,6 +7008,9 @@ static void valueFlowFunctionReturn(TokenList *tokenlist, ErrorLogger *errorLogg function = tok->astOperand1()->function(); if (!function) continue; + // TODO: Check if member variable is a pointer or reference + if (function->isImplicitlyVirtual() && !function->hasFinalSpecifier()) + continue; if (tok->hasKnownValue()) continue; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 4e797fa61..c3bb4d399 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -4341,8 +4341,51 @@ private: " x = 10 - f1(2);\n" " }\n" "};"; - ASSERT_EQUALS(7, valueOfTok(code, "-").intvalue); + TODO_ASSERT_EQUALS(7, 0, valueOfTok(code, "-").intvalue); ASSERT_EQUALS(false, valueOfTok(code, "-").isKnown()); + + code = "struct base {\n" + " virtual int f() { return 0; }\n" + "};\n" + "void g(base* b) {\n" + " int x = b->f();\n" + " return x;\n" + "}\n"; + TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 6U, 0)); + ASSERT_EQUALS(false, testValueOfXKnown(code, 6U, 0)); + + code = "struct base {\n" + " virtual int f() { return 0; }\n" + "};\n" + "void g(base& b) {\n" + " int x = b.f();\n" + " return x;\n" + "}\n"; + TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 6U, 0)); + ASSERT_EQUALS(false, testValueOfXKnown(code, 6U, 0)); + + code = "struct base {\n" + " virtual int f() { return 0; }\n" + "};\n" + "struct derived {\n" + " virtual int f() { return 1; }\n" + "};\n" + "void g(derived* d) {\n" + " base* b = d;\n" + " int x = b->f();\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(false, testValueOfX(code, 10U, 0)); + TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 10U, 1)); + + code = "struct base {\n" + " virtual int f() final { return 0; }\n" + "};\n" + "void g(base* b) {\n" + " int x = b->f();\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfX(code, 6U, 0)); } void valueFlowFunctionDefaultParameter() {