Skip to content

Commit b19874a

Browse files
committed
Exclude literals that are the result of constexpr variable uses.
1 parent 31f5ba4 commit b19874a

File tree

4 files changed

+48
-2
lines changed

4 files changed

+48
-2
lines changed

cpp/autosar/src/rules/A5-1-1/LiteralValueUsedOutsideTypeInit.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ where
5151
// Aggregate literal
5252
not l = any(ArrayOrVectorAggregateLiteral aal).getAnElementExpr(_).getAChild*() and
5353
// Ignore x - 1 expressions
54-
not exists(SubExpr se | se.getRightOperand() = l and l.getValue() = "1")
54+
not exists(SubExpr se | se.getRightOperand() = l and l.getValue() = "1") and
55+
not l instanceof CompileTimeComputedIntegralLiteral
5556
select l,
5657
"Literal value " + getTruncatedLiteralText(l) + " used outside of type initialization " +
5758
l.getAPrimaryQlClass()

cpp/autosar/test/rules/A5-1-1/LiteralValueUsedOutsideTypeInit.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
| test.cpp:54:7:54:7 | 1 | Literal value 1 used outside of type initialization Literal |
44
| test.cpp:75:23:75:28 | test | Literal value "test" used outside of type initialization StringLiteral |
55
| test.cpp:76:19:76:28 | not okay | Literal value "not okay" used outside of type initialization StringLiteral |
6+
| test.cpp:104:8:104:8 | 4 | Literal value 4 used outside of type initialization Literal |
7+
| test.cpp:104:8:104:8 | 4 | Literal value 4 used outside of type initialization Literal |
8+
| test.cpp:104:8:104:8 | 4 | Literal value 4 used outside of type initialization Literal |
9+
| test.cpp:108:18:108:18 | 1 | Literal value 1 used outside of type initialization Literal |

cpp/autosar/test/rules/A5-1-1/test.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,32 @@ void test_not_wrapper_stream(std::ostream &os, const char *str) noexcept {
8080
#define MACRO_LOG(test_str) \
8181
do { \
8282
struct test_struct { \
83-
static const char *get_str() { return static_cast<char *>(test_str); } \
83+
static const char *get_str() { \
84+
return static_cast<const char *>(test_str); \
85+
} \
8486
}; \
8587
} while (false)
8688

8789
void f() {
8890
MACRO_LOG("test"); // COMPLIANT - exclusion
91+
}
92+
93+
template <typename T> struct S1 { static constexpr size_t value(); };
94+
95+
template <> struct S1<int> {
96+
static constexpr size_t value() { return sizeof(int); };
97+
};
98+
99+
constexpr size_t g1 = S1<int>::value();
100+
constexpr size_t f1() { return sizeof(int); }
101+
102+
template <typename T, int size> struct S2 {
103+
T m1[size]; // COMPLIANT
104+
T m2[4]; // NON_COMPLIANT
105+
};
106+
107+
void test_fp_reported_in_371() {
108+
struct S2<int, 1> l1; // COMPLIANT[FALSE_POSITIVE]
109+
struct S2<int, g1> l2; // COMPLIANT
110+
struct S2<int, f1()> l3; // COMPLIANT
89111
}

cpp/common/src/codingstandards/cpp/Literals.qll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,22 @@ class Utf16StringLiteral extends StringLiteral {
2828
class Utf32StringLiteral extends StringLiteral {
2929
Utf32StringLiteral() { this.getValueText().regexpMatch("(?s)\\s*U\".*") }
3030
}
31+
32+
/**
33+
* A literal resulting from the use of a constexpr
34+
* variable, or macro expansion.
35+
*/
36+
class CompileTimeComputedIntegralLiteral extends Literal {
37+
CompileTimeComputedIntegralLiteral() {
38+
this.getUnspecifiedType() instanceof IntegralType and
39+
not this.getUnspecifiedType() instanceof BoolType and
40+
not this.getUnspecifiedType() instanceof CharType and
41+
// In some cases we still type char constants like '.' as int
42+
not this.getValueText().trim().matches("'%'") and
43+
not this.getValueText()
44+
.trim()
45+
.regexpMatch("([0-9][0-9']*|0[xX][0-9a-fA-F']+|0b[01']+)[uU]?([lL]{1,2}|[zZ])?") and
46+
// Exclude class field initializers whose value text equals the initializer expression, e.g., `x(0)`
47+
not any(ConstructorFieldInit cfi).getExpr() = this
48+
}
49+
}

0 commit comments

Comments
 (0)