Skip to content
Merged
2 changes: 2 additions & 0 deletions change_notes/2024-01-30-exclusion-a13-3-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
`A13-3-1` - `FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql`:
- Fixes #399. Exclude functions that have different number of parameters.
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,36 @@ class Candidate extends TemplateFunction {
}
}

from Candidate c, Function f
from
Candidate c, Function f, Function overload, Function overloaded, string msg,
string firstMsgSegment
where
not isExcluded(f,
OperatorsPackage::functionThatContainsForwardingReferenceAsItsArgumentOverloadedQuery()) and
not f.isDeleted() and
f = c.getAnOverload()
select f, "Function overloads a $@ with a forwarding reference parameter.", c, "function"
f = c.getAnOverload() and
// allow for overloading with different number of parameters, because there is no
// confusion on what function will be called.
f.getNumberOfParameters() = c.getNumberOfParameters() and
//build a dynamic select statement that guarantees to read that the overloading function is the explicit one
if
(f instanceof CopyConstructor or f instanceof MoveConstructor) and
f.isCompilerGenerated()
then (
(
f instanceof CopyConstructor and
msg = "implicit copy constructor"
or
f instanceof MoveConstructor and
msg = "implicit move constructor"
) and
firstMsgSegment = " with a forwarding reference parameter " and
overloaded = f and
overload = c
) else (
msg = "function with a forwarding reference parameter" and
firstMsgSegment = " " and
overloaded = c and
overload = f
)
select overload, "Function" + firstMsgSegment + "overloads a $@.", overloaded, msg
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
| test.cpp:24:6:24:7 | F1 | Function overloads a $@ with a forwarding reference parameter. | test.cpp:27:25:27:26 | F1 | function |
| test.cpp:49:3:49:3 | A | Function overloads a $@ with a forwarding reference parameter. | test.cpp:47:3:47:3 | A | function |
| test.cpp:50:3:50:3 | A | Function overloads a $@ with a forwarding reference parameter. | test.cpp:47:3:47:3 | A | function |
| test.cpp:63:8:63:8 | B | Function overloads a $@ with a forwarding reference parameter. | test.cpp:66:3:66:3 | B | function |
| test.cpp:63:8:63:8 | B | Function overloads a $@ with a forwarding reference parameter. | test.cpp:66:3:66:3 | B | function |
| test.cpp:24:6:24:7 | F1 | Function overloads a $@. | test.cpp:27:25:27:26 | F1 | function with a forwarding reference parameter |
| test.cpp:50:3:50:3 | A | Function overloads a $@. | test.cpp:48:3:48:3 | A | function with a forwarding reference parameter |
| test.cpp:51:3:51:3 | A | Function overloads a $@. | test.cpp:48:3:48:3 | A | function with a forwarding reference parameter |
| test.cpp:69:3:69:3 | B | Function with a forwarding reference parameter overloads a $@. | test.cpp:64:8:64:8 | B | implicit copy constructor |
| test.cpp:69:3:69:3 | B | Function with a forwarding reference parameter overloads a $@. | test.cpp:64:8:64:8 | B | implicit move constructor |
| test.cpp:77:25:77:25 | C | Function with a forwarding reference parameter overloads a $@. | test.cpp:74:7:74:7 | C | implicit copy constructor |
| test.cpp:77:25:77:25 | C | Function with a forwarding reference parameter overloads a $@. | test.cpp:74:7:74:7 | C | implicit move constructor |
19 changes: 14 additions & 5 deletions cpp/autosar/test/rules/A13-3-1/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ template <class T> void F1(T &&x) {} //

class A {
public:
// COMPLIANT by exception, constrained to not match copy/move ctors
// COMPLIANT[FALSE_POSITIVE] - by exception, constrained to not match
// copy/move ctors
template <
typename T,
std::enable_if_t<!std::is_same<
Expand All @@ -61,9 +62,17 @@ A b(a);
void F1(int &) = delete; // COMPLIANT by exception

struct B {
template <typename T,
std::enable_if_t<!std::is_same<T, B>::value> * = nullptr>
B(T &&value) {}
template <
typename T,
std::enable_if_t<!std::is_same<
std::remove_cv_t<std::remove_reference_t<T>>, A>::value> * = nullptr>
B(T &&value) {} // COMPLIANT[FALSE_POSITIVE] - by exception
};

int main() {}
int main() {}

class C {
public:
C() {}
template <typename T> C(T &&) {} // NON_COMPLIANT
};