Skip to content

Commit 18eae16

Browse files
authored
Merge branch 'main' into codeql/upgrade-to-2.14.6
2 parents 91fd477 + c719039 commit 18eae16

7 files changed

+82
-21
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
* `A7-3-1` - `HiddenInheritedNonOverridableMemberFunction.ql`:
2+
- Reduce duplication by reporting only a single location for each declaration of a problematic element.
3+
- Reduce duplication when reporting the hidden function by reporting only one declaration entry.
4+
- Improve performance by eliminating a number of bad join orders.
5+
- Fix false positives where the using declaration occurred after the function declaration.
6+
- Exclude special member functions, which cannot be inherited.
7+
- Exclude private member functions, which cannot be inherited.

cpp/autosar/src/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.ql

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,45 @@
1515

1616
import cpp
1717
import codingstandards.cpp.autosar
18+
import codingstandards.cpp.Class
1819

19-
from FunctionDeclarationEntry overridingDecl, FunctionDeclarationEntry hiddenDecl
20+
/**
21+
* Holds if the class has a non-virtual member function with the given name.
22+
*/
23+
pragma[noinline, nomagic]
24+
predicate hasNonVirtualMemberFunction(Class clazz, MemberFunction mf, string name) {
25+
mf.getDeclaringType() = clazz and
26+
mf.getName() = name and
27+
not mf.isVirtual() and
28+
// Exclude private member functions, which cannot be inherited.
29+
not mf.isPrivate()
30+
}
31+
32+
/**
33+
* Holds if the member function is in a class with the given base class, and has the given name.
34+
*/
35+
pragma[noinline, nomagic]
36+
predicate hasDeclarationBaseClass(MemberFunction mf, Class baseClass, string functionName) {
37+
baseClass = mf.getDeclaringType().getABaseClass() and
38+
functionName = mf.getName()
39+
}
40+
41+
from MemberFunction overridingDecl, MemberFunction hiddenDecl, Class baseClass, string name
2042
where
2143
not isExcluded(overridingDecl, ScopePackage::hiddenInheritedNonOverridableMemberFunctionQuery()) and
2244
// Check if we are overriding a non-virtual inherited member function
23-
overridingDecl.getName() = hiddenDecl.getName() and
24-
overridingDecl.getDeclaration().getDeclaringType().getABaseClass() =
25-
hiddenDecl.getDeclaration().getDeclaringType() and
26-
not hiddenDecl.getDeclaration().isVirtual() and
45+
hasNonVirtualMemberFunction(baseClass, hiddenDecl, name) and
46+
hasDeclarationBaseClass(overridingDecl, baseClass, name) and
2747
// Where the hidden member function isn't explicitly brought in scope through a using declaration.
2848
not exists(UsingDeclarationEntry ude |
29-
ude.getDeclaration() = hiddenDecl.getDeclaration() and
30-
ude.getEnclosingElement() = overridingDecl.getDeclaration().getDeclaringType() and
31-
ude.getLocation().getStartLine() < overridingDecl.getLocation().getStartLine()
49+
ude.getDeclaration() = hiddenDecl and
50+
ude.getEnclosingElement() = overridingDecl.getDeclaringType()
3251
) and
3352
// Exclude compiler generated member functions which include things like copy constructor that hide base class
3453
// copy constructors.
35-
not overridingDecl.getDeclaration().isCompilerGenerated()
54+
not overridingDecl.isCompilerGenerated() and
55+
// Exclude special member functions, which cannot be inherited.
56+
not overridingDecl instanceof SpecialMemberFunction
3657
select overridingDecl,
37-
"Declaration for member '" + overridingDecl.getName() +
38-
"' hides non-overridable inherited member function $@", hiddenDecl, hiddenDecl.getName()
58+
"Declaration for member '" + name + "' hides non-overridable inherited member function $@",
59+
hiddenDecl, hiddenDecl.getName()

cpp/autosar/src/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.ql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ where
2121
not isExcluded(overridingDecl, ScopePackage::hiddenInheritedOverridableMemberFunctionQuery()) and
2222
// Check if we are overriding a virtual inherited member function
2323
hiddenDecl.getDeclaration().isVirtual() and
24+
// Exclude private member functions, which cannot be inherited.
25+
not hiddenDecl.getDeclaration().(MemberFunction).isPrivate() and
2426
// The overriding declaration hides the hidden declaration if:
2527
(
2628
// 1. the overriding declaration overrides a function in a base class that is an overload of the hidden declaration
@@ -36,8 +38,7 @@ where
3638
// and the hidden declaration isn't explicitly brought in scope through a using declaration.
3739
not exists(UsingDeclarationEntry ude |
3840
ude.getDeclaration() = hiddenDecl.getDeclaration() and
39-
ude.getEnclosingElement() = overridingDecl.getDeclaration().getDeclaringType() and
40-
ude.getLocation().getStartLine() < overridingDecl.getLocation().getStartLine()
41+
ude.getEnclosingElement() = overridingDecl.getDeclaration().getDeclaringType()
4142
)
4243
or
4344
// 2. if the overriding declaration doesn't override a base member function but has the same name
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
| test.cpp:42:6:42:7 | declaration of f1 | Definition for 'f1' is not available for unqualified lookup because it is declared after $@ | test.cpp:39:12:39:13 | using f1 | using-declaration |
1+
| test.cpp:46:6:46:7 | declaration of f1 | Definition for 'f1' is not available for unqualified lookup because it is declared after $@ | test.cpp:43:12:43:13 | using f1 | using-declaration |
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
| test.cpp:16:8:16:9 | declaration of f1 | Declaration for member 'f1' hides non-overridable inherited member function $@ | test.cpp:7:8:7:9 | declaration of f1 | f1 |
1+
| test.cpp:20:8:20:9 | f1 | Declaration for member 'f1' hides non-overridable inherited member function $@ | test.cpp:7:8:7:9 | f1 | f1 |
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
| test.cpp:18:8:18:9 | declaration of f2 | Declaration for member 'f2' hides overridable inherited member function $@ | test.cpp:9:16:9:17 | declaration of f2 | f2 |
2-
| test.cpp:18:8:18:9 | declaration of f2 | Declaration for member 'f2' hides overridable inherited member function $@ | test.cpp:11:16:11:17 | declaration of f2 | f2 |
3-
| test.cpp:23:8:23:9 | declaration of f2 | Declaration for member 'f2' hides overridable inherited member function $@ | test.cpp:9:16:9:17 | declaration of f2 | f2 |
4-
| test.cpp:23:8:23:9 | declaration of f2 | Declaration for member 'f2' hides overridable inherited member function $@ | test.cpp:10:16:10:17 | declaration of f2 | f2 |
5-
| test.cpp:23:8:23:9 | declaration of f2 | Declaration for member 'f2' hides overridable inherited member function $@ | test.cpp:11:16:11:17 | declaration of f2 | f2 |
1+
| test.cpp:22:8:22:9 | declaration of f2 | Declaration for member 'f2' hides overridable inherited member function $@ | test.cpp:9:16:9:17 | declaration of f2 | f2 |
2+
| test.cpp:22:8:22:9 | declaration of f2 | Declaration for member 'f2' hides overridable inherited member function $@ | test.cpp:11:16:11:17 | declaration of f2 | f2 |
3+
| test.cpp:27:8:27:9 | declaration of f2 | Declaration for member 'f2' hides overridable inherited member function $@ | test.cpp:9:16:9:17 | declaration of f2 | f2 |
4+
| test.cpp:27:8:27:9 | declaration of f2 | Declaration for member 'f2' hides overridable inherited member function $@ | test.cpp:10:16:10:17 | declaration of f2 | f2 |
5+
| test.cpp:27:8:27:9 | declaration of f2 | Declaration for member 'f2' hides overridable inherited member function $@ | test.cpp:11:16:11:17 | declaration of f2 | f2 |

cpp/autosar/test/rules/A7-3-1/test.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ class C1 {
99
virtual void f2(int);
1010
virtual void f2(double);
1111
virtual void f2(S1);
12+
13+
private:
14+
void f3(int);
15+
void f4(int);
1216
};
1317

1418
class C2 : public C1 {
@@ -47,7 +51,7 @@ void f1() {
4751
l1.f1(0); // calls C2::f1(double) instead of C1::f1(int)
4852
l1.f2(0); // calls C2::f2(double) instead of C1::f2(int)
4953
// S1 s1;
50-
// l1.f2(s1); Won't compile because there is no suitable conversion fro S1 to
54+
// l1.f2(s1); Won't compile because there is no suitable conversion from S1 to
5155
// double.
5256
C1 &l2{l1};
5357
l2.f1(0); // calls C1::f1(int)
@@ -60,3 +64,31 @@ void f1() {
6064
S1 l4;
6165
l3.f2(l4); // calls C1:f2(S1)
6266
}
67+
68+
class C5 : public C1 {
69+
public:
70+
void f1(double); // COMPLIANT
71+
using C1::f1; // order of using and f1 declaration is not relevant
72+
73+
void f2(double) override; // COMPLIANT
74+
using C1::f2; // order of using and f2 declaration is not relevant
75+
};
76+
77+
void f2() {
78+
C5 c5;
79+
c5.f1(0); // calls C1::f1(int)
80+
c5.f1(0.0); // calls C5::f1(double)
81+
c5.f2(0); // calls C1::f2(int)
82+
c5.f2(0.0); // calls C5::f2(double)
83+
}
84+
85+
class C6 : public C1 {
86+
public:
87+
C6 &operator=(const C6 &); // COMPLIANT
88+
};
89+
90+
class C7 : public C1 {
91+
void f3(int); // COMPLIANT
92+
93+
void f4(int); // COMPLIANT
94+
};

0 commit comments

Comments
 (0)