From 9dc38f80c06388cbfe1359be19d060a88c4f4548 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sun, 25 Jun 2023 20:38:54 +0200 Subject: [PATCH] Fix #11790 FP functionConst with template function (#5187) --- lib/checkclass.cpp | 11 +++++++++++ test/testclass.cpp | 15 +++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 0efd37f12a0..2b49d061a5b 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2098,6 +2098,17 @@ void CheckClass::checkConst() const bool returnsPtrOrRef = isPointerOrReference(func.retDef, func.tokenDef); + if (Function::returnsPointer(&func, /*unknown*/ true) || Function::returnsReference(&func, /*unknown*/ true, /*includeRValueRef*/ true)) { // returns const/non-const depending on template arg + bool isTemplateArg = false; + for (const Token* tok2 = func.retDef; precedes(tok2, func.token); tok2 = tok2->next()) + if (tok2->isTemplateArg() && tok2->str() == "const") { + isTemplateArg = true; + break; + } + if (isTemplateArg) + continue; + } + if (func.isOperator()) { // Operator without return type: conversion operator const std::string& opName = func.tokenDef->str(); if (opName.compare(8, 5, "const") != 0 && (endsWith(opName,'&') || endsWith(opName,'*'))) diff --git a/test/testclass.cpp b/test/testclass.cpp index 9ed7823ba3a..2a4be2d7c1c 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -180,6 +180,7 @@ class TestClass : public TestFixture { TEST_CASE(const88); TEST_CASE(const89); TEST_CASE(const90); + TEST_CASE(const91); TEST_CASE(const_handleDefaultParameters); TEST_CASE(const_passThisToMemberOfOtherClass); @@ -6595,6 +6596,20 @@ class TestClass : public TestFixture { errout.str()); } + void const91() { // #11790 + checkConst("struct S {\n" + " char* p;\n" + " template \n" + " T* get() {\n" + " return reinterpret_cast(p);\n" + " }\n" + "};\n" + "const int* f(S& s) {\n" + " return s.get();\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void const_handleDefaultParameters() { checkConst("struct Foo {\n" " void foo1(int i, int j = 0) {\n"