cppcheck/test/testunusedvar.cpp
dummyunit b18e6f1e10
Fix varId assignment for uses of variables declared in the if condition (#3231)
Variables declared in the if condition (or in C++17 init-statement) are
visible not only in the if body but also in the else body. But logic in
Tokenizer::setVarIdPass1() handled such variables as if they were
declared in the if body.

As the result they were removed from variablesMap by the time the else
block was parsed and their uses in the else block were either given an
incorrect varId from variables in some outer scope or not given a varId
at all.

This then resulted in false positive unreadVariable errors for variables
declared in the if condition (or init-statement) and used only in the
else block.

Simplification from "else if ..." to "else { if ... }" was moved before
setVarId() to simplify detection for ends of blocks in if-else chains.
2021-04-26 07:38:03 +02:00

5856 lines
232 KiB
C++

/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2021 Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "checkunusedvar.h"
#include "preprocessor.h"
#include "settings.h"
#include "testsuite.h"
#include "tokenize.h"
#include <string>
class TestUnusedVar : public TestFixture {
public:
TestUnusedVar() : TestFixture("TestUnusedVar") {
}
private:
Settings settings;
void run() OVERRIDE {
settings.severity.enable(Severity::style);
settings.severity.enable(Severity::information);
settings.checkLibrary = true;
LOAD_LIB_2(settings.library, "std.cfg");
TEST_CASE(isRecordTypeWithoutSideEffects);
TEST_CASE(cleanFunction);
TEST_CASE(emptyclass); // #5355 - False positive: Variable is not assigned a value.
TEST_CASE(emptystruct); // #5355 - False positive: Variable is not assigned a value.
TEST_CASE(structmember1);
TEST_CASE(structmember2);
TEST_CASE(structmember3);
TEST_CASE(structmember4);
TEST_CASE(structmember5);
TEST_CASE(structmember6);
TEST_CASE(structmember7);
TEST_CASE(structmember8);
TEST_CASE(structmember9); // #2017 - struct is inherited
TEST_CASE(structmember_extern); // No false positives for extern structs
TEST_CASE(structmember10);
TEST_CASE(structmember11); // #4168 - initialization with {} / passed by address to unknown function
TEST_CASE(structmember12); // #7179 - FP unused structmember
TEST_CASE(structmember13); // #3088 - __attribute__((packed))
TEST_CASE(structmember14); // #6508 - (struct x){1,2,..}
TEST_CASE(structmember15); // #3088 - #pragma pack(1)
TEST_CASE(structmember_sizeof);
TEST_CASE(localvar1);
TEST_CASE(localvar2);
TEST_CASE(localvar3);
TEST_CASE(localvar4);
TEST_CASE(localvar5);
TEST_CASE(localvar6);
TEST_CASE(localvar8);
TEST_CASE(localvar9); // ticket #1605
TEST_CASE(localvar10);
TEST_CASE(localvar11);
TEST_CASE(localvar12);
TEST_CASE(localvar13); // ticket #1640
TEST_CASE(localvar14); // ticket #5
TEST_CASE(localvar15);
TEST_CASE(localvar16); // ticket #1709
TEST_CASE(localvar17); // ticket #1720
TEST_CASE(localvar18); // ticket #1723
TEST_CASE(localvar19); // ticket #1776
TEST_CASE(localvar20); // ticket #1799
TEST_CASE(localvar21); // ticket #1807
TEST_CASE(localvar22); // ticket #1811
TEST_CASE(localvar23); // ticket #1808
TEST_CASE(localvar24); // ticket #1803
TEST_CASE(localvar25); // ticket #1729
TEST_CASE(localvar26); // ticket #1894
TEST_CASE(localvar27); // ticket #2160
TEST_CASE(localvar28); // ticket #2205
TEST_CASE(localvar29); // ticket #2206 (array initialization)
TEST_CASE(localvar30);
TEST_CASE(localvar31); // ticket #2286
TEST_CASE(localvar32); // ticket #2330
TEST_CASE(localvar33); // ticket #2346
TEST_CASE(localvar34); // ticket #2368
TEST_CASE(localvar35); // ticket #2535
TEST_CASE(localvar36); // ticket #2805
TEST_CASE(localvar37); // ticket #3078
TEST_CASE(localvar38);
TEST_CASE(localvar39); // ticket #3454
TEST_CASE(localvar40); // ticket #3473
TEST_CASE(localvar41); // ticket #3603
TEST_CASE(localvar42); // ticket #3742
TEST_CASE(localvar43); // ticket #3602
TEST_CASE(localvar44); // ticket #4020
TEST_CASE(localvar45); // ticket #4899
TEST_CASE(localvar46); // ticket #5491 (C++11 style initialization)
TEST_CASE(localvar47); // ticket #6603
TEST_CASE(localvar48); // ticket #6954
TEST_CASE(localvar49); // ticket #7594
TEST_CASE(localvar50); // ticket #6261 : dostuff(cond ? buf1 : buf2)
TEST_CASE(localvar51); // ticket #8128 - FN : tok = tok->next();
TEST_CASE(localvar52);
TEST_CASE(localvar53); // continue
TEST_CASE(localvar54); // ast, {}
TEST_CASE(localvar55);
TEST_CASE(localvar56);
TEST_CASE(localvar57); // #8974 - increment
TEST_CASE(localvar58); // #9901 - increment false positive
TEST_CASE(localvar59); // #9737
TEST_CASE(localvarloops); // loops
TEST_CASE(localvaralias1);
TEST_CASE(localvaralias2); // ticket #1637
TEST_CASE(localvaralias3); // ticket #1639
TEST_CASE(localvaralias4); // ticket #1643
TEST_CASE(localvaralias5); // ticket #1647
TEST_CASE(localvaralias6); // ticket #1729
TEST_CASE(localvaralias7); // ticket #1732
TEST_CASE(localvaralias8);
TEST_CASE(localvaralias9); // ticket #1996
TEST_CASE(localvaralias10); // ticket #2004
TEST_CASE(localvaralias11); // ticket #4423 - iterator
TEST_CASE(localvaralias12); // ticket #4394
TEST_CASE(localvaralias13); // ticket #4487
TEST_CASE(localvaralias14); // ticket #5619
TEST_CASE(localvaralias15); // ticket #6315
TEST_CASE(localvaralias16);
TEST_CASE(localvaralias17); // ticket #8911
TEST_CASE(localvaralias18); // ticket #9234 - iterator
TEST_CASE(localvarasm);
TEST_CASE(localvarstatic);
TEST_CASE(localvarextern);
TEST_CASE(localvardynamic1);
TEST_CASE(localvardynamic2); // ticket #2904
TEST_CASE(localvardynamic3); // ticket #3467
TEST_CASE(localvararray1); // ticket #2780
TEST_CASE(localvararray2); // ticket #3438
TEST_CASE(localvararray3); // ticket #3980
TEST_CASE(localvararray4); // ticket #4839
TEST_CASE(localvararray5); // ticket #7092
TEST_CASE(localvarstring1);
TEST_CASE(localvarstring2); // ticket #2929
TEST_CASE(localvarconst1);
TEST_CASE(localvarconst2);
TEST_CASE(localvarreturn); // ticket #9167
TEST_CASE(localvarmaybeunused);
TEST_CASE(localvarthrow); // ticket #3687
TEST_CASE(localVarStd);
TEST_CASE(localVarClass);
TEST_CASE(localVarSmartPtr);
// Don't give false positives for variables in structs/unions
TEST_CASE(localvarStruct1);
TEST_CASE(localvarStruct2);
TEST_CASE(localvarStruct3);
TEST_CASE(localvarStruct5);
TEST_CASE(localvarStruct6);
TEST_CASE(localvarStruct7);
TEST_CASE(localvarStruct8);
TEST_CASE(localvarStruct9);
TEST_CASE(localvarStructArray);
TEST_CASE(localvarUnion1);
TEST_CASE(localvarOp); // Usage with arithmetic operators
TEST_CASE(localvarInvert); // Usage with inverted variable
TEST_CASE(localvarIf); // Usage in if
TEST_CASE(localvarIfElse); // return tmp1 ? tmp2 : tmp3;
TEST_CASE(localvarDeclaredInIf);
TEST_CASE(localvarOpAssign); // a |= b;
TEST_CASE(localvarFor); // for ( ; var; )
TEST_CASE(localvarForEach); // #4155 - BOOST_FOREACH, hlist_for_each, etc
TEST_CASE(localvarShift1); // 1 >> var
TEST_CASE(localvarShift3); // x << y
TEST_CASE(localvarCast);
TEST_CASE(localvarClass);
TEST_CASE(localvarUnused);
TEST_CASE(localvarFunction); // ticket #1799
TEST_CASE(localvarIfNOT); // #3104 - if ( NOT var )
TEST_CASE(localvarAnd); // #3672
TEST_CASE(localvarSwitch); // #3744 - false positive when localvar is used in switch
TEST_CASE(localvarNULL); // #4203 - Setting NULL value is not redundant - it is safe
TEST_CASE(localvarUnusedGoto); // #4447, #4558 goto
TEST_CASE(localvarRangeBasedFor); // #7075
TEST_CASE(localvarAssignInWhile);
TEST_CASE(localvarTemplate); // #4955 - variable is used as template parameter
TEST_CASE(localvarFuncPtr); // #7194
TEST_CASE(localvarAddr); // #7477
TEST_CASE(localvarDelete);
TEST_CASE(localvarLambda); // #8941, #8948
TEST_CASE(localvarCppInitialization);
TEST_CASE(localvarCpp11Initialization);
TEST_CASE(chainedAssignment); // #5466
TEST_CASE(crash1);
TEST_CASE(crash2);
TEST_CASE(usingNamespace); // #4585
TEST_CASE(lambdaFunction); // #5078
TEST_CASE(namespaces); // #7557
TEST_CASE(bracesInitCpp11);// #7895 - "int var{123}" initialization
TEST_CASE(argument);
TEST_CASE(argumentClass);
TEST_CASE(escapeAlias); // #9150
TEST_CASE(volatileData); // #9280
}
void checkStructMemberUsage(const char code[], const std::list<Directive> *directives=nullptr) {
// Clear the error buffer..
errout.str("");
Preprocessor preprocessor(settings, nullptr);
if (directives)
preprocessor.setDirectives(*directives);
// Tokenize..
Tokenizer tokenizer(&settings, this);
tokenizer.setPreprocessor(&preprocessor);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
// Check for unused variables..
CheckUnusedVar checkUnusedVar(&tokenizer, &settings, this);
checkUnusedVar.checkStructMemberUsage();
}
void isRecordTypeWithoutSideEffects() {
functionVariableUsage(
"class A {};\n"
"void f() {\n"
" A a;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: a\n", errout.str());
functionVariableUsage(
"class A {};\n"
"class B {\n"
"public:\n"
" A a;\n"
"};\n"
"void f() {\n"
" B b;\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (style) Unused variable: b\n", errout.str());
functionVariableUsage(
"class C {\n"
"public:\n"
" C() = default;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Unused variable: c\n", errout.str());
functionVariableUsage(
"class D {\n"
"public:\n"
" D() {}\n"
"};\n"
"void f() {\n"
" D d;\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Unused variable: d\n", errout.str());
functionVariableUsage(
"class E {\n"
"public:\n"
" uint32_t u{1};\n"
"};\n"
"void f() {\n"
" E e;\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Unused variable: e\n", errout.str());
functionVariableUsage(
"class F {\n"
"public:\n"
" F() : x(0) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (style) Unused variable: f\n", errout.str());
functionVariableUsage(
"class F {\n"
"public:\n"
" F() : x{0} {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (style) Unused variable: f\n", errout.str());
functionVariableUsage(
"int y = 0;\n"
"class F {\n"
"public:\n"
" F() : x(y) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("[test.cpp:8]: (style) Unused variable: f\n", errout.str());
functionVariableUsage(
"int y = 0;"
"class F {\n"
"public:\n"
" F() : x(++y) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (style) Unused variable: f\n", errout.str());
functionVariableUsage(
"int y = 0;"
"class F {\n"
"public:\n"
" F() : x(--y) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (style) Unused variable: f\n", errout.str());
functionVariableUsage(
"int y = 0;"
"class F {\n"
"public:\n"
" F() : x(y+=1) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (style) Unused variable: f\n", errout.str());
functionVariableUsage(
"int y = 0;"
"class F {\n"
"public:\n"
" F() : x(y-=1) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (style) Unused variable: f\n", errout.str());
// non-empty constructor
functionVariableUsage(
"class F {\n"
"public:\n"
" F() {\n"
" int i = 0;\n"
" (void) i;"
" }\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
TODO_ASSERT_EQUALS("error", "", errout.str());
// side-effect variable
functionVariableUsage(
"class F {\n"
"public:\n"
" F() {\n"
" int i = 0;\n"
" (void) i;"
" }\n"
"};\n"
"class G {\n"
"public:\n"
" F f;\n"
"};\n"
"void f() {\n"
" G g;\n"
"}");
ASSERT_EQUALS("", errout.str());
// side-effect variable in initialization list
functionVariableUsage(
"class F {\n"
"public:\n"
" F() {\n"
" int i = 0;\n"
" (void) i;"
" }\n"
"};\n"
"class G {\n"
"public:\n"
" G() : f(F()) {}\n"
" F f;"
"};\n"
"void f() {\n"
" G g;\n"
"}");
ASSERT_EQUALS("", errout.str());
// unknown variable type
functionVariableUsage(
"class H {\n"
"public:\n"
" unknown_type u{1};\n"
"};\n"
"void f() {\n"
" H h;\n"
"}");
ASSERT_EQUALS("", errout.str());
// unknown variable type in initialization list
functionVariableUsage(
"class H {\n"
"public:\n"
" H() : x{0}, u(1) {}\n"
" int x;"
" unknown_type u;\n"
"};\n"
"void f() {\n"
" H h;\n"
"}");
ASSERT_EQUALS("", errout.str());
// unknown variable type used for initialization
functionVariableUsage(
"unknown_type y = 0;\n"
"class F {\n"
"public:\n"
" F() : x(y) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"int sideEffectFunc();\n"
"class F {\n"
"public:\n"
" F() : x(sideEffectFunc()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"class F {\n"
"public:\n"
" F() : x(++unknownValue) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"class F {\n"
"public:\n"
" F() : x(--unknownValue) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"class F {\n"
"public:\n"
" F() : x(unknownValue+=1) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"class F {\n"
"public:\n"
" F() : x(unknownValue-=1) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void cleanFunction() {
// unknown function
functionVariableUsage(
"class F {\n"
"public:\n"
" F() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" F f;\n"
"}");
ASSERT_EQUALS("", errout.str());
// function forward declaration
functionVariableUsage(
"int func();\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// return literal
functionVariableUsage(
"int func() { return 1; }\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:8]: (style) Unused variable: c\n", errout.str());
// return variable without side effects
functionVariableUsage(
"int func() {\n"
" int x = 1;\n"
" return x;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:11]: (style) Unused variable: c\n", errout.str());
// return variable with side effects
functionVariableUsage(
"int func() {\n"
" unknown_type x = 1;\n"
" return x;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// return unknown variable
functionVariableUsage(
"int func() {\n"
" return unknown_var;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// return variable is global, but not changed
functionVariableUsage(
"int x = 1;\n"
"int func() {\n"
" return x;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:11]: (style) Unused variable: c\n", errout.str());
// changing global variable in return
functionVariableUsage(
"int x = 1;\n"
"int func() {\n"
" return x++;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// changing global variable in function body
functionVariableUsage(
"int x = 1;\n"
"int func() {\n"
" x++;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"int x = 1;\n"
"int func() {\n"
" --x;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"int x = 1;\n"
"int func() {\n"
" x += 2;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"int x = 1;\n"
"int func() {\n"
" x = 2;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// global variable use in function body without change
functionVariableUsage(
"int global = 1;\n"
"int func() {\n"
" int x = global + 1;\n"
" return x;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:12]: (style) Unused variable: c\n", errout.str());
// changing global array variable in function body
functionVariableUsage(
"int x[] = {0, 1, 3};\n"
"int func() {\n"
" x[0] = 4;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"int x[] = {0, 1, 3};\n"
"int func() {\n"
" *x = 2;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"int x[] = {0, 1, 3};\n"
"int func() {\n"
" *(x) = 2;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// pointer arithmetic on global array
functionVariableUsage(
"int x[] = {0, 1, 3};\n"
"int func() {\n"
" *(x + 1) = 2;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"int x[][] = {{0, 1}, {2, 3}};\n"
"int func() {\n"
" *((x + 1) + 1) = 4;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"int x[] = {0, 1, 3};\n"
"int func() {\n"
" int local = *(x + 1);\n"
" (void) local;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:13]: (style) Unused variable: c\n", errout.str());
functionVariableUsage(
"int x[] = {0, 1, 3};\n"
"int func() {\n"
" int* local = x + 2;\n"
" (void) local;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:13]: (style) Unused variable: c\n", errout.str());
functionVariableUsage(
"int x[] = {0, 1, 3};\n"
"int func() {\n"
" int* local = x + 2;\n"
" return *local;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"int x[] = {0, 1, 3};\n"
"int func() {\n"
" return *(x + 1);\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// changing local variable
functionVariableUsage(
"int func() {\n"
" int x = 1;\n"
" x = 2;\n"
" x++;\n"
" return x;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:13]: (style) Unused variable: c\n", errout.str());
// variable of user-defined class without side effects
functionVariableUsage(
"class A {};\n"
"A func() {\n"
" A a;\n"
" return a;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" A x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:12]: (style) Unused variable: c\n", errout.str());
// variable of user-defined class with side effects
functionVariableUsage(
"class A {\n"
"public:\n"
" unknown_type u{1};\n"
"};\n"
"int func() {\n"
" A a;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// unknown type variable
functionVariableUsage(
"int func() {\n"
" unknown_type a;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// nested clean function call
functionVariableUsage(
"int another_func() { return 1;}\n"
"int func() {\n"
" another_func();\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:12]: (style) Unused variable: c\n", errout.str());
// nested side-effects function call
functionVariableUsage(
"int global = 1;"
"int another_func() {\n"
" global++;\n"
" return global;}\n"
"int func() {\n"
" another_func();\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// unknown nested function
functionVariableUsage(
"int func() {\n"
" unknown_func();\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// clean function recursion
functionVariableUsage(
"int func(int i) {\n"
" if (i != 2) {\n"
" func(i++);\n"
" return 2;\n"
" }\n"
" return i;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func(0)) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:14]: (style) Unused variable: c\n", errout.str());
// indirect clean function recursion
functionVariableUsage(
"void another_func() {\n"
" func(0);\n"
"}\n"
"int func(int i) {\n"
" if (i != 2) {\n"
" another_func();\n"
" return 2;\n"
" }\n"
" return i;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func(0)) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:17]: (style) Unused variable: c\n", errout.str());
// side-effect function recursion
functionVariableUsage(
"int global = 1;\n"
"int func(int i) {\n"
" if (i != 2) {\n"
" global++;\n"
" func(i++);\n"
" return 2;\n"
" }\n"
" return i;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func(0)) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// multiple returns (side-effect & clean)
functionVariableUsage(
"int func(int i) {\n"
" if (i == 0) { return 0;}\n"
" else { return unknownSideEffectFunction(); }\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func(0)) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// multiple clean returns
functionVariableUsage(
"int func(int i) {\n"
" if (i == 0) { return 0;}\n"
" else { return i; }\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func(0)) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:11]: (style) Unused variable: c\n", errout.str());
// multiple side-effect returns
functionVariableUsage(
"int func(int i) {\n"
" if (i == 0) { return unknownSideEffectFunction();}\n"
" else { return unknown_var; }\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func(0)) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// argument return
functionVariableUsage(
"int func(int i) {\n"
" return i;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func(0)) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:10]: (style) Unused variable: c\n", errout.str());
// global variable modifying through function argument
functionVariableUsage(
"char buf[10];\n"
"int func(char* p) {\n"
" *p = 0;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func(buf)) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// global variable modifying through local pointer
functionVariableUsage(
"int global = 1;\n"
"int func() {\n"
" int* p = &global;\n"
" *p = 0;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// global variable assigning to local pointer, but not modifying
functionVariableUsage(
"int global = 1;\n"
"int func() {\n"
" int* p = &global;\n"
" (void) p;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:13]: (style) Unused variable: c\n", errout.str());
// global struct variable modification
functionVariableUsage(
"struct S { int x; } s;\n"
"int func() {\n"
" s.x = 1;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// global struct variable without modification
functionVariableUsage(
"struct S { int x; } s;\n"
"int func() {\n"
" int y = s.x + 1;\n"
" return y;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:12]: (style) Unused variable: c\n", errout.str());
// global pointer to struct variable modification
functionVariableUsage(
"struct S { int x; };\n"
"struct S* s = new(struct S);\n"
"int func() {\n"
" s->x = 1;\n"
" return 1;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("", errout.str());
// global pointer to struct variable without modification
functionVariableUsage(
"struct S { int x; };\n"
"struct S* s = new(struct S);\n"
"int func() {\n"
" int y = s->x + 1;\n"
" return y;\n"
"}\n"
"class C {\n"
"public:\n"
" C() : x(func()) {}\n"
" int x;\n"
"};\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:13]: (style) Unused variable: c\n", errout.str());
}
// #5355 - False positive: Variable is not assigned a value.
void emptyclass() {
functionVariableUsage("class Carla {\n"
"};\n"
"class Fred : Carla {\n"
"};\n"
"void foo() {\n"
" Fred fred;\n"
" throw fred;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
// #5355 - False positive: Variable is not assigned a value.
void emptystruct() {
functionVariableUsage("struct Fred {\n"
"};\n"
"void foo() {\n"
" Fred fred;\n"
" throw fred;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void structmember1() {
checkStructMemberUsage("struct abc\n"
"{\n"
" int a;\n"
" int b;\n"
" int c;\n"
"};");
ASSERT_EQUALS("[test.cpp:3]: (style) struct member 'abc::a' is never used.\n"
"[test.cpp:4]: (style) struct member 'abc::b' is never used.\n"
"[test.cpp:5]: (style) struct member 'abc::c' is never used.\n", errout.str());
checkStructMemberUsage("union abc\n"
"{\n"
" int a;\n"
" int b;\n"
" int c;\n"
"};");
ASSERT_EQUALS("[test.cpp:3]: (style) union member 'abc::a' is never used.\n"
"[test.cpp:4]: (style) union member 'abc::b' is never used.\n"
"[test.cpp:5]: (style) union member 'abc::c' is never used.\n", errout.str());
}
void structmember2() {
checkStructMemberUsage("struct ABC\n"
"{\n"
" int a;\n"
" int b;\n"
" int c;\n"
"};\n"
"\n"
"void foo()\n"
"{\n"
" struct ABC abc;\n"
" int a = abc.a;\n"
" int b = abc.b;\n"
" int c = abc.c;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void structmember3() {
checkStructMemberUsage("struct ABC\n"
"{\n"
" int a;\n"
" int b;\n"
" int c;\n"
"};\n"
"\n"
"static struct ABC abc[] = { {1, 2, 3} };\n"
"\n"
"void foo()\n"
"{\n"
" int a = abc[0].a;\n"
" int b = abc[0].b;\n"
" int c = abc[0].c;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void structmember4() {
checkStructMemberUsage("struct ABC\n"
"{\n"
" const int a;\n"
"};\n"
"\n"
"void foo()\n"
"{\n"
" ABC abc;\n"
" if (abc.a == 2);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void structmember5() {
checkStructMemberUsage("struct AB\n"
"{\n"
" int a;\n"
" int b;\n"
" void reset()\n"
" {\n"
" a = 1;\n"
" b = 2;\n"
" }\n"
"};\n"
"\n"
"void foo()\n"
"{\n"
" struct AB ab;\n"
" ab.reset();\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void structmember6() {
checkStructMemberUsage("struct AB\n"
"{\n"
" int a;\n"
" int b;\n"
"};\n"
"\n"
"void foo(char *buf)\n"
"{\n"
" struct AB *ab = (struct AB *)&buf[10];\n"
"}");
ASSERT_EQUALS("", errout.str());
checkStructMemberUsage("struct AB\n"
"{\n"
" int a;\n"
" int b;\n"
"};\n"
"\n"
"void foo(char *buf)\n"
"{\n"
" struct AB *ab = (AB *)&buf[10];\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void structmember7() {
checkStructMemberUsage("struct AB\n"
"{\n"
" int a;\n"
" int b;\n"
"};\n"
"\n"
"void foo(struct AB *ab)\n"
"{\n"
" ab->a = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
checkStructMemberUsage("struct AB\n"
"{\n"
" int a;\n"
" int b;\n"
"};\n"
"\n"
"void foo(struct AB _shuge *ab)\n"
"{\n"
" ab->a = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void structmember8() {
checkStructMemberUsage("struct AB\n"
"{\n"
" int a;\n"
" int b;\n"
"};\n"
"\n"
"void foo(char *ab)\n"
"{\n"
" ((AB *)ab)->b = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void structmember9() {
checkStructMemberUsage("struct base {\n"
" int a;\n"
"};\n"
"\n"
"struct derived : public base {"
"}");
ASSERT_EQUALS("", errout.str());
}
void structmember10() {
// Fred may have some useful side-effects
checkStructMemberUsage("struct abc {\n"
" Fred fred;\n"
"};");
ASSERT_EQUALS("", errout.str());
}
void structmember11() { // #4168
checkStructMemberUsage("struct abc { int x; };\n"
"struct abc s = {0};\n"
"void f() { do_something(&s); }");
ASSERT_EQUALS("", errout.str());
checkStructMemberUsage("struct abc { int x; };\n"
"struct abc s = {0};\n"
"void f() { }");
TODO_ASSERT_EQUALS("abc::x is not used", "", errout.str());
}
void structmember12() { // #7179
checkStructMemberUsage("#include <stdio.h>\n"
"struct\n"
"{\n"
" union\n"
" {\n"
" struct\n"
" {\n"
" int a;\n"
" } struct1;\n"
" };\n"
"} var = {0};\n"
"int main(int argc, char *argv[])\n"
"{\n"
" printf(\"var.struct1.a = %d\", var.struct1.a);\n"
" return 1;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void structmember13() { // #3088 - struct members required by hardware
checkStructMemberUsage("struct S {\n"
" int x;\n"
"} __attribute__((packed));");
ASSERT_EQUALS("", errout.str());
}
void structmember14() { // #6508
checkStructMemberUsage("struct bstr { char *bstart; size_t len; };\n"
"struct bstr bstr0(void) {\n"
" return (struct bstr){\"hello\",6};\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void structmember15() { // #3088
std::list<Directive> directives;
directives.emplace_back("test.cpp", 1, "#pragma pack(1)");
checkStructMemberUsage("\nstruct Foo { int x; int y; };", &directives);
ASSERT_EQUALS("", errout.str());
}
void structmember_extern() {
// extern struct => no false positive
checkStructMemberUsage("extern struct AB\n"
"{\n"
" int a;\n"
" int b;\n"
"} ab;\n"
"\n"
"void foo()\n"
"{\n"
" ab.b = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
// global linkage => no false positive
checkStructMemberUsage("struct AB\n"
"{\n"
" int a;\n"
" int b;\n"
"} ab;\n"
"\n"
"void foo()\n"
"{\n"
" ab.b = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
// static linkage => error message
checkStructMemberUsage("static struct AB\n"
"{\n"
" int a;\n"
" int b;\n"
"} ab;\n"
"\n"
"void foo()\n"
"{\n"
" ab.b = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) struct member 'AB::a' is never used.\n", errout.str());
checkStructMemberUsage("struct A\n"
"{\n"
" static const int a = 0;\n"
"};\n"
"\n"
"int foo()\n"
"{\n"
" return A::a;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void structmember_sizeof() {
checkStructMemberUsage("struct Header {\n"
" uint8_t message_type;\n"
"}\n"
"\n"
"input.skip(sizeof(Header));");
ASSERT_EQUALS("", errout.str());
checkStructMemberUsage("struct Header {\n"
" uint8_t message_type;\n"
"}\n"
"\n"
"input.skip(sizeof(struct Header));");
ASSERT_EQUALS("", errout.str());
}
void functionVariableUsage(const char code[], const char filename[]="test.cpp") {
// Clear the error buffer..
errout.str("");
// Tokenize..
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
if (!tokenizer.tokenize(istr, filename))
return;
// Check for unused variables..
CheckUnusedVar checkUnusedVar(&tokenizer, &settings, this);
checkUnusedVar.checkFunctionVariableUsage();
}
void localvar1() {
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i(0);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
// if a is undefined then Cppcheck can't determine if "int i(a)" is a
// * variable declaration
// * function declaration
functionVariableUsage("void foo()\n"
"{\n"
" int i(a);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int j = 0;\n"
" int i(j);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int j = 0;\n"
" int & i = j;\n"
" x(j);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int j = 0;\n"
" const int & i = j;\n"
" x(j);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int j = 0;\n"
" int & i(j);\n"
" x(j);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int j = 0;\n"
" const int & i(j);\n"
" x(j);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int * j = Data;\n"
" int * i(j);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int * j = Data;\n"
" const int * i(j);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" bool i = false;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" bool i = true;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char *i;\n"
" i = fgets();\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
// undefined variables are not reported because they may be classes with constructors
functionVariableUsage("undefined foo()\n"
"{\n"
" undefined i = 0;\n"
"}");
// ? ASSERT_EQUALS("", errout.str());
functionVariableUsage("undefined foo()\n"
"{\n"
" undefined i = 0;\n"
"}\n",
"test.c");
ASSERT_EQUALS("[test.c:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i = undefined;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int * i = Data;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" void * i = Data;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" const void * i = Data;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" struct S * i = DATA;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" const struct S * i = DATA;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" struct S & i = j;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" const struct S & i = j;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" undefined * i = X;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0;\n"
" int j = i;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'j' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i[10] = { 0 };\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo(int n)\n"
"{\n"
" int i[n] = { 0 };\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char i[10] = \"123456789\";\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char *i = \"123456789\";\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0,code=10;\n"
" for(i = 0; i < 10; i++) {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0,code=10,d=10;\n"
" for(i = 0; i < 10; i++) {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" d = code;\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'd' is assigned a value that is never used.\n"
"[test.cpp:7]: (style) Variable 'd' is assigned a value that is never used.\n",
errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0,code=10,d=10;\n"
" for(i = 0; i < 10; i++) {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" g(d);\n"
" d = code;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0,code=10,d=10;\n"
" for(i = 0; i < 10; i++) {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" if (i == 3) {\n"
" return d;\n"
" }\n"
" d = code;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0,a=10,b=20;\n"
" for(i = 0; i < 10; i++) {\n"
" std::cout<<a<<std::endl;\n"
" int tmp=a;\n"
" a=b;\n"
" b=tmp;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int code=10;\n"
" while(code < 20) {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int code=10,d=10;\n"
" while(code < 20) {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" d += code;\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'd' is assigned a value that is never used.\n"
"[test.cpp:7]: (style) Variable 'd' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int code=10,d=10;\n"
" while(code < 20) {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" g(d);\n"
" d += code;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int code=10,d=10;\n"
" while(code < 20) {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" if (i == 3) {\n"
" return d;\n"
" }\n"
" d += code;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a=10,b=20;\n"
" while(a != 30) {\n"
" std::cout<<a<<std::endl;\n"
" int tmp=a;\n"
" a=b;\n"
" b=tmp;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int code=10;\n"
" do {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" } while(code < 20);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int code=10,d=10;\n"
" do {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" d += code;\n"
" } while(code < 20);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'd' is assigned a value that is never used.\n"
"[test.cpp:7]: (style) Variable 'd' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int code=10,d=10;\n"
" do {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" g(d);\n"
" d += code;\n"
" } while(code < 20);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int code=10,d=10;\n"
" do {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" if (i == 3) {\n"
" return d;\n"
" }\n"
" d += code;\n"
" } while(code < 20);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a=10,b=20;\n"
" do {\n"
" std::cout<<a<<std::endl;\n"
" int tmp=a;\n"
" a=b;\n"
" b=tmp;\n"
" } while( a!=30 );\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int code=10;\n"
" for(int i=0; i < 10; i++) {\n"
" if(true) {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" }\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int code=10;\n"
" for(int i=0; i < 10; i++) {\n"
" if(true) {\n"
" std::cout<<code<<std::endl;\n"
" }\n"
" code += 2;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int code=10;\n"
" while(code < 20) {\n"
" if(true) {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" }\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int code=10;\n"
" do {\n"
" if(true) {\n"
" std::cout<<code<<std::endl;\n"
" code += 2;\n"
" }\n"
" } while(code < 20);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo(int j = 0) {\n" // #5985 - default function parameters should not affect checking results
" int i = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
}
void localvar2() {
functionVariableUsage("int foo()\n"
"{\n"
" int i;\n"
" return i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is not assigned a value.\n", errout.str());
functionVariableUsage("bool foo()\n"
"{\n"
" bool i;\n"
" return i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is not assigned a value.\n", errout.str());
// undefined variables are not reported because they may be classes with constructors
functionVariableUsage("undefined foo()\n"
"{\n"
" undefined i;\n"
" return i;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("undefined foo()\n"
"{\n"
" undefined i;\n"
" return i;\n"
"}\n",
"test.c");
ASSERT_EQUALS("[test.c:3]: (style) Variable 'i' is not assigned a value.\n", errout.str());
functionVariableUsage("undefined *foo()\n"
"{\n"
" undefined * i;\n"
" return i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is not assigned a value.\n", errout.str());
functionVariableUsage("int *foo()\n"
"{\n"
" int * i;\n"
" return i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is not assigned a value.\n", errout.str());
functionVariableUsage("const int *foo()\n"
"{\n"
" const int * i;\n"
" return i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is not assigned a value.\n", errout.str());
functionVariableUsage("struct S *foo()\n"
"{\n"
" struct S * i;\n"
" return i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is not assigned a value.\n", errout.str());
functionVariableUsage("const struct S *foo()\n"
"{\n"
" const struct S * i;\n"
" return i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is not assigned a value.\n", errout.str());
// assume f() can write a
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" f(a[0]);\n"
"}");
ASSERT_EQUALS("", errout.str());
// assume f() can write a
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" f(a[0], 0);\n"
"}");
ASSERT_EQUALS("", errout.str());
// assume f() can write a
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" f(0, a[0]);\n"
"}");
ASSERT_EQUALS("", errout.str());
// assume f() can write a
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" f(0, a[0], 0);\n"
"}");
ASSERT_EQUALS("", errout.str());
// f() can not write a (not supported yet)
functionVariableUsage("void f(int i) { }\n"
"void foo()\n"
"{\n"
" int a[10];\n"
" f(a[0]);\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a' is not assigned a value.\n",
"", errout.str());
// f() can not write a (not supported yet)
functionVariableUsage("void f(const int & i) { }\n"
"void foo()\n"
"{\n"
" int a[10];\n"
" f(a[0]);\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a' is not assigned a value.\n",
"", errout.str());
// f() writes a
functionVariableUsage("void f(int & i) { }\n"
"void foo()\n"
"{\n"
" int a[10];\n"
" f(a[0]);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f(int * i);\n"
"void foo()\n"
"{\n"
" int a[10];\n"
" f(a+1);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar3() {
functionVariableUsage("void foo()\n"
"{\n"
" int i;\n"
" if ( abc )\n"
" ;\n"
" else i = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
}
void localvar4() {
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0;\n"
" f(i);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0;\n"
" f(&i);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar5() {
functionVariableUsage("void foo()\n"
"{\n"
" int a = 0;\n"
" b = (char)a;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar6() {
functionVariableUsage("void foo()\n"
"{\n"
" int b[10];\n"
" for (int i=0;i<10;++i)\n"
" b[i] = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a = 0;\n"
" int b[10];\n"
" for (int i=0;i<10;++i)\n"
" b[i] = ++a;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
}
void localvar8() {
functionVariableUsage("void foo()\n"
"{\n"
" int i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i[2];\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" void * i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" const void * i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" A * i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" struct A * i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" const struct A * i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int * i[2];\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", "", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" const int * i[2];\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", "", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" void * i[2];\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", "", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" const void * i[2];\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", "", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" struct A * i[2];\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", "", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" const struct A * i[2];\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", "", errout.str());
functionVariableUsage("void foo(int n)\n"
"{\n"
" int i[n];\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i = 0;\n"
" int &j = i;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'j' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i;\n"
" int &j = i;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'j' is assigned a value that is never used.\n"
"[test.cpp:3]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int i;\n"
" int &j = i;\n"
" j = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("double foo()\n"
"{\n"
" double i = 0.0;\n"
" const double j = i;\n"
" return j;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" A * i;\n"
" i->f();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char * i;\n"
" if (i);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char * i = 0;\n"
" if (i);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char * i = new char[10];\n"
" if (i);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char *i;\n"
" f(i);\n"
"}");
functionVariableUsage("int a;\n"
"void foo()\n"
"{\n"
" return &a;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int a[10];\n"
"void foo()\n"
"{\n"
" int *p = a;\n"
" for (int i = 0; i < 10; i++)\n"
" p[i] = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int a[10];\n"
"void foo()\n"
"{\n"
" int *p = &a[0];\n"
" for (int i = 0; i < 10; i++)\n"
" p[i] = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" int x;\n"
" a[0] = 0;\n"
" x = a[0];\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a, b, c;\n"
" a = b = c = f();\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("int * foo()\n"
"{\n"
" return &undefined[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar9() {
// ticket #1605
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" for (int i = 0; i < 10; )\n"
" a[i++] = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
}
void localvar10() {
functionVariableUsage("void foo(int x)\n"
"{\n"
" int i;\n"
" if (x) {\n"
" int i;\n"
" } else {\n"
" int i;\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n"
"[test.cpp:5]: (style) Unused variable: i\n"
"[test.cpp:7]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo(int x)\n"
"{\n"
" int i;\n"
" if (x)\n"
" int i;\n"
" else\n"
" int i;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n"
"[test.cpp:5]: (style) Unused variable: i\n"
"[test.cpp:7]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo(int x)\n"
"{\n"
" int i;\n"
" if (x) {\n"
" int i;\n"
" } else {\n"
" int i = 0;\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'i' is assigned a value that is never used.\n"
"[test.cpp:3]: (style) Unused variable: i\n"
"[test.cpp:5]: (style) Unused variable: i\n", errout.str());
functionVariableUsage("void foo(int x)\n"
"{\n"
" int i;\n"
" if (x) {\n"
" int i;\n"
" } else {\n"
" int i;\n"
" }\n"
" i = 1;\n"
"}");
ASSERT_EQUALS("[test.cpp:9]: (style) Variable 'i' is assigned a value that is never used.\n"
"[test.cpp:5]: (style) Unused variable: i\n"
"[test.cpp:7]: (style) Unused variable: i\n", errout.str());
}
void localvar11() {
functionVariableUsage("void foo(int x)\n"
"{\n"
" int a = 0;\n"
" if (x == 1)\n"
" {\n"
" a = 123;\n" // redundant assignment
" return;\n"
" }\n"
" x = a;\n" // redundant assignment
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:9]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
// The variable 'a' is initialized. But the initialized value is
// never used. It is only initialized for security reasons.
functionVariableUsage("void foo(int x)\n"
"{\n"
" int a = 0;\n"
" if (x == 1)\n"
" a = 123;\n"
" else if (x == 2)\n"
" a = 456;\n"
" else\n"
" return;\n"
" x = a;\n"
"}");
ASSERT_EQUALS("[test.cpp:10]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
}
void localvar12() {
// ticket #1574
functionVariableUsage("void foo()\n"
"{\n"
" int a, b, c, d, e, f;\n"
" a = b = c = d = e = f = 15;\n"
"}");
ASSERT_EQUALS(
"[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Variable 'b' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Variable 'c' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Variable 'd' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Variable 'e' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Variable 'f' is assigned a value that is never used.\n",
errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a, b, c = 0;\n"
" a = b = c;\n"
"\n"
"}");
TODO_ASSERT_EQUALS(
"[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Variable 'b' is assigned a value that is never used.\n"
"[test.cpp:3]: (style) Variable 'c' is assigned a value that is never used.\n",
"[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Variable 'b' is assigned a value that is never used.\n",
errout.str());
}
void localvar13() { // ticket #1640
functionVariableUsage("void foo( OBJECT *obj )\n"
"{\n"
" int x;\n"
" x = obj->ySize / 8;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
}
void localvar14() {
// ticket #5
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: a\n", errout.str());
}
void localvar15() {
functionVariableUsage("int foo()\n"
"{\n"
" int a = 5;\n"
" int b[a];\n"
" b[0] = 0;\n"
" return b[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo()\n"
"{\n"
" int a = 5;\n"
" int * b[a];\n"
" b[0] = &c;\n"
" return *b[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int * foo()\n"
"{\n"
" int a = 5;\n"
" const int * b[a];\n"
" b[0] = &c;\n"
" return b[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct B * foo()\n"
"{\n"
" int a = 5;\n"
" struct B * b[a];\n"
" b[0] = &c;\n"
" return b[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("const struct B * foo()\n"
"{\n"
" int a = 5;\n"
" const struct B * b[a];\n"
" b[0] = &c;\n"
" return b[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar16() { // ticket #1709
functionVariableUsage("int foo()\n"
"{\n"
" char buf[5];\n"
" char *ptr = buf;\n"
" *(ptr++) = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("int foo()\n"
"{\n"
" char buf[5];\n"
" char *ptr = buf - 1;\n"
" *(++ptr) = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'buf' is not assigned a value.\n", errout.str());
// #3910
functionVariableUsage("int foo() {\n"
" char buf[5];\n"
" char *data[2];\n"
" data[0] = buf;\n"
" do_something(data);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo() {\n"
" char buf1[5];\n"
" char buf2[5];\n"
" char *data[2];\n"
" data[0] = buf1;\n"
" data[1] = buf2;\n"
" do_something(data);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar17() { // ticket #1720
// Don't crash when checking the code below!
functionVariableUsage("void foo()\n"
"{\n"
" struct DATA *data = DATA;\n"
" char *k = data->req;\n"
" char *ptr;\n"
" char *line_start;\n"
" ptr = data->buffer;\n"
" line_start = ptr;\n"
" data->info = k;\n"
" line_start = ptr;\n"
"}");
ASSERT_EQUALS("[test.cpp:10]: (style) Variable 'line_start' is assigned a value that is never used.\n", errout.str());
}
void localvar18() { // ticket #1723
functionVariableUsage("A::A(int iValue) {\n"
" UserDefinedException* pe = new UserDefinedException();\n"
" throw pe;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar19() { // ticket #1776
functionVariableUsage("void foo() {\n"
" int a[10];\n"
" int c;\n"
" c = *(a);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'c' is assigned a value that is never used.\n"
"[test.cpp:2]: (style) Variable 'a' is not assigned a value.\n", errout.str());
}
void localvar20() { // ticket #1799
functionVariableUsage("void foo()\n"
"{\n"
" char c1 = 'c';\n"
" char c2[] = { c1 };\n"
" a(c2);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar21() { // ticket #1807
functionVariableUsage("void foo()\n"
"{\n"
" char buffer[1024];\n"
" bar((void *)buffer);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar22() { // ticket #1811
functionVariableUsage("int foo(int u, int v)\n"
"{\n"
" int h, i;\n"
" h = 0 ? u : v;\n"
" i = 1 ? u : v;\n"
" return h + i;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar23() { // ticket #1808
functionVariableUsage("int foo(int c)\n"
"{\n"
" int a;\n"
" int b[10];\n"
" a = b[c] = 0;\n"
" return a;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
}
void localvar24() { // ticket #1803
functionVariableUsage("class MyException\n"
"{\n"
" virtual void raise() const\n"
" {\n"
" throw *this;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar25() { // ticket #1729
functionVariableUsage("int main() {\n"
" int ppos = 1;\n"
" int pneg = 0;\n"
" const char*edge = ppos? \" +\" : pneg ? \" -\" : \"\";\n"
" printf(\"This should be a '+' -> %s\n\", edge);\n"
" return 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar26() { // ticket #1894
functionVariableUsage("int main() {\n"
" const Fred &fred = getfred();\n"
" int *p = fred.x();\n"
" *p = 0;"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar27() { // ticket #2160
functionVariableUsage("void f(struct s *ptr) {\n"
" int param = 1;\n"
" ptr->param = param++;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar28() { // ticket #2205
functionVariableUsage("void f(char* buffer, int value) {\n"
" char* pos = buffer;\n"
" int size = value;\n"
" *(int*)pos = size;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar29() { // ticket #2206
functionVariableUsage("void f() {\n"
" float s_ranges[] = { 0, 256 };\n"
" float* ranges[] = { s_ranges };\n"
" cout << ranges[0][0];\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar30() { // ticket #2264
functionVariableUsage("void f() {\n"
" Engine *engine = e;\n"
" x->engine = engine->clone();\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar31() { // ticket #2286
functionVariableUsage("void f() {\n"
" int x = 0;\n"
" a.x = x - b;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar32() {
// ticket #2330 - fstream >> x
functionVariableUsage("void f() {\n"
" int x;\n"
" fstream &f = getfile();\n"
" f >> x;\n"
"}");
ASSERT_EQUALS("", errout.str());
// ticket #4596 - if (c >>= x) {}
functionVariableUsage("void f(int x) {\n"
" C c;\n" // possibly some stream class
" if (c >>= x) {}\n"
"}");
// TODO ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f(int x) {\n"
" C c;\n"
" if (c >>= x) {}\n"
"}", "test.c");
ASSERT_EQUALS("[test.c:3]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void f(int c) {\n"
" int x;\n"
" if (c >> x) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' is not assigned a value.\n", errout.str());
functionVariableUsage("void f() {\n"
" int x, y;\n"
" std::cin >> x >> y;\n"
"}");
ASSERT_EQUALS("", errout.str());
// ticket #8494
functionVariableUsage("void f(C c) {\n"
" int x;\n"
" c & x;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f(int c) {\n"
" int x;\n"
" c & x;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' is not assigned a value.\n", errout.str());
}
void localvar33() { // ticket #2345
functionVariableUsage("void f() {\n"
" Abc* abc = getabc();\n"
" while (0 != (abc = abc->next())) {\n"
" ++nOldNum;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar34() { // ticket #2368
functionVariableUsage("void f() {\n"
" int i = 0;\n"
" if (false) {\n"
" } else {\n"
" j -= i;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar35() { // ticket #2535
functionVariableUsage("void f() {\n"
" int a, b;\n"
" x(1,a,b);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar36() { // ticket #2805
functionVariableUsage("int f() {\n"
" int a, b;\n"
" a = 2 * (b = 3);\n"
" return a + b;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int f() {\n" // ticket #4318
" int a,b;\n"
" x(a, b=2);\n" // <- if param2 is passed-by-reference then b might be used in x
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo() {\n" // ticket #6147
" int a = 0;\n"
" bar(a=a+2);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo() {\n" // ticket #6147
" int a = 0;\n"
" bar(a=2);\n"
"}");
TODO_ASSERT_EQUALS("error", "", errout.str());
functionVariableUsage("void bar(int);\n"
"int foo() {\n"
" int a = 0;\n"
" bar(a=a+2);\n"
"}");
TODO_ASSERT_EQUALS("error", "", errout.str());
}
void localvar37() { // ticket #3078
functionVariableUsage("void f() {\n"
" int a = 2;\n"
" ints.at(a) = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar38() {
functionVariableUsage("std::string f() {\n"
" const char code[] = \"foo\";\n"
" const std::string s1(sizeof_(code));\n"
" const std::string s2 = sizeof_(code);\n"
" return(s1+s2);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar39() {
functionVariableUsage("void f() {\n"
" int a = 1;\n"
" foo(x*a);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar40() {
functionVariableUsage("int f() {\n"
" int a = 1;\n"
" return x & a;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar41() {
// #3603 - false positive 'x is assigned a value that is never used'
functionVariableUsage("int f() {\n"
" int x = 1;\n"
" int y = FOO::VALUE * x;\n"
" return y;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar42() { // #3742
functionVariableUsage("float g_float = 1;\n"
"extern void SomeTestFunc(float);\n"
"void MyFuncError()\n"
"{\n"
" const float floatA = 2.2f;\n"
" const float floatTot = g_float * floatA;\n"
" SomeTestFunc(floatTot);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("float g_float = 1;\n"
"extern void SomeTestFunc(float);\n"
"void MyFuncNoError()\n"
"{\n"
" const float floatB = 2.2f;\n"
" const float floatTot = floatB * g_float;\n"
" SomeTestFunc(floatTot);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("float g_float = 1;\n"
"extern void SomeTestFunc(float);\n"
"void MyFuncNoError2()\n"
"{\n"
" const float floatC = 2.2f;\n"
" float floatTot = g_float * floatC;\n"
" SomeTestFunc(floatTot);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar43() { // ticket #3602 (false positive)
functionVariableUsage("void bar()\n"
"{\n"
" int * piArray = NULL;\n"
" unsigned int uiArrayLength = 2048;\n"
" unsigned int uiIndex;\n"
"\n"
" try\n"
" {\n"
" piArray = new int[uiArrayLength];\n" // Allocate memory
" }\n"
" catch (...)\n"
" {\n"
" SOME_MACRO\n"
" delete [] piArray;\n"
" return;\n"
" }\n"
" for (uiIndex = 0; uiIndex < uiArrayLength; uiIndex++)\n"
" {\n"
" piArray[uiIndex] = -1234;\n"
" }\n"
" delete [] piArray;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar44() { // #4020 - FP
functionVariableUsage("void func() {\n"
" int *sp_mem[2] = { global1, global2 };\n"
" sp_mem[0][3] = 123;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar45() { // #4899 - FP
functionVariableUsage("int func() {\n"
" int a = 123;\n"
" int b = (short)-a;;\n"
" return b;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar46() { // #5491/#5494/#6301
functionVariableUsage("int func() {\n"
" int i = 0;\n"
" int j{i};\n"
" return j;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int func() {\n"
" std::mutex m;\n"
" std::unique_lock<std::mutex> l{ m };\n"
" return 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int func() {\n"
" std::shared_lock<std::shared_timed_mutex> lock( m );\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar47() { // #6603
functionVariableUsage("void f() {\n"
" int (SfxUndoManager::*retrieveCount)(bool) const\n"
" = (flag) ? &SfxUndoManager::foo : &SfxUndoManager::bar;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'retrieveCount' is assigned a value that is never used.\n", errout.str());
}
void localvar48() { // #6954
functionVariableUsage("void foo() {\n"
" long (*pKoeff)[256] = new long[9][256];\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar49() { // #7594
functionVariableUsage("class A {\n"
" public:\n"
" typedef enum { ID1,ID2,ID3 } Id_t;\n"
" typedef struct {Id_t id; std::string a; } x_t;\n"
" std::vector<x_t> m_vec;\n"
" std::vector<x_t> Get(void);\n"
" void DoSomething();\n"
"};\n"
"std::vector<A::x_t> A::Get(void) {\n"
" return m_vec;\n"
"}\n"
"const std::string Bar() {\n"
" return \"x\";\n"
"}\n"
"void A::DoSomething(void) {\n"
" const std::string x = Bar();\n" // <- warning
"}");
ASSERT_EQUALS("[test.cpp:16]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
}
void localvar50() { // #6261, #6542
// #6261 - ternary operator in function call
functionVariableUsage("void foo() {\n"
" char buf1[10];\n"
" dostuff(cond?buf1:buf2);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo() {\n"
" char buf1[10];\n"
" dostuff(cond?buf2:buf1);\n"
"}");
ASSERT_EQUALS("", errout.str());
// #6542 - ternary operator
functionVariableUsage("void foo(int c) {\n"
" char buf1[10], buf2[10];\n"
" char *p = c ? buf1 : buf2;\n"
" dostuff(p);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar51() { // #8128 FN
functionVariableUsage("void foo() {\n"
" const char *tok = var->nameToken();\n"
" tok = tok->next();\n" // read+write
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'tok' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo() {\n"
" int x = 4;\n"
" x = 15 + x;\n" // read+write
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
}
void localvar52() {
functionVariableUsage("void foo() {\n"
" std::vector<int> data;\n"
" data[2] = 32;\n"
" return data;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar53() {
functionVariableUsage("void foo() {\n"
" bool x = false;\n"
" while (loop) {\n"
" if (a) {\n"
" x = true;\n" // unused value
" continue;\n"
" }\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo() {\n"
" bool x = false;\n"
" while (loop) {\n"
" if (a) {\n"
" x = true;\n"
" continue;\n"
" }\n"
" }\n"
" return x;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar54() {
functionVariableUsage("Padding fun() {\n"
" Distance d = DISTANCE;\n"
" return (Padding){ d, d, d, d };\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar55() {
functionVariableUsage("void f(int mode) {\n"
" int x = 0;\n" // <- redundant assignment
"\n"
" for (int i = 0; i < 10; i++) {\n"
" if (mode == 0x04)\n"
" x = 0;\n" // <- redundant assignment
" if (mode == 0x0f) {\n"
" x = address;\n"
" data[x] = 0;\n"
" }\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' is assigned a value that is never used.\n"
"[test.cpp:6]: (style) Variable 'x' is assigned a value that is never used.\n",
errout.str());
}
void localvar56() {
functionVariableUsage("void f()\n"
"{\n"
" int x = 31;\n"
" mask[x] |= 123;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvar57() {
functionVariableUsage("void f()\n"
"{\n"
" int x = 0;\n"
" x++;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
}
void localvar58() { // #9901 - increment false positive
functionVariableUsage("void f() {\n"
" int x = 0;\n"
" if (--x > 0) {}\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f() {\n"
" int x = 0;\n"
" if (x-- > 0) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
}
void localvar59() { // #9737
functionVariableUsage("Response foo() {\n"
" const std::vector<char> cmanifest = z;\n"
" return {.a = cmanifest, .b =0};\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarloops() {
// loops
functionVariableUsage("void fun() {\n"
" int x;\n"
" while (c) { x=10; }\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void dostuff(int x);\n"
"void fun() {\n"
" int x = 1;\n"
" while (c) {\n"
" dostuff(x);\n"
" if (y) { x=10; break; }\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void dostuff(int &x);\n"
"void fun() {\n"
" int x = 1;\n"
" while (c) {\n"
" dostuff(x);\n"
" if (y) { x=10; break; }\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str()); // TODO : in this special case we can ignore that x is aliased. x is local and there are no function calls after the assignment
functionVariableUsage("void fun() {\n"
" int x = 0;\n"
" while (c) {\n"
" dostuff(x);\n"
" x = 10;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void fun() {\n"
" int x = 0;\n"
" while (x < 10) { x = x + 1; }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void fun()\n"
"{\n"
" int status = 0;\n"
" for (ind = 0; ((ind < nrArgs) && (status < 10)); ind++)\n"
" status = x;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f()\n"
"{\n"
" int sum = 0U;\n"
" for (i = 0U; i < 2U; i++)\n"
" sum += 123;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'sum' is assigned a value that is never used.\n"
"[test.cpp:5]: (style) Variable 'sum' is assigned a value that is never used.\n", errout.str());
}
void localvaralias1() {
functionVariableUsage("void foo()\n"
"{\n"
" int a;\n"
" int *b = &a;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'b' is assigned a value that is never used.\n"
"[test.cpp:3]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" int *b = a;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'b' is assigned a value that is never used.\n"
"[test.cpp:3]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a;\n"
" int *b = &a;\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a;\n"
" char *b = (char *)&a;\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a;\n"
" char *b = (char *)(&a);\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a;\n"
" const char *b = (const char *)&a;\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a;\n"
" const char *b = (const char *)(&a);\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a;\n"
" char *b = static_cast<char *>(&a);\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a;\n"
" const char *b = static_cast<const char *>(&a);\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
// a is not a local variable and b is aliased to it
functionVariableUsage("int a;\n"
"void foo()\n"
"{\n"
" int *b = &a;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
// a is not a local variable and b is aliased to it
functionVariableUsage("void foo(int a)\n"
"{\n"
" int *b = &a;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
// a is not a local variable and b is aliased to it
functionVariableUsage("class A\n"
"{\n"
" int a;\n"
" void foo()\n"
" {\n"
" int *b = &a;\n"
" }\n"
"}");
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("int a;\n"
"void foo()\n"
"{\n"
" int *b = &a;\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo(int a)\n"
"{\n"
" int *b = &a;\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("class A\n"
"{\n"
" int a;\n"
" void foo()\n"
" {\n"
" int *b = &a;\n"
" *b = 0;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" int *b = a;\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" char *b = (char *)a;\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" char *b = (char *)(a);\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" const char *b = (const char *)a;\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" const char *b = (const char *)(a);\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" char *b = static_cast<char *>(a);\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" const char *b = static_cast<const char *>(a);\n"
" *b = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("int a[10];\n"
"void foo()\n"
"{\n"
" int *b = a;\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int a[10];\n"
"void foo()\n"
"{\n"
" int *b = a;\n"
" int *c = b;\n"
" *c = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int *b = a;\n"
" int *c = b;\n"
" *c = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int *b = a;\n"
" int *c = b;\n"
" *c = b[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int *b = a;\n"
" int *c;\n"
" *c = b[0];\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'c' is not assigned a value.\n", errout.str());
functionVariableUsage("int a[10];\n"
"void foo()\n"
"{\n"
" int *b = a;\n"
" int c = b[0];\n"
" x(c);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int *b = a;\n"
" int c = b[0];\n"
" x(c);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int a[10];\n"
"void foo()\n"
"{\n"
" int *b = &a[0];\n"
" a[0] = b[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int *b = &a[0];\n"
" a[0] = b[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int *b = a;\n"
" a[0] = b[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo(int a[10])\n"
"{\n"
" int *b = a;\n"
" *b = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("class A\n"
"{\n"
" int a[10];\n"
" void foo()\n"
" {\n"
" int *b = a;\n"
" *b = 0;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" int *b = a;\n"
" int *c = b;\n"
" *c = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" int b[10];\n"
" int *c = a;\n"
" int *d = b;\n"
" *d = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: a\n"
// TODO "[test.cpp:7]: (style) Variable 'b' is assigned a value that is never used.\n"
// TODO "[test.cpp:5]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" int b[10];\n"
" int *c = a;\n"
" c = b;\n"
" *c = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: a\n"
// TODO "[test.cpp:7]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10];\n"
" int b[10];\n"
" int *c = a;\n"
" c = b;\n"
" *c = 0;\n"
" c = a;\n"
" *c = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:9]: (style) Variable 'a' is assigned a value that is never used.\n"
// TODO "[test.cpp:7]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10], * b = a + 10;\n"
" b[-10] = 1;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'b[-10]' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10], * b = a + 10;\n"
" b[-10] = 0;\n"
" int * c = b - 10;\n"
"}");
ASSERT_EQUALS(// TODO "[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:5]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10], * b = a + 10;\n"
" int * c = b - 10;\n"
" x = c[0];\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' is not assigned a value.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10], * b = a + 10;\n"
" int * c = b - 10;\n"
" c[1] = 3;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'c[1]' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10], * b = a + 10;\n"
" int * c = b - 10;\n"
" c[1] = c[0];\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'c[1]' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a[10], * b = a + 10;\n"
" int * c = b - 10;\n"
" int d = c[0];\n"
" f(d);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' is not assigned a value.\n", errout.str());
functionVariableUsage("void foo() {\n" // #4022 - FP (a is assigned a value that is never used)
" int a[2], *b[2];\n"
" a[0] = 123;\n"
" b[0] = &a[0];\n"
" int *d = b[0];\n"
" return *d;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo() {\n" // #4022 - FP (a is assigned a value that is never used)
" entry a[2], *b[2];\n"
" a[0].value = 123;\n"
" b[0] = &a[0];\n"
" int d = b[0].value;\n"
" return d;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct S { char c[100]; };\n"
"void foo()\n"
"{\n"
" char a[100];\n"
" struct S * s = (struct S *)a;\n"
" s->c[0] = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct S { char c[100]; };\n"
"void foo()\n"
"{\n"
" char a[100];\n"
" struct S * s = (struct S *)a;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 's' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("struct S { char c[100]; };\n"
"void foo()\n"
"{\n"
" char a[100];\n"
" const struct S * s = (const struct S *)a;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 's' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("struct S { char c[100]; };\n"
"void foo()\n"
"{\n"
" char a[100];\n"
" struct S * s = static_cast<struct S *>(a);\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 's' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("struct S { char c[100]; };\n"
"void foo()\n"
"{\n"
" char a[100];\n"
" const struct S * s = static_cast<const struct S *>(a);\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 's' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("int a[10];\n"
"void foo()\n"
"{\n"
" int b[10];\n"
" int c[10];\n"
" int *d;\n"
" d = b;\n"
" d = a;\n"
" d = c;\n"
" *d = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: b\n"
// TODO "[test.cpp:10]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("int a[10];\n"
"void foo()\n"
"{\n"
" int b[10];\n"
" int c[10];\n"
" int *d;\n"
" d = b; *d = 0;\n"
" d = a; *d = 0;\n"
" d = c; *d = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'b' is assigned a value that is never used.\n"
// TODO "[test.cpp:9]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
}
void localvaralias2() { // ticket 1637
functionVariableUsage("void foo()\n"
"{\n"
" int * a;\n"
" x(a);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvaralias3() { // ticket 1639
functionVariableUsage("void foo()\n"
"{\n"
" BROWSEINFO info;\n"
" char szDisplayName[MAX_PATH];\n"
" info.pszDisplayName = szDisplayName;\n"
" SHBrowseForFolder(&info);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvaralias4() { // ticket 1643
functionVariableUsage("struct AB { int a; int b; } ab;\n"
"void foo()\n"
"{\n"
" int * a = &ab.a;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("struct AB { int a; int b; } ab;\n"
"void foo()\n"
"{\n"
" int * a = &ab.a;\n"
" *a = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct AB { int a; int b; };\n"
"void foo()\n"
"{\n"
" struct AB ab;\n"
" int * a = &ab.a;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:4]: (style) Variable 'ab' is not assigned a value.\n", errout.str());
functionVariableUsage("struct AB { int a; int b; };\n"
"void foo()\n"
"{\n"
" struct AB ab;\n"
" int * a = &ab.a;\n"
" *a = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvaralias5() { // ticket 1647
functionVariableUsage("char foo()\n"
"{\n"
" char buf[8];\n"
" char *p = &buf[0];\n"
" *p++ = 0;\n"
" return buf[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("char foo()\n"
"{\n"
" char buf[8];\n"
" char *p = &buf[1];\n"
" *p-- = 0;\n"
" return buf[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("char foo()\n"
"{\n"
" char buf[8];\n"
" char *p = &buf[0];\n"
" *++p = 0;\n"
" return buf[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("char foo()\n"
"{\n"
" char buf[8];\n"
" char *p = &buf[1];\n"
" *--p = 0;\n"
" return buf[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvaralias6() { // ticket 1729
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" if (a()) {\n"
" buf[0] = 1;\n"
" srcdata = buf;\n"
" } else {\n"
" srcdata = vdata;\n"
" }\n"
" b(srcdata);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" if (a()) {\n"
" buf[0] = 1;\n"
" srcdata = buf;\n"
" srcdata = vdata;\n"
" }\n"
" b(srcdata);\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" if (a()) {\n"
" buf[0] = 1;\n"
" srcdata = buf;\n"
" }\n"
" srcdata = vdata;\n"
" b(srcdata);\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" if (a()) {\n"
" srcdata = buf;\n"
" }\n"
" srcdata = vdata;\n"
" b(srcdata);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: buf\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" if (a()) {\n"
" srcdata = vdata;\n"
" }\n"
" srcdata = buf;\n"
" b(srcdata);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" char vdata[8];\n"
" if (a()) {\n"
" buf[0] = 1;\n"
" srcdata = buf;\n"
" } else {\n"
" srcdata = vdata;\n"
" }\n"
" b(srcdata);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" char vdata[8];\n"
" if (a()) {\n"
" buf[0] = 1;\n"
" srcdata = buf;\n"
" srcdata = vdata;\n"
" }\n"
" b(srcdata);\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" char vdata[8];\n"
" if (a()) {\n"
" buf[0] = 1;\n"
" srcdata = buf;\n"
" }\n"
" srcdata = vdata;\n"
" b(srcdata);\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" char vdata[8];\n"
" if (a()) {\n"
" srcdata = buf;\n"
" }\n"
" srcdata = vdata;\n"
" b(srcdata);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: buf\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char buf[8];\n"
" char *srcdata;\n"
" char vdata[8];\n"
" if (a()) {\n"
" srcdata = vdata;\n"
" }\n"
" srcdata = buf;\n"
" b(srcdata);\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Unused variable: vdata\n", errout.str());
}
void localvaralias7() { // ticket 1732
functionVariableUsage("void foo()\n"
"{\n"
" char *c[10];\n"
" char **cp;\n"
" cp = c;\n"
" *cp = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvaralias8() {
functionVariableUsage("void foo()\n"
"{\n"
" char b1[8];\n"
" char b2[8];\n"
" char b3[8];\n"
" char b4[8];\n"
" char *pb;\n"
" if (a == 1)\n"
" pb = b1;\n"
" else if (a == 2)\n"
" pb = b2;\n"
" else if (a == 3)\n"
" pb = b3;\n"
" else\n"
" pb = b4;\n"
" b(pb);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char b1[8];\n"
" char b2[8];\n"
" char b3[8];\n"
" char b4[8];\n"
" char *pb;\n"
" if (a == 1)\n"
" pb = b1;\n"
" else if (a == 2)\n"
" pb = b2;\n"
" else if (a == 3)\n"
" pb = b3;\n"
" else {\n"
" pb = b1;\n"
" pb = b4;\n"
" }\n"
" b(pb);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char b1[8];\n"
" char b2[8];\n"
" char b3[8];\n"
" char b4[8];\n"
" char *pb;\n"
" if (a == 1)\n"
" pb = b1;\n"
" else if (a == 2)\n"
" pb = b2;\n"
" else if (a == 3)\n"
" pb = b3;\n"
" else {\n"
" pb = b1;\n"
" pb = b2;\n"
" pb = b3;\n"
" pb = b4;\n"
" }\n"
" b(pb);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char b1[8];\n"
" char b2[8];\n"
" char b3[8];\n"
" char b4[8];\n"
" char *pb;\n"
" if (a == 1)\n"
" pb = b1;\n"
" else if (a == 2)\n"
" pb = b2;\n"
" else if (a == 3)\n"
" pb = b3;\n"
" pb = b4;\n"
" b(pb);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: b1\n"
"[test.cpp:4]: (style) Unused variable: b2\n"
"[test.cpp:5]: (style) Unused variable: b3\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char b1[8];\n"
" char b2[8];\n"
" char b3[8];\n"
" char b4[8];\n"
" char *pb;\n"
" if (a == 1)\n"
" pb = b1;\n"
" else {\n"
" if (a == 2)\n"
" pb = b2;\n"
" else {\n"
" if (a == 3)\n"
" pb = b3;\n"
" else\n"
" pb = b4;\n"
" }\n"
" }\n"
" b(pb);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char b1[8];\n"
" char b2[8];\n"
" char b3[8];\n"
" char b4[8];\n"
" char *pb;\n"
" if (a == 1)\n"
" pb = b1;\n"
" else {\n"
" if (a == 2)\n"
" pb = b2;\n"
" else {\n"
" if (a == 3)\n"
" pb = b3;\n"
" else {\n"
" pb = b1;\n"
" pb = b4;\n"
" }\n"
" }\n"
" }\n"
" b(pb);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char b1[8];\n"
" char b2[8];\n"
" char b3[8];\n"
" char b4[8];\n"
" char *pb;\n"
" if (a == 1)\n"
" pb = b1;\n"
" else {\n"
" if (a == 2)\n"
" pb = b2;\n"
" else {\n"
" if (a == 3)\n"
" pb = b3;\n"
" else {\n"
" pb = b1;\n"
" pb = b2;\n"
" pb = b3;\n"
" pb = b4;\n"
" }\n"
" }\n"
" }\n"
" b(pb);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char b1[8];\n"
" char b2[8];\n"
" char b3[8];\n"
" char b4[8];\n"
" char *pb;\n"
" if (a == 1)\n"
" pb = b1;\n"
" else {\n"
" if (a == 2)\n"
" pb = b2;\n"
" else {\n"
" if (a == 3)\n"
" pb = b3;\n"
" }\n"
" }\n"
" pb = b4;\n"
" b(pb);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: b1\n"
"[test.cpp:4]: (style) Unused variable: b2\n"
"[test.cpp:5]: (style) Unused variable: b3\n", errout.str());
}
void localvaralias9() { // ticket 1996
functionVariableUsage("void foo()\n"
"{\n"
" Foo foo;\n"
" Foo &ref = foo;\n"
" ref[0] = 123;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" Foo foo;\n"
" Foo &ref = foo;\n"
" ref[0] = 123;\n"
"}",
"test.c");
// TODO ASSERT_EQUALS("[test.c:5]: (style) Variable 'foo' is assigned a value that is never used.\n", errout.str());
}
void localvaralias10() { // ticket 2004
functionVariableUsage("void foo(Foo &foo)\n"
"{\n"
" Foo &ref = foo;\n"
" int *x = &ref.x();\n"
" *x = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo(Foo &foo)\n"
"{\n"
" Foo &ref = foo;\n"
" int *x = &ref.x;\n"
" *x = 0;\n"
"}",
"test.c");
ASSERT_EQUALS("", errout.str());
}
void localvaralias11() { // #4423 - iterator
functionVariableUsage("void f(Foo &foo) {\n"
" std::set<int>::iterator x = foo.dostuff();\n"
" *(x) = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvaralias12() { // #4394
functionVariableUsage("void f(void) {\n"
" int a[4];\n"
" int *b = (int*)((int*)a+1);\n"
" x(b);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int f(void) {\n" // #4628
" int x=1,y;\n"
" y = (x * a) / 100;\n"
" return y;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvaralias13() { // #4487
functionVariableUsage("void f(char *p) {\n"
" char a[4];\n"
" p = a;\n"
" strcpy(p, \"x\");\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f(char *p) {\n"
" char a[4];\n"
" p = a;\n"
" strcpy(p, \"x\");\n"
"}");
TODO_ASSERT_EQUALS("a is assigned value that is never used", "", errout.str());
}
void localvaralias14() { // #5619
functionVariableUsage("char * dostuff(char *p);\n"
"void f() {\n"
" char a[4], *p=a;\n"
" p = dostuff(p);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'p' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("char * dostuff(char *&p);\n"
"void f() {\n"
" char a[4], *p=a;\n"
" p = dostuff(p);\n"
"}");
ASSERT_EQUALS("", errout.str()); // TODO: we can warn in this special case; variable is local and there are no function calls after the assignment
functionVariableUsage("void f() {\n"
" char a[4], *p=a;\n"
" p = dostuff(p);\n"
"}");
ASSERT_EQUALS("", errout.str()); // TODO: we can warn in this special case; variable is local and there are no function calls after the assignment
}
void localvaralias15() { // #6315
functionVariableUsage("void f() {\n"
" int x=3;\n"
" int *p = &x;\n"
" int *p2[1] = {p};\n"
" dostuff(p2);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvaralias16() {
functionVariableUsage("void f() {\n"
" auto x = dostuff();\n"
" p = x;\n"
" x->data[0] = 9;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvaralias17() {
functionVariableUsage("void f() {\n"
" int x;\n"
" unknown_type p = &x;\n"
" *p = 9;\n"
"}", "test.c");
ASSERT_EQUALS("", errout.str());
}
void localvaralias18() {
functionVariableUsage("void add( std::vector< std::pair< int, double > >& v)\n"
"{\n"
" std::vector< std::pair< int, double > >::iterator it;\n"
" for ( it = v.begin(); it != v.end(); ++it )\n"
" {\n"
" if ( x )\n"
" {\n"
" ( *it ).second = 0;\n"
" break;\n"
" }\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarasm() {
functionVariableUsage("void foo(int &b)\n"
"{\n"
" int a;\n"
" asm();\n"
" b = a;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarStruct1() {
functionVariableUsage("void foo()\n"
"{\n"
" static const struct{ int x, y, w, h; } bounds = {1,2,3,4};\n"
" return bounds.x + bounds.y + bounds.w + bounds.h;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarStruct2() {
functionVariableUsage("void foo()\n"
"{\n"
" struct ABC { int a, b, c; };\n"
" struct ABC abc = { 1, 2, 3 };\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'abc' is assigned a value that is never used.\n", errout.str());
}
void localvarStruct3() {
functionVariableUsage("void foo()\n"
"{\n"
" int a = 10;\n"
" union { struct { unsigned char x; }; unsigned char z; };\n"
" do {\n"
" func();\n"
" } while(a--);\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: x\n"
"[test.cpp:4]: (style) Unused variable: z\n", "", errout.str());
}
void localvarStruct5() {
functionVariableUsage("int foo() {\n"
" A a;\n"
" return a.i;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo() {\n"
" A a;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo() {\n"
" A a;\n"
" return 0;\n"
"}\n",
"test.c");
ASSERT_EQUALS("[test.c:2]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("struct A { int i; };\n"
"int foo() {\n"
" A a;\n"
" return a.i;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("class A { int i; };\n"
"int foo() {\n"
" A a;\n"
" return a.i;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct A { int i; };\n"
"int foo() {\n"
" A a;\n"
" a.i = 0;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a.i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("class A { int i; };\n"
"int foo() {\n"
" A a;\n"
" a.i = 0;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a.i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("struct A { int i; };\n"
"int foo() {\n"
" A a = { 0 };\n"
" return 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("class A { int i; };\n"
"int foo() {\n"
" A a = { 0 };\n"
" return 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("class A { int i; public: A(); { } };\n"
"int foo() {\n"
" A a;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct A { int i; };\n"
"int foo() {\n"
" A a;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("class A { int i; };\n"
"int foo() {\n"
" A a;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: a\n", errout.str());
functionVariableUsage("class A { int i; public: A(); { } };\n"
"int foo() {\n"
" A a;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("class A { unknown i; };\n"
"int foo() {\n"
" A a;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("class A : public Fred { int i; };\n"
"int foo() {\n"
" A a;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("class Fred {char c;};\n"
"class A : public Fred { int i; };\n"
"int foo() {\n"
" A a;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Unused variable: a\n", errout.str());
}
void localvarStruct6() {
functionVariableUsage("class Type { };\n"
"class A {\n"
"public:\n"
" Type & get() { return t; }\n"
"private:\n"
" Type t;\n"
"};");
ASSERT_EQUALS("", errout.str());
}
void localvarStruct7() {
functionVariableUsage("struct IMAPARG {\n"
" void *text;\n"
"};\n"
"\n"
"void fun() {\n"
" IMAPARG *args, aatt;\n"
" args = &aatt;\n"
" aatt.text = tmp;\n"
" dostuff(args);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct ARG {\n"
" void *a;\n"
" void *b;\n"
"};\n"
"\n"
"void fun() {\n"
" ARG aatt;\n"
" int *p = &aatt.b;\n"
" aatt.a = 123;\n"
" dostuff(p);\n"
"}");
ASSERT_EQUALS("[test.cpp:9]: (style) Variable 'aatt.a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("struct AB {\n"
" int a;\n"
" int b;\n"
"};\n"
"\n"
"void fun() {\n"
" AB ab;\n"
" int &a = ab.a;\n"
" ab.a = 123;\n"
" dostuff(a);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarStruct8() {
functionVariableUsage("struct s {\n"
" union {\n"
" struct {\n"
" int fld1 : 16;\n"
" int fld2 : 16;\n"
" };\n"
" int raw;\n"
" };\n"
"};\n"
"\n"
"void foo() {\n"
" struct s test;\n"
" test.raw = 0x100;\n"
" dostuff(test.fld1, test.fld2);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarStruct9() {
functionVariableUsage("struct XY { int x; int y; };\n"
"\n"
"void foo() {\n"
" struct XY xy(get());\n"
" return xy.x + xy.y;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarStructArray() {
// #3633 - detect that struct array is assigned a value
functionVariableUsage("void f() {\n"
" struct X x[10];\n"
" x[0].a = 5;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x[0].a' is assigned a value that is never used.\n", errout.str());
}
void localvarUnion1() {
// #9707
functionVariableUsage("static short read(FILE *fp) {\n"
" typedef union { short s; unsigned char c[2]; } u;\n"
" u x;\n"
" x.c[0] = fgetuc(fp);\n"
" x.c[1] = fgetuc(fp);\n"
" return x.s;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarOp() {
const char op[] = "+-*/%&|^";
for (const char *p = op; *p; ++p) {
std::string code("int main()\n"
"{\n"
" int tmp = 10;\n"
" return 123 " + std::string(1, *p) + " tmp;\n"
"}");
functionVariableUsage(code.c_str());
ASSERT_EQUALS("", errout.str());
}
}
void localvarInvert() {
functionVariableUsage("int main()\n"
"{\n"
" int tmp = 10;\n"
" return ~tmp;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarIf() {
functionVariableUsage("int main()\n"
"{\n"
" int tmp = 10;\n"
" if ( tmp )\n"
" return 1;\n"
" return 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarIfElse() {
functionVariableUsage("int foo()\n"
"{\n"
" int tmp1 = 1;\n"
" int tmp2 = 2;\n"
" int tmp3 = 3;\n"
" return tmp1 ? tmp2 : tmp3;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarDeclaredInIf() {
functionVariableUsage("int foo(int x)\n"
"{\n"
" if (int y = x % 2)\n"
" return 2;\n"
" else\n"
" return 1;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'y' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("int foo(int x)\n"
"{\n"
" if (int y = x % 2)\n"
" return y;\n"
" else\n"
" return 1;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo(int x)\n"
"{\n"
" if (int y = x % 2)\n"
" return 2;\n"
" else\n"
" return y;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarOpAssign() {
functionVariableUsage("void foo()\n"
"{\n"
" int a = 1;\n"
" int b = 2;\n"
" a |= b;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:5]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo() {\n"
" int a = 1;\n"
" (b).x += a;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo() {\n"
" int a=1, b[10];\n"
" b[0] = x;\n"
" a += b[0];\n"
" return a;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f(int *start, int *stop) {\n"
" int length = *start - *stop;\n"
" if (length < 10000)\n"
" length = 10000;\n"
" *stop -= length;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f(int a) {\n"
" int x = 3;\n"
" a &= ~x;\n"
" return a;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f() {\n" // unknown class => library configuration is needed
" Fred fred;\n"
" int *a; a = b;\n"
" fred += a;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (information) --check-library: Provide <type-checks><unusedvar> configuration for Fred\n", errout.str());
functionVariableUsage("void f() {\n"
" std::pair<int,int> fred;\n" // class with library configuration
" fred = x;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'fred' is assigned a value that is never used.\n", errout.str());
}
void localvarFor() {
functionVariableUsage("void foo()\n"
"{\n"
" int a = 1;\n"
" for (;a;);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo() {\n"
" for (int i = 0; (pci = cdi_list_get(pciDevices, i)); i++)\n"
" {}\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarForEach() { // #4155 - foreach
functionVariableUsage("void foo() {\n"
" int i = -1;\n"
" int a[] = {1,2,3};\n"
" FOREACH_X (int x, a) {\n"
" if (i==x) return x;\n"
" i = x;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
// #5154 - MSVC 'for each'
functionVariableUsage("void f() {\n"
" std::map<int,int> ints;\n"
" ints[0]= 1;\n"
" for each(std::pair<int,int> i in ints) { x += i.first; }\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarShift1() {
functionVariableUsage("int foo()\n"
"{\n"
" int var = 1;\n"
" return 1 >> var;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarShift3() { // #3509
functionVariableUsage("int foo()\n"
"{\n"
" QList<int *> ints;\n"
" ints << 1;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo() {\n" // #4320
" int x;\n"
" x << 1;\n"
" return x;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarCast() {
functionVariableUsage("int foo()\n"
"{\n"
" int a = 1;\n"
" int b = static_cast<int>(a);\n"
" return b;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarClass() {
functionVariableUsage("int foo()\n"
"{\n"
" class B : public A {\n"
" int a;\n"
" int f() { return a; }\n"
" } b;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarUnused() {
functionVariableUsage("int foo()\n"
"{\n"
" bool test __attribute__((unused));\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo()\n"
"{\n"
" bool test __attribute__((unused)) = true;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo()\n"
"{\n"
" bool __attribute__((unused)) test;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo()\n"
"{\n"
" bool __attribute__((unused)) test = true;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo()\n"
"{\n"
" bool test __attribute__((used));\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo()\n"
"{\n"
" bool __attribute__((used)) test;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarFunction() {
functionVariableUsage("void check_dlsym(void*& h)\n"
"{\n"
" typedef void (*function_type) (void);\n"
" function_type fn;\n"
" fn = reinterpret_cast<function_type>(dlsym(h, \"try_allocation\"));\n"
" fn();\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarstatic() {
functionVariableUsage("void foo()\n"
"{\n"
" static int i;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" static int i = 0;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" static int i(0);\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" static int j = 0;\n"
" static int i(j);\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("int * foo(int x)\n"
"{\n"
" static int a[] = { 3, 4, 5, 6 };\n"
" static int b[] = { 4, 5, 6, 7 };\n"
" static int c[] = { 5, 6, 7, 8 };\n"
" b[1] = 1;\n"
" return x ? a : c;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" static int i = 0;\n"
" if(i < foo())\n"
" i += 5;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo() {\n"
" static int x = 0;\n"
" print(x);\n"
" if(x > 5)\n"
" x = 0;\n"
" else\n"
" x++;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo(int value) {\n"
" static int array[16] = {0};\n"
" if(array[value]) {}\n"
" array[value] = 1;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarextern() {
functionVariableUsage("void foo() {\n"
" extern int i;\n"
" i = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvardynamic1() {
functionVariableUsage("void foo()\n"
"{\n"
" void* ptr = malloc(16);\n"
" free(ptr);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" void* ptr = g_malloc(16);\n"
" g_free(ptr);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" void* ptr = kmalloc(16, GFP_KERNEL);\n"
" kfree(ptr);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" void* ptr = vmalloc(16, GFP_KERNEL);\n"
" vfree(ptr);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char* ptr = new char[16];\n"
" delete[] ptr;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char* ptr = new ( nothrow ) char[16];\n"
" delete[] ptr;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char* ptr = new ( std::nothrow ) char[16];\n"
" delete[] ptr;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char* ptr = new char;\n"
" delete ptr;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" void* ptr = malloc(16);\n"
" ptr[0] = 123;\n"
" free(ptr);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char* ptr = new char[16];\n"
" ptr[0] = 123;\n"
" delete[] ptr;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" Fred* fred = new Fred;\n"
" std::cout << \"test\" << std::endl;\n"
" delete fred;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct Fred { int a; };\n"
"void foo()\n"
"{\n"
" Fred* fred = new Fred;\n"
" std::cout << \"test\" << std::endl;\n"
" delete fred;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'fred' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("struct Fred { int a; Fred() : a(0) {} };\n"
"void foo()\n"
"{\n"
" Fred* fred = new Fred;\n"
" std::cout << \"test\" << std::endl;\n"
" delete fred;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'fred' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" Fred* fred = malloc(sizeof(Fred));\n"
" std::cout << \"test\" << std::endl;\n"
" free(fred);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'fred' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" char* ptr = names[i];\n"
" delete[] ptr;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvardynamic2() {
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = malloc(sizeof(Fred));\n"
" free(ptr);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = malloc(sizeof(Fred));\n"
" ptr->i = 0;\n"
" free(ptr);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" struct Fred* ptr = malloc(sizeof(Fred));\n"
" free(ptr);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" struct Fred* ptr = malloc(sizeof(Fred));\n"
" ptr->i = 0;\n"
" free(ptr);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = new Fred();\n"
" delete ptr;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = new (nothrow ) Fred();\n"
" delete ptr;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = new (std::nothrow) Fred();\n"
" delete ptr;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = new Fred();\n"
" ptr->i = 0;\n"
" delete ptr;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" struct Fred* ptr = new Fred();\n"
" free(ptr);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("struct Fred { int i; };\n"
"void foo()\n"
"{\n"
" struct Fred* ptr = new Fred();\n"
" ptr->i = 0;\n"
" free(ptr);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("class Fred { public: int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = malloc(sizeof(Fred));\n"
" free(ptr);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("class Fred { public: int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = malloc(sizeof(Fred));\n"
" ptr->i = 0;\n"
" free(ptr);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("class Fred { public: int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = new Fred();\n"
" delete ptr;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
functionVariableUsage("class Fred { public: int i; };\n"
"void foo()\n"
"{\n"
" Fred* ptr = new Fred();\n"
" ptr->i = 0;\n"
" delete ptr;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvardynamic3() {
// Ticket #3467 - False positive that 'data' is not assigned a value
functionVariableUsage("void foo() {\n"
" int* data = new int[100];\n"
" int* p = data;\n"
" for ( int i = 0; i < 10; ++i )\n"
" p++;\n"
"}");
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'p' is modified but its new value is never used.\n", errout.str());
}
void localvararray1() {
functionVariableUsage("void foo() {\n"
" int p[5];\n"
" *p = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvararray2() {
functionVariableUsage("int foo() {\n"
" int p[5][5];\n"
" p[0][0] = 0;\n"
" return p[0][0];\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvararray3() {
functionVariableUsage("int foo() {\n"
" int p[5][5];\n"
" *((int*)p[0]) = 0;\n"
" return p[0][0];\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvararray4() {
functionVariableUsage("void foo() {\n"
" int p[1];\n"
" int *pp[0];\n"
" p[0] = 1;\n"
" *pp[0] = p[0];\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvararray5() {
functionVariableUsage("int foo() {\n"
" int p[5][5];\n"
" dostuff(*p);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarstring1() { // ticket #1597
functionVariableUsage("void foo() {\n"
" std::string s;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Unused variable: s\n", errout.str());
functionVariableUsage("void foo() {\n"
" std::string s;\n"
" s = \"foo\";\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 's' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo() {\n"
" std::string s = \"foo\";\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void foo() {\n" // #8901
" const std::string s = \"foo\";\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("std::string foo() {\n"
" std::string s;\n" // Class instances are initialized. Assignment is not necessary
" return s;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("std::string foo() {\n"
" std::string s = \"foo\";\n"
" return s;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarstring2() { // ticket #2929
functionVariableUsage("void foo() {\n"
" std::string s;\n"
" int i;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Unused variable: s\n"
"[test.cpp:3]: (style) Unused variable: i\n", errout.str());
}
void localvarconst1() {
functionVariableUsage("void foo() {\n"
" const bool b = true;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
}
void localvarconst2() {
functionVariableUsage("void foo() {\n"
" const int N = 10;\n"
" struct X { int x[N]; };\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarreturn() { // ticket #9167
functionVariableUsage("void foo() {\n"
" const int MyInt = 1;\n"
" class bar {\n"
" public:\n"
" bool operator()(const int &uIndexA, const int &uIndexB) const {\n"
" return true;\n"
" }\n"
" bar() {}\n"
" };\n"
" return MyInt;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarmaybeunused() {
functionVariableUsage("int main() {\n"
" [[maybe_unused]] int x;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("[[nodiscard]] int getX() { return 4; }\n"
"int main() {\n"
" [[maybe_unused]] int x = getX();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("[[nodiscard]] int getX() { return 4; }\n"
"int main() {\n"
" [[maybe_unused]] int x = getX();\n"
" x = getX();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("[[nodiscard]] int getX() { return 4; }\n"
"int main() {\n"
" [[maybe_unused]] int x = getX();\n"
" x = getX();\n"
" std::cout << x;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int main() {\n"
" [[maybe_unused]] const int x = getX();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int main() {\n"
" [[maybe_unused]] const int& x = getX();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int main() {\n"
" [[maybe_unused]] const int* x = getX();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int main() {\n"
" [[maybe_unused]] int& x = getX();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int main() {\n"
" [[maybe_unused]] int* x = getX();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int main() {\n"
" [[maybe_unused]] auto x = getX();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int main() {\n"
" [[maybe_unused]] auto&& x = getX();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int main() {\n"
" [[maybe_unused]] int x[] = getX();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int main() {\n"
" [[maybe_unused]] constexpr volatile static int x = 1;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("[[maybe_unused]] inline int x = 1;");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int main() {\n"
" [[maybe_unused]] [[anotherattribute]] const int* = 1;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarthrow() { // ticket #3687
functionVariableUsage("void foo() {\n"
" try {}"
" catch(Foo& bar) {}\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localVarStd() {
functionVariableUsage("void f() {\n"
" std::string x = foo();\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void f() {\n"
" std::vector<int> x;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Unused variable: x\n", errout.str());
functionVariableUsage("void f() {\n"
" std::vector<int> x(100);\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void f() {\n"
" std::vector<MyClass> x;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Unused variable: x\n", errout.str());
functionVariableUsage("void f() {\n"
" std::lock_guard<MyClass> lock(mutex_);\n" // Has a side-effect #4385
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f() {\n"
" pLocker = std::shared_ptr<jfxLocker>(new jfxLocker(m_lock, true));\n" // Could have side-effects (#4355)
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f() {\n"
" std::mutex m;\n"
" std::unique_lock<std::mutex> lock(m);\n" // #4624
"}");
ASSERT_EQUALS("", errout.str());
}
void localVarClass() {
functionVariableUsage("void f() {\n"
" Fred f;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("class C { int x; };\n"
"void f() {\n"
" C c;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: c\n", errout.str());
functionVariableUsage("class C { public: C(int); ~C(); };\n"
"void f() {\n"
" C c(12);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localVarSmartPtr() {
// handling of smart pointers (#9680)
functionVariableUsage("static int s_i = 0;\n"
"\n"
"class A {\n"
"public:\n"
" ~A() {\n"
" ++s_i;\n"
" }\n"
"};\n"
"\n"
"static void func() {\n"
" auto a = std::make_shared<A>();\n"
" auto a2 = std::unique_ptr<A>(new A());\n"
"}\n");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("class A {\n"
"public:\n"
" std::string x;\n"
"};\n"
"\n"
"static void func() {\n"
" auto a = std::make_shared<A>();\n"
" auto a2 = std::unique_ptr<A>(new A());\n"
"}\n");
ASSERT_EQUALS("[test.cpp:7]: (style) Variable 'a' is assigned a value that is never used.\n"
"[test.cpp:8]: (style) Variable 'a2' is assigned a value that is never used.\n", errout.str());
}
// ticket #3104 - false positive when variable is read with "if (NOT var)"
void localvarIfNOT() {
functionVariableUsage("void f() {\n"
" bool x = foo();\n"
" if (NOT x) { }\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarAnd() { // #3672
functionVariableUsage("int main() {\n"
" unsigned flag = 0x1 << i;\n"
" if (m_errorflags & flag) {\n"
" return 1;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarSwitch() { // #3744 - false positive when used in switch
functionVariableUsage("const char *f(int x) {\n"
" const char a[] = \"abc\";\n"
" const char def[] = \"def\";\n"
" const char *ptr;\n"
" switch(x) {\n"
" case 1: ptr=a; break;\n"
" default: ptr=def; break;\n"
" }\n"
" return ptr;\n"
"}");
ASSERT_EQUALS("", errout.str()); // Don't write an error that "a" is not used
functionVariableUsage("void x() {\n"
" unsigned char* pcOctet = NULL;\n"
" float fValeur;\n"
" switch (pnodeCurrent->left.pnode->usLen) {\n"
" case 4:\n"
" fValeur = (float)pevalDataLeft->data.fd;\n"
" pcOctet = (unsigned char*)&fValeur;\n"
" break;\n"
" case 8:\n"
" pcOctet = (unsigned char*)&pevalDataLeft->data.fd;\n"
" break;\n"
" }\n"
" for (iIndice = 1; iIndice <= (pnodeCurrent->usLen / 2); iIndice++) {\n"
" *pcData = gacHexChar[(*pcOctet >> 4) & 0x0F];\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str()); // Don't write an error that "fValeur" is not used
}
void localvarNULL() { // #4203 - Setting NULL value is not redundant - it is safe
functionVariableUsage("void f() {\n"
" char *p = malloc(100);\n"
" foo(p);\n"
" free(p);\n"
" p = NULL;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f(Foo *p) {\n"
" free(p);\n"
" p = (Foo *)NULL;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarUnusedGoto() {
// #4447
functionVariableUsage("bool f(const int &i) {\n"
" int X = i;\n"
"label:\n"
" if ( X == 0 ) {\n"
" X -= 101;\n"
" return true;\n"
" }\n"
" if ( X < 1001 ) {\n"
" X += 1;\n"
" goto label;\n"
" }\n"
" return false;\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'X' is assigned a value that is never used.\n", errout.str());
// #4558
functionVariableUsage("int f() {\n"
" int i,j=0;\n"
" start:\n"
" i=j;\n"
" i++;\n"
" j=i;\n"
" if (i<3)\n"
" goto start;\n"
" return i;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarLambda() {
functionVariableUsage("int foo() {\n"
" auto f = []{return 1};\n"
" return f();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo() {\n"
" auto f = []{return 1};\n"
" auto g = []{return 1};\n"
" return f() + g();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void foo(std::vector<int>& v) {\n"
" int n = 0;\n"
" std::generate(v.begin(), v.end(), [&n] {\n"
" int r = n;\n"
" n += 2;\n"
" return r;\n"
" });\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarCppInitialization() {
functionVariableUsage("void foo() {\n"
" int buf[6];\n"
" Data data(buf);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarCpp11Initialization() {
// #6160
functionVariableUsage("void foo() {\n"
" int myNewValue{ 3u };\n"
" myManager.theDummyTable.addRow(UnsignedIndexValue{ myNewValue }, DummyRowData{ false });\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarRangeBasedFor() {
// #7075
functionVariableUsage("void reset() {\n"
" for (auto & e : array)\n"
" e = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarAssignInWhile() {
functionVariableUsage("void foo() {\n"
" int a = 0;\n"
" do {\n"
" dostuff(a);\n"
" } while((a + = x) < 30);\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int foo() {\n"
" int var = 1;\n"
" while (var = var >> 1) { }\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarTemplate() {
functionVariableUsage("template<int A> void f() {}\n"
"void foo() {\n"
" const int x = 0;\n"
" f<x>();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f() {\n"
" constexpr std::size_t ArraySize(5);\n"
" std::array<int, ArraySize> X; X.dostuff();\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarFuncPtr() {
functionVariableUsage("int main() {\n"
" void(*funcPtr)(void)(x);\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'funcPtr' is assigned a value never used.\n", "", errout.str());
functionVariableUsage("int main() {\n"
" void(*funcPtr)(void);\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Unused variable: funcPtr\n", errout.str());
functionVariableUsage("int main() {\n"
" void(*funcPtr)(void)(x);\n"
" funcPtr();\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("int main() {\n"
" void(*funcPtr)(void) = x;\n"
" funcPtr();\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarAddr() { // #7747
functionVariableUsage("void f() {\n"
" int x = 0;\n"
" dostuff(&x);\n"
" x = 1;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f() {\n"
" int x = 0;\n"
" dostuff(std::ref(x));\n"
" x = 1;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void localvarDelete() { // #8339
functionVariableUsage("void reassign(char*& data, int size)"
"{"
" char* buf = new char[size];"
""
" char* tmp = data;"
" data = buf;"
" buf = tmp;"
""
" delete [] buf;"
"}");
ASSERT_EQUALS("", errout.str());
}
void chainedAssignment() {
// #5466
functionVariableUsage("void NotUsed(double* pdD, int n) {\n"
" double sum = 0.0;\n"
" for (int i = 0; i<n; ++i)\n"
" pdD[i] = (sum += pdD[i]);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void crash1() {
functionVariableUsage("SAL_WNODEPRECATED_DECLARATIONS_PUSH\n"
"void convertToTokenArray() {\n"
"}\n"
"SAL_WNODEPRECATED_DECLARATIONS_POP"); // #4033
}
void crash2() {
functionVariableUsage("template<unsigned dim>\n"
"struct Y: Y<dim-1> { };\n"
"template<>\n"
"struct Y<0> {};\n"
"void f() {\n"
" Y y;\n"
"}"); // #4695
}
void usingNamespace() {
functionVariableUsage("int foo() {\n"
" using namespace ::com::sun::star::i18n;\n"
" bool b = false;\n"
" int j = 0;\n"
" for (int i = 0; i < 3; i++) {\n"
" if (!b) {\n"
" j = 3;\n"
" b = true;\n"
" }\n"
" }\n"
" return j;\n"
"}"); // #4585
ASSERT_EQUALS("", errout.str());
}
void lambdaFunction() {
// #7026
functionVariableUsage("void f() {\n"
" bool first = true;\n"
"\n"
" auto do_something = [&first]() {\n"
" if (first) {\n"
" first = false;\n"
" } else {\n"
" dostuff();\n"
" }\n"
" };\n"
" do_something();\n"
" do_something();\n"
"}");
ASSERT_EQUALS("", errout.str());
// #4956 - assignment in for_each
functionVariableUsage("void f(std::vector<int> ints) {\n"
" int x = 0;\n"
" std::for_each(ints.begin(), ints.end(), [&x](int i){ dostuff(x); x = i; });\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage("void f(std::vector<int> ints) {\n"
" int x = 0;\n"
" std::for_each(ints.begin(), ints.end(), [&x](int i){ x += i; });\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x' is assigned a value that is never used.\n", "", errout.str());
}
void namespaces() { // #7557
functionVariableUsage("namespace t { namespace g {\n"
" typedef std::pair<BoostBox, size_t> value;\n"
"} }\n"
"namespace t { namespace g {} }\n"
"namespace t {\n"
" inline double getTime() const {\n"
" iterator it=find();\n"
" double& value=it->second.values[index];\n"
" if(isnan(value)) {\n"
" value=get();\n"
" }\n"
" return value;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void bracesInitCpp11() {
functionVariableUsage(
"int fun() {\n"
" static int fpUnread{0};\n"
" const int var{fpUnread++};\n"
" return var;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void argument() {
functionVariableUsage(
"void fun(Value value) {\n"
" value[10] = 123;\n"
"}");
ASSERT_EQUALS("", errout.str());
functionVariableUsage(
"void fun(std::string s) {\n"
" s[10] = 123;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's[10]' is assigned a value that is never used.\n", errout.str());
functionVariableUsage(
"void fun(short data[2]) {\n"
" data[2] = 1;\n"
"}"
);
ASSERT_EQUALS("", errout.str());
// Unknown argument type
functionVariableUsage(
"void A::b(Date& result) {"
" result = 12;\n"
"}"
);
ASSERT_EQUALS("", errout.str());
{
// #8914
functionVariableUsage( // assume unknown argument type is reference
"void fun(Date result) {"
" result.x = 12;\n"
"}"
);
ASSERT_EQUALS("", errout.str());
functionVariableUsage( // there is no reference type in C
"void fun(Date result) {"
" result.x = 12;\n"
"}",
"test.c"
);
ASSERT_EQUALS("[test.c:1]: (style) Variable 'result.x' is assigned a value that is never used.\n", errout.str());
functionVariableUsage(
"struct Date { int x; };\n"
"void fun(Date result) {"
" result.x = 12;\n"
"}"
);
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'result.x' is assigned a value that is never used.\n", errout.str());
}
// Unknown struct type
functionVariableUsage(
"void fun() {"
" struct FOO foo;\n"
" foo.x = 123;\n"
"}"
);
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'foo.x' is assigned a value that is never used.\n", errout.str());
}
void argumentClass() {
functionVariableUsage(
"void foo(std::insert_iterator<C> it) {\n"
" it = 123;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void escapeAlias() {
functionVariableUsage(
"struct A {\n"
" std::map<int, int> m;\n"
" void f(int key, int number) {\n"
" auto pos = m.find(key);\n"
" if (pos == m.end())\n"
" m.insert(std::map<int, int>::value_type(key, number));\n"
" else\n"
" (*pos).second = number;\n"
" }\n"
"};");
ASSERT_EQUALS("", errout.str());
}
void volatileData() {
functionVariableUsage(
"struct Data { unsigned int n; };\n"
"int main() {\n"
" (*(volatile struct Data*)0x4200).n = 1;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
};
REGISTER_TEST(TestUnusedVar)