Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
5 changes: 4 additions & 1 deletion cpp/ql/src/Likely Bugs/Arithmetic/PointlessComparison.ql
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ import UnsignedGEZero
//
// So to reduce the number of false positives, we do not report a result if
// the comparison is in a macro expansion. Similarly for template
// instantiations.
// instantiations, static asserts, non-type template arguments, and constexprs.
from ComparisonOperation cmp, SmallSide ss, float left, float right, boolean value, string reason
where
not cmp.isInMacroExpansion() and
not cmp.isFromTemplateInstantiation(_) and
not exists(StaticAssert s | s.getCondition() = cmp.getParent*()) and
not exists(Declaration d | d.getATemplateArgument() = cmp.getParent*()) and
not exists(Variable v | v.isConstexpr() | v.getInitializer().getExpr() = cmp.getParent*()) and
not functionContainsDisabledCode(cmp.getEnclosingFunction()) and
reachablePointlessComparison(cmp, left, right, value, ss) and
// a comparison between an enum and zero is always valid because whether
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ void constantAddresses(int param) {
constexpr int *array2d = &int_arr_arr[1][1] + 1;
constexpr int *const_ints = &int_arr_arr[int_const][extern_int_const];

// Commented out because clang and EDG disagree on whether this is
// constant.
//constexpr int *stmtexpr_int = &int_arr[ ({ 1; }) ];
constexpr int *stmtexpr_int = &int_arr[ ({ 1; }) ];

constexpr int *comma_int = &int_arr[ ((void)0, 1) ];
constexpr int *comma_addr = ((void)0, &int_var);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
| addresses.cpp:29:35:29:54 | & ... | stmtexpr_int | misclassified as NOT constant |
| addresses.cpp:31:32:31:55 | & ... | comma_int | misclassified as NOT constant |
| addresses.cpp:36:39:36:70 | ... ? ... : ... | ternary_ptr_cond | misclassified as NOT constant |
| addresses.cpp:37:35:37:69 | & ... | ptr_subtract | misclassified as NOT constant |
| addresses.cpp:39:35:39:50 | ... + ... | constexpr_va | misclassified as NOT constant |
8 changes: 8 additions & 0 deletions cpp/ql/test/library-tests/ir/ir/PrintAST.expected
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
#-----| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [RValueReferenceType] __va_list_tag &&
#-----| [CopyAssignmentOperator] std::__va_list& std::__va_list::operator=(std::__va_list const&)
#-----| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const __va_list &
#-----| [MoveAssignmentOperator] std::__va_list& std::__va_list::operator=(std::__va_list&&)
#-----| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [RValueReferenceType] __va_list &&
#-----| [Operator,TopLevelFunction] void operator delete(void*)
#-----| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
Expand Down
40 changes: 20 additions & 20 deletions cpp/ql/test/library-tests/ir/ir/aliased_ir.expected
Original file line number Diff line number Diff line change
Expand Up @@ -9648,29 +9648,29 @@ ir.cpp:
# 1054| r1054_1(glval<decltype([...](...){...})>) = VariableAddress[lambda_inits] :
# 1054| r1054_2(glval<decltype([...](...){...})>) = VariableAddress[#temp1054:22] :
# 1054| m1054_3(decltype([...](...){...})) = Uninitialized[#temp1054:22] : &:r1054_2
# 1054| r1054_4(glval<String &>) = FieldAddress[s] : r1054_2
# 1054| r1054_5(glval<String &>) = VariableAddress[s] :
# 1054| r1054_6(String &) = Load[s] : &:r1054_5, m1040_9
# 1054| r1054_7(glval<String>) = CopyValue : r1054_6
# 1054| r1054_8(String &) = CopyValue : r1054_7
# 1054| m1054_9(String &) = Store[?] : &:r1054_4, r1054_8
# 1054| r1054_4(glval<int>) = FieldAddress[i] : r1054_2
# 1054| r1054_5(glval<int>) = VariableAddress[x] :
# 1054| r1054_6(int) = Load[x] : &:r1054_5, ~m1052_7
# 1054| r1054_7(int) = Constant[1] :
# 1054| r1054_8(int) = Add : r1054_6, r1054_7
# 1054| m1054_9(int) = Store[?] : &:r1054_4, r1054_8
# 1054| m1054_10(decltype([...](...){...})) = Chi : total:m1054_3, partial:m1054_9
# 1054| r1054_11(glval<int>) = FieldAddress[x] : r1054_2
# 1054| r1054_12(glval<int>) = VariableAddress[x] :
# 1054| r1054_13(int) = Load[x] : &:r1054_12, ~m1052_7
# 1054| m1054_14(int) = Store[?] : &:r1054_11, r1054_13
# 1054| r1054_11(glval<int &>) = FieldAddress[j] : r1054_2
# 1054| r1054_12(glval<int>) = VariableAddress[r] :
# 1054| r1054_13(int &) = CopyValue : r1054_12
# 1054| m1054_14(int &) = Store[?] : &:r1054_11, r1054_13
# 1054| m1054_15(decltype([...](...){...})) = Chi : total:m1054_10, partial:m1054_14
# 1054| r1054_16(glval<int>) = FieldAddress[i] : r1054_2
# 1054| r1054_17(glval<int>) = VariableAddress[x] :
# 1054| r1054_18(int) = Load[x] : &:r1054_17, ~m1052_7
# 1054| r1054_19(int) = Constant[1] :
# 1054| r1054_20(int) = Add : r1054_18, r1054_19
# 1054| m1054_21(int) = Store[?] : &:r1054_16, r1054_20
# 1054| r1054_16(glval<String &>) = FieldAddress[s] : r1054_2
# 1054| r1054_17(glval<String &>) = VariableAddress[s] :
# 1054| r1054_18(String &) = Load[s] : &:r1054_17, m1040_9
# 1054| r1054_19(glval<String>) = CopyValue : r1054_18
# 1054| r1054_20(String &) = CopyValue : r1054_19
# 1054| m1054_21(String &) = Store[?] : &:r1054_16, r1054_20
# 1054| m1054_22(decltype([...](...){...})) = Chi : total:m1054_15, partial:m1054_21
# 1054| r1054_23(glval<int &>) = FieldAddress[j] : r1054_2
# 1054| r1054_24(glval<int>) = VariableAddress[r] :
# 1054| r1054_25(int &) = CopyValue : r1054_24
# 1054| m1054_26(int &) = Store[?] : &:r1054_23, r1054_25
# 1054| r1054_23(glval<int>) = FieldAddress[x] : r1054_2
# 1054| r1054_24(glval<int>) = VariableAddress[x] :
# 1054| r1054_25(int) = Load[x] : &:r1054_24, ~m1052_7
# 1054| m1054_26(int) = Store[?] : &:r1054_23, r1054_25
# 1054| m1054_27(decltype([...](...){...})) = Chi : total:m1054_22, partial:m1054_26
# 1054| r1054_28(decltype([...](...){...})) = Load[#temp1054:22] : &:r1054_2, m1054_27
# 1054| m1054_29(decltype([...](...){...})) = Store[lambda_inits] : &:r1054_1, r1054_28
Expand Down
40 changes: 20 additions & 20 deletions cpp/ql/test/library-tests/ir/ir/raw_ir.expected
Original file line number Diff line number Diff line change
Expand Up @@ -8892,26 +8892,26 @@ ir.cpp:
# 1054| r1054_1(glval<decltype([...](...){...})>) = VariableAddress[lambda_inits] :
# 1054| r1054_2(glval<decltype([...](...){...})>) = VariableAddress[#temp1054:22] :
# 1054| mu1054_3(decltype([...](...){...})) = Uninitialized[#temp1054:22] : &:r1054_2
# 1054| r1054_4(glval<String &>) = FieldAddress[s] : r1054_2
# 1054| r1054_5(glval<String &>) = VariableAddress[s] :
# 1054| r1054_6(String &) = Load[s] : &:r1054_5, ~m?
# 1054| r1054_7(glval<String>) = CopyValue : r1054_6
# 1054| r1054_8(String &) = CopyValue : r1054_7
# 1054| mu1054_9(String &) = Store[?] : &:r1054_4, r1054_8
# 1054| r1054_10(glval<int>) = FieldAddress[x] : r1054_2
# 1054| r1054_11(glval<int>) = VariableAddress[x] :
# 1054| r1054_12(int) = Load[x] : &:r1054_11, ~m?
# 1054| mu1054_13(int) = Store[?] : &:r1054_10, r1054_12
# 1054| r1054_14(glval<int>) = FieldAddress[i] : r1054_2
# 1054| r1054_15(glval<int>) = VariableAddress[x] :
# 1054| r1054_16(int) = Load[x] : &:r1054_15, ~m?
# 1054| r1054_17(int) = Constant[1] :
# 1054| r1054_18(int) = Add : r1054_16, r1054_17
# 1054| mu1054_19(int) = Store[?] : &:r1054_14, r1054_18
# 1054| r1054_20(glval<int &>) = FieldAddress[j] : r1054_2
# 1054| r1054_21(glval<int>) = VariableAddress[r] :
# 1054| r1054_22(int &) = CopyValue : r1054_21
# 1054| mu1054_23(int &) = Store[?] : &:r1054_20, r1054_22
# 1054| r1054_4(glval<int>) = FieldAddress[i] : r1054_2
# 1054| r1054_5(glval<int>) = VariableAddress[x] :
# 1054| r1054_6(int) = Load[x] : &:r1054_5, ~m?
# 1054| r1054_7(int) = Constant[1] :
# 1054| r1054_8(int) = Add : r1054_6, r1054_7
# 1054| mu1054_9(int) = Store[?] : &:r1054_4, r1054_8
# 1054| r1054_10(glval<int &>) = FieldAddress[j] : r1054_2
# 1054| r1054_11(glval<int>) = VariableAddress[r] :
# 1054| r1054_12(int &) = CopyValue : r1054_11
# 1054| mu1054_13(int &) = Store[?] : &:r1054_10, r1054_12
# 1054| r1054_14(glval<String &>) = FieldAddress[s] : r1054_2
# 1054| r1054_15(glval<String &>) = VariableAddress[s] :
# 1054| r1054_16(String &) = Load[s] : &:r1054_15, ~m?
# 1054| r1054_17(glval<String>) = CopyValue : r1054_16
# 1054| r1054_18(String &) = CopyValue : r1054_17
# 1054| mu1054_19(String &) = Store[?] : &:r1054_14, r1054_18
# 1054| r1054_20(glval<int>) = FieldAddress[x] : r1054_2
# 1054| r1054_21(glval<int>) = VariableAddress[x] :
# 1054| r1054_22(int) = Load[x] : &:r1054_21, ~m?
# 1054| mu1054_23(int) = Store[?] : &:r1054_20, r1054_22
# 1054| r1054_24(decltype([...](...){...})) = Load[#temp1054:22] : &:r1054_2, ~m?
# 1054| mu1054_25(decltype([...](...){...})) = Store[lambda_inits] : &:r1054_1, r1054_24
# 1055| r1055_1(glval<decltype([...](...){...})>) = VariableAddress[lambda_inits] :
Expand Down
4 changes: 2 additions & 2 deletions cpp/ql/test/library-tests/scopes/parents/parents.expected
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
| 0 | file://:0:0:0:0 | (global namespace) | file://:0:0:0:0 | __va_list_tag |
| 0 | file://:0:0:0:0 | (global namespace) | parents.cpp:2:11:2:13 | foo |
| 0 | file://:0:0:0:0 | (global namespace) | parents.cpp:18:3:18:3 | var |
| 0 | file://:0:0:0:0 | (global namespace) | parents.cpp:18:7:18:7 | var |
| 0 | file://:0:0:0:0 | (global namespace) | parents.cpp:18:3:18:5 | var |
| 0 | file://:0:0:0:0 | (global namespace) | parents.cpp:20:5:20:5 | g |
| 1 | file://:0:0:0:0 | __va_list_tag | file://:0:0:0:0 | fp_offset |
| 1 | file://:0:0:0:0 | __va_list_tag | file://:0:0:0:0 | gp_offset |
Expand All @@ -22,6 +22,6 @@
| 1 | parents.cpp:6:11:10:7 | { ... } | parents.cpp:7:9:9:9 | for(...;...;...) ... |
| 1 | parents.cpp:6:11:10:7 | { ... } | parents.cpp:7:33:9:9 | { ... } |
| 1 | parents.cpp:7:33:9:9 | { ... } | parents.cpp:8:15:8:15 | k |
| 1 | parents.cpp:18:7:18:7 | var | parents.cpp:17:19:17:19 | T |
| 1 | parents.cpp:18:3:18:5 | var | parents.cpp:17:19:17:19 | T |
| 1 | parents.cpp:20:5:20:5 | g | parents.cpp:20:9:24:1 | { ... } |
| 1 | parents.cpp:20:9:24:1 | { ... } | parents.cpp:21:16:21:16 | l |
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ isFromUninstantiatedTemplate
| isfromtemplateinstantiation.cpp:99:1:99:1 | return ... | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<T> |
| isfromtemplateinstantiation.cpp:99:1:99:1 | return ... | isfromtemplateinstantiation.cpp:97:25:97:60 | myMethod2 |
| isfromtemplateinstantiation.cpp:99:1:99:1 | return ... | isfromtemplateinstantiation.cpp:97:52:97:52 | myMethod2 |
| isfromtemplateinstantiation.cpp:110:15:110:15 | definition of var_template | isfromtemplateinstantiation.cpp:110:15:110:15 | var_template |
| isfromtemplateinstantiation.cpp:110:15:110:15 | var_template | isfromtemplateinstantiation.cpp:110:15:110:15 | var_template |
| isfromtemplateinstantiation.cpp:110:3:110:14 | definition of var_template | isfromtemplateinstantiation.cpp:110:3:110:14 | var_template |
| isfromtemplateinstantiation.cpp:110:3:110:14 | var_template | isfromtemplateinstantiation.cpp:110:3:110:14 | var_template |
| isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass<T *> | isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass<T *> |
| isfromtemplateinstantiation.cpp:128:7:128:30 | definition of AnotherTemplateClass<T *> | isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass<T *> |
| isfromtemplateinstantiation.cpp:129:6:129:6 | definition of f | isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass<T *> |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
| variables.cpp:2:13:2:13 | pi | variables.cpp:25:12:25:16 | T | |
| variables.cpp:2:13:2:13 | pi | variables.cpp:25:12:25:16, variables.cpp:37:16:37:24 | float | |
| variables.cpp:2:13:2:13 | pi | variables.cpp:25:12:25:16, variables.cpp:38:16:38:22 | int | |
| variables.cpp:2:16:2:16 | pi | | T | TemplateVariable |
| variables.cpp:2:13:2:14 | pi | | T | TemplateVariable |
| variables.cpp:5:23:5:37 | pi | | const char * | |
| variables.cpp:8:13:8:13 | multi_arg | variables.cpp:33:19:33:33 | S, T | |
| variables.cpp:8:13:8:13 | multi_arg | variables.cpp:33:19:33:33 | float, char | |
| variables.cpp:8:13:8:13 | multi_arg | variables.cpp:33:19:33:33 | short, long | |
| variables.cpp:8:13:8:13 | multi_arg | variables.cpp:40:23:40:60 | unsigned int, unsigned char | |
| variables.cpp:8:13:8:13 | multi_arg | variables.cpp:41:23:41:42 | int, char | |
| variables.cpp:8:23:8:23 | multi_arg | | S, T | TemplateVariable |
| variables.cpp:8:13:8:21 | multi_arg | | S, T | TemplateVariable |
| variables.cpp:11:3:11:3 | mutable_val | variables.cpp:26:3:26:16 | T | |
| variables.cpp:11:3:11:3 | mutable_val | variables.cpp:26:3:26:16 | float | |
| variables.cpp:11:3:11:3 | mutable_val | variables.cpp:26:3:26:16, variables.cpp:43:3:43:18 | int | |
| variables.cpp:11:3:11:3 | mutable_val | variables.cpp:44:3:44:19 | long | |
| variables.cpp:11:15:11:15 | mutable_val | | T | TemplateVariable |
| variables.cpp:11:3:11:13 | mutable_val | | T | TemplateVariable |
| variables.cpp:19:3:19:10 | bar | | T | TemplateVariable |
| variables.cpp:19:8:19:8 | bar | variables.cpp:27:3:27:13 | T | |
| variables.cpp:19:8:19:8 | bar | variables.cpp:27:3:27:13 | float | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
| main.cpp:4:5:4:6 | ys | Poor global variable name 'ys'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). |
| main.cpp:9:5:9:6 | v1 | Poor global variable name 'v1'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). |
| main.cpp:10:5:10:6 | v2 | Poor global variable name 'v2'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). |
| main.cpp:12:5:12:5 | v3 | Poor global variable name 'v3'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). |
| main.cpp:14:5:14:5 | v4 | Poor global variable name 'v4'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). |
| main.cpp:16:5:16:5 | v5 | Poor global variable name 'v5'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). |
| main.cpp:12:3:12:4 | v3 | Poor global variable name 'v3'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). |
| main.cpp:14:3:14:4 | v4 | Poor global variable name 'v4'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). |
| main.cpp:16:3:16:4 | v5 | Poor global variable name 'v5'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). |
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
| code2.cpp:7:6:7:7 | v3 | Variable v3 is not used. |
| code2.cpp:11:16:11:17 | v7 | Variable v7 is not used. |
| code2.cpp:26:16:26:17 | v1 | Variable v1 is not used. |
| code2.cpp:27:16:27:17 | v2 | Variable v2 is not used. |
| code2.cpp:42:11:42:16 | myVar1 | Variable myVar1 is not used. |
| code2.cpp:64:7:64:8 | v3 | Variable v3 is not used. |
| code2.cpp:108:11:108:12 | v2 | Variable v2 is not used. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void myFunction()
void test_template_parameter()
{
constexpr int v1 = 0; // BAD: unused
constexpr int v2 = 0; // GOOD: used as a template parameter below [FALSE POSITIVE]
constexpr int v2 = 0; // GOOD: used as a template parameter below

myFunction<v2>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,34 @@ void testTempObject() {
f(&x);
if (x > 0) {} // GOOD [NO LONGER REPORTED]
}

void staticAssert() {
static const int a = 42;
static const int b = 43;
static_assert(a < b + 0, ""); // GOOD
}

constexpr int global_1 = 42;
constexpr int global_2 = global_1 < 2 * sizeof(int*) ? 43 : 2 * sizeof(int*); // GOOD

static const int global_3 = 42;
static const int global_4 = global_3 < 2 * sizeof(int*) ? 43 : 2 * sizeof(int*); // GOOD

template<unsigned int p, unsigned int n, bool = ((2u * n) < p)>
struct templateCompare : public templateCompare<p, 2u * n> // GOOD
{ };

template< unsigned int p, unsigned int n>
struct templateCompare< p, n, false>
{
static const unsigned int v = n;
};

unsigned int templateCompare_x = templateCompare<42, 42>::v;

template<int n>
struct someType {
typedef someType<((n - 4) < 0 ? 0 : n - 4)> b; // GOOD
};

someType<42>::b someType_x;
Loading