-
Notifications
You must be signed in to change notification settings - Fork 76
Expand file tree
/
Copy pathStdMoveWithNonConstLvalue.ql
More file actions
56 lines (51 loc) · 1.69 KB
/
StdMoveWithNonConstLvalue.ql
File metadata and controls
56 lines (51 loc) · 1.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
* @id cpp/misra/std-move-with-non-const-lvalue
* @name RULE-28-6-1: The argument to std::move shall be a non-const lvalue
* @description Calling std::move on a const lvalue will not result in a move, and calling std::move
* on an rvalue is redundant.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-28-6-1
* scope/single-translation-unit
* correctness
* maintainability
* external/misra/enforcement/decidable
* external/misra/obligation/required
*/
import cpp
import codingstandards.cpp.standardlibrary.Utility
import codingstandards.cpp.ast.ValueCategory
predicate resolvesToConstOrConstRef(Type t) {
t.isConst()
or
resolvesToConstOrConstRef(t.(ReferenceType).getBaseType())
or
resolvesToConstOrConstRef(t.(TypedefType).getBaseType())
or
resolvesToConstOrConstRef(t.(Decltype).getBaseType())
}
predicate isConstLvalue(Expr arg) {
getValueCategory(arg).isLValue() and
resolvesToConstOrConstRef(arg.getType())
}
Type typeOfArgument(Expr e) {
// An xvalue may be a constructor, which has no return type. However, these xvalues act as values
// of the constructed type.
if e instanceof ConstructorCall
then result = e.(ConstructorCall).getTargetType()
else result = e.getType()
}
from StdMoveCall call, Expr arg, string description
where
arg = call.getArgument(0) and
(
isConstLvalue(arg) and
description = "const " + getValueCategory(arg).toString()
or
getValueCategory(arg).isRValue() and
description = getValueCategory(arg).toString()
)
select call,
"Call to 'std::move' with " + description + " argument of type '" + typeOfArgument(arg).toString()
+ "'."