Skip to content

Commit ee2ed07

Browse files
committed
Fix RULE-7-11-3 false positives for callees in templates
Inside class and function templates, an unqualified call to a member or free function can be modelled as a FunctionAccess that is the called expression of an ExprCall. Such an access is the callee of a call, not an implicit conversion to a function pointer, but it has function pointer type and was reported by FunctionPointerConversionContext. Exclude function accesses that are the called expression of an ExprCall, and add test cases for member, static member and free function calls inside templates.
1 parent bc8a0eb commit ee2ed07

3 files changed

Lines changed: 36 additions & 2 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- `RULE-7-11-3` - `FunctionPointerConversionContext.ql`:
2+
- Fixed false positives on unqualified calls to member and free functions inside class and function templates, where the callee is modelled as a function access that is the called expression of a call rather than a conversion to a function pointer.

‎cpp/misra/src/rules/RULE-7-11-3/FunctionPointerConversionContext.ql‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ class FunctionAccessConversionToFunctionPointer extends FunctionAccess,
3333
FunctionToFunctionPointerConversion
3434
{
3535
FunctionAccessConversionToFunctionPointer() {
36-
this.getType().getUnspecifiedType() instanceof FunctionPointerIshType
36+
this.getType().getUnspecifiedType() instanceof FunctionPointerIshType and
37+
// In templates, the callee of a dependent call is modelled as a function access that is the
38+
// called expression of an ExprCall. This is a function call, not a conversion.
39+
not any(ExprCall call).getExpr() = this
3740
}
3841
}
3942

‎cpp/misra/test/rules/RULE-7-11-3/test.cpp‎

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,33 @@ void test_logical_expressions() {
9595
// Lambda used in logical OR expression
9696
if (lam || false) { // NON_COMPLIANT
9797
}
98-
}
98+
}
99+
template <typename T> class TemplateWithMemberCalls {
100+
public:
101+
void callMembers() {
102+
helper(); // COMPLIANT: callee of a call, not a conversion
103+
this->helper(); // COMPLIANT
104+
staticHelper(); // COMPLIANT
105+
TemplateWithMemberCalls::staticHelper(); // COMPLIANT
106+
}
107+
108+
auto takeAddress() {
109+
return &TemplateWithMemberCalls::helper; // COMPLIANT: member pointer, not a
110+
// function pointer
111+
}
112+
113+
private:
114+
void helper() {}
115+
static void staticHelper() {}
116+
};
117+
118+
template <typename T> void templateCallsFree() {
119+
f(); // COMPLIANT
120+
}
121+
122+
void instantiate() {
123+
TemplateWithMemberCalls<int> t;
124+
t.callMembers();
125+
t.takeAddress();
126+
templateCallsFree<int>();
127+
}

0 commit comments

Comments
 (0)