Skip to content

Commit f92139d

Browse files
authored
Merge pull request #4202 from geoffw0/localhidesparam
C++: Improve handling of template functions in cpp/declaration-hides-parameter
2 parents 5ffc959 + 156a174 commit f92139d

File tree

5 files changed

+89
-4
lines changed

5 files changed

+89
-4
lines changed

change-notes/1.26/analysis-cpp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
1313

1414
| **Query** | **Expected impact** | **Change** |
1515
|----------------------------|------------------------|------------------------------------------------------------------|
16+
| Declaration hides parameter (`cpp/declaration-hides-parameter`) | Fewer false positive results | False positives involving template functions have been fixed. |
1617
| Inconsistent direction of for loop (`cpp/inconsistent-loop-direction`) | Fewer false positive results | The query now accounts for intentional wrapping of an unsigned loop counter. |
1718
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | | The precision of this query has been decreased from "high" to "medium". As a result, the query is still run but results are no longer displayed on LGTM by default. |
1819
| Comparison result is always the same (`cpp/constant-comparison`) | More correct results | Bounds on expressions involving multiplication can now be determined in more cases. |

cpp/ql/src/Best Practices/Hiding/DeclarationHidesParameter.ql

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,35 @@
1111

1212
import cpp
1313

14+
/**
15+
* Gets the template that a function `f` is constructed from, or just `f` if it
16+
* is not from a template instantiation.
17+
*/
18+
Function getConstructedFrom(Function f) {
19+
f.isConstructedFrom(result)
20+
or
21+
not f.isConstructedFrom(_) and
22+
result = f
23+
}
24+
1425
/**
1526
* Gets the parameter of `f` with name `name`, which has to come from the
1627
* _definition_ of `f` and not a prototype declaration.
1728
* We also exclude names from functions that have multiple definitions.
1829
* This should not happen in a single application but since we
1930
* have a system wide view it is likely to happen for instance for
2031
* the main function.
32+
*
33+
* Note: we use `getConstructedFrom` to ensure that we look at template
34+
* functions rather than their instantiations. We get better results this way
35+
* as the instantiation is artificial and may have inherited parameter names
36+
* from the declaration rather than the definition.
2137
*/
2238
ParameterDeclarationEntry functionParameterNames(Function f, string name) {
2339
exists(FunctionDeclarationEntry fe |
2440
result.getFunctionDeclarationEntry() = fe and
25-
fe.getFunction() = f and
41+
getConstructedFrom(f).getDefinition() = fe and
2642
fe.getLocation() = f.getDefinitionLocation() and
27-
result.getFile() = fe.getFile() and // Work around CPP-331
2843
strictcount(f.getDefinitionLocation()) = 1 and
2944
result.getName() = name
3045
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
| hiding.cpp:4:17:4:18 | ii | Local variable 'ii' hides a $@. | hiding.cpp:2:12:2:13 | definition of ii | parameter of the same name |
22
| hiding.cpp:15:15:15:16 | kk | Local variable 'kk' hides a $@. | hiding.cpp:12:25:12:26 | definition of kk | parameter of the same name |
3+
| hiding.cpp:28:7:28:7 | a | Local variable 'a' hides a $@. | hiding.cpp:26:21:26:21 | definition of a | parameter of the same name |
4+
| hiding.cpp:45:7:45:7 | a | Local variable 'a' hides a $@. | hiding.cpp:43:41:43:41 | definition of a | parameter of the same name |
5+
| hiding.cpp:64:11:64:11 | i | Local variable 'i' hides a $@. | hiding.cpp:61:20:61:20 | definition of i | parameter of the same name |
6+
| hiding.cpp:78:7:78:10 | arg1 | Local variable 'arg1' hides a $@. | hiding.cpp:74:28:74:31 | definition of arg1 | parameter of the same name |
7+
| hiding.cpp:79:5:79:8 | arg2 | Local variable 'arg2' hides a $@. | hiding.cpp:74:36:74:39 | definition of arg2 | parameter of the same name |

cpp/ql/test/query-tests/Best Practices/Hiding/DeclarationHidesParameter/hiding.cpp

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
void f(int ii) {
33
if (1) {
4-
for(int ii = 1; ii < 10; ii++) {
4+
for(int ii = 1; ii < 10; ii++) { // local variable hides parameter of the same name
55
;
66
}
77
}
@@ -12,7 +12,7 @@ namespace foo {
1212
void f2(int ii, int kk) {
1313
try {
1414
for (ii = 0; ii < 3; ii++) {
15-
int kk;
15+
int kk; // local variable hides parameter of the same name
1616
}
1717
}
1818
catch (int ee) {
@@ -21,4 +21,61 @@ namespace foo {
2121
}
2222
}
2323

24+
void myFunction(int a, int b, int c);
2425

26+
void myFunction(int a, int b, int _c) {
27+
{
28+
int a = a; // local variable hides parameter of the same name
29+
int _b = b;
30+
int c = _c;
31+
32+
// ...
33+
}
34+
}
35+
36+
template<class T>
37+
class MyTemplateClass {
38+
public:
39+
void myMethod(int a, int b, int c);
40+
};
41+
42+
template<class T>
43+
void MyTemplateClass<T> :: myMethod(int a, int b, int _c) {
44+
{
45+
int a = a; // local variable hides parameter of the same name
46+
int _b = b;
47+
int c = _c;
48+
49+
// ...
50+
}
51+
}
52+
53+
MyTemplateClass<int> mtc_i;
54+
55+
void test() {
56+
mtc_i.myMethod(0, 0, 0);
57+
}
58+
59+
#define MYMACRO for (int i = 0; i < 10; i++) {}
60+
61+
void testMacro(int i) {
62+
MYMACRO;
63+
64+
for (int i = 0; i < 10; i++) {}; // local variable hides parameter of the same name
65+
}
66+
67+
#include "hiding.h"
68+
69+
void myClass::myCaller(void) {
70+
this->myMethod(5, 6);
71+
}
72+
73+
template <typename T>
74+
void myClass::myMethod(int arg1, T arg2) {
75+
{
76+
int protoArg1;
77+
T protoArg2;
78+
int arg1; // local variable hides parameter of the same name
79+
T arg2; // local variable hides parameter of the same name
80+
}
81+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
class myClass {
3+
public:
4+
template <typename T>
5+
void myMethod(int protoArg1, T protoArg2);
6+
void myCaller(void);
7+
};

0 commit comments

Comments
 (0)