Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions change_notes/2024-02-16-fix-fps-a5-1-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- `A5-1-1` - `LiteralValueUsedOutsideTypeInit.ql`:
- Address FP reported in #371. Exclude literals generated by uses of constexpr variables.
- Exclude literals used in class template instantiations.
- Update the alert message to adhere to the style-guide.
10 changes: 6 additions & 4 deletions cpp/autosar/src/rules/A5-1-1/LiteralValueUsedOutsideTypeInit.ql
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ where
// Aggregate literal
not l = any(ArrayOrVectorAggregateLiteral aal).getAnElementExpr(_).getAChild*() and
// Ignore x - 1 expressions
not exists(SubExpr se | se.getRightOperand() = l and l.getValue() = "1")
select l,
"Literal value " + getTruncatedLiteralText(l) + " used outside of type initialization " +
l.getAPrimaryQlClass()
not exists(SubExpr se | se.getRightOperand() = l and l.getValue() = "1") and
not l instanceof CompileTimeComputedIntegralLiteral and
// Exclude literals to instantiate a class template per example in the standard
// where an type of std::array is intialized with size 5.
not l = any(ClassTemplateInstantiation cti).getATemplateArgument()
select l, "Literal value '" + getTruncatedLiteralText(l) + "' used outside of type initialization."
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
| test.cpp:5:9:5:25 | constant string | Literal value "constant string" used outside of type initialization StringLiteral |
| test.cpp:14:23:14:25 | 100 | Literal value 100 used outside of type initialization Literal |
| test.cpp:54:7:54:7 | 1 | Literal value 1 used outside of type initialization Literal |
| test.cpp:75:23:75:28 | test | Literal value "test" used outside of type initialization StringLiteral |
| test.cpp:76:19:76:28 | not okay | Literal value "not okay" used outside of type initialization StringLiteral |
| test.cpp:5:9:5:25 | constant string | Literal value '"constant string"' used outside of type initialization. |
| test.cpp:14:23:14:25 | 100 | Literal value '100' used outside of type initialization. |
| test.cpp:54:7:54:7 | 1 | Literal value '1' used outside of type initialization. |
| test.cpp:75:23:75:28 | test | Literal value '"test"' used outside of type initialization. |
| test.cpp:76:19:76:28 | not okay | Literal value '"not okay"' used outside of type initialization. |
| test.cpp:104:8:104:8 | 4 | Literal value '4' used outside of type initialization. |
| test.cpp:104:8:104:8 | 4 | Literal value '4' used outside of type initialization. |
| test.cpp:104:8:104:8 | 4 | Literal value '4' used outside of type initialization. |
24 changes: 23 additions & 1 deletion cpp/autosar/test/rules/A5-1-1/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,32 @@ void test_not_wrapper_stream(std::ostream &os, const char *str) noexcept {
#define MACRO_LOG(test_str) \
do { \
struct test_struct { \
static const char *get_str() { return static_cast<char *>(test_str); } \
static const char *get_str() { \
return static_cast<const char *>(test_str); \
} \
}; \
} while (false)

void f() {
MACRO_LOG("test"); // COMPLIANT - exclusion
}

template <typename T> struct S1 { static constexpr size_t value(); };

template <> struct S1<int> {
static constexpr size_t value() { return sizeof(int); };
};

constexpr size_t g1 = S1<int>::value();
constexpr size_t f1() { return sizeof(int); }

template <typename T, int size> struct S2 {
T m1[size]; // COMPLIANT
T m2[4]; // NON_COMPLIANT
};

void test_fp_reported_in_371() {
struct S2<int, 1> l1; // COMPLIANT
struct S2<int, g1> l2; // COMPLIANT
struct S2<int, f1()> l3; // COMPLIANT
}
19 changes: 19 additions & 0 deletions cpp/common/src/codingstandards/cpp/Literals.qll
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,22 @@ class Utf16StringLiteral extends StringLiteral {
class Utf32StringLiteral extends StringLiteral {
Utf32StringLiteral() { this.getValueText().regexpMatch("(?s)\\s*U\".*") }
}

/**
* A literal resulting from the use of a constexpr
* variable, or macro expansion.
*/
class CompileTimeComputedIntegralLiteral extends Literal {
CompileTimeComputedIntegralLiteral() {
this.getUnspecifiedType() instanceof IntegralType and
not this.getUnspecifiedType() instanceof BoolType and
not this.getUnspecifiedType() instanceof CharType and
// In some cases we still type char constants like '.' as int
not this.getValueText().trim().matches("'%'") and
not this.getValueText()
.trim()
.regexpMatch("([0-9][0-9']*|0[xX][0-9a-fA-F']+|0b[01']+)[uU]?([lL]{1,2}|[zZ])?") and
// Exclude class field initializers whose value text equals the initializer expression, e.g., `x(0)`
not any(ConstructorFieldInit cfi).getExpr() = this
}
}