From 848dfce9e8d390e83e726d9aff5b1a5d40b0282f Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 3 Apr 2023 12:56:14 +0200 Subject: [PATCH 01/34] Expected files for qcc --- ...tractAScaledIntegerToAPointer.expected.qcc | 23 +++++++++++ ...omicVariableTwiceInExpression.expected.qcc | 6 +++ ...nsThatCanFailSpuriouslyInLoop.expected.qcc | 4 ++ .../ErrnoReadBeforeReturn.expected.qcc | 3 ++ ...erformFileOperationsOnDevices.expected.qcc | 40 +++++++++++++++++++ 5 files changed, 76 insertions(+) create mode 100644 c/cert/test/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.expected.qcc create mode 100644 c/cert/test/rules/CON40-C/AtomicVariableTwiceInExpression.expected.qcc create mode 100644 c/cert/test/rules/CON41-C/WrapFunctionsThatCanFailSpuriouslyInLoop.expected.qcc create mode 100644 c/cert/test/rules/ERR30-C/ErrnoReadBeforeReturn.expected.qcc create mode 100644 c/cert/test/rules/FIO32-C/DoNotPerformFileOperationsOnDevices.expected.qcc diff --git a/c/cert/test/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.expected.qcc b/c/cert/test/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.expected.qcc new file mode 100644 index 0000000000..17f9312a38 --- /dev/null +++ b/c/cert/test/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.expected.qcc @@ -0,0 +1,23 @@ +edges +| test.c:7:13:7:14 | p1 | test.c:9:9:9:10 | p1 | +| test.c:16:19:16:41 | __builtin_offsetof | test.c:18:26:18:31 | offset | +| test.c:16:19:16:41 | __builtin_offsetof | test.c:29:6:29:11 | offset | +| test.c:17:17:17:26 | sizeof() | test.c:23:9:23:12 | size | +| test.c:29:6:29:11 | offset | test.c:7:13:7:14 | p1 | +nodes +| test.c:7:13:7:14 | p1 | semmle.label | p1 | +| test.c:9:9:9:10 | p1 | semmle.label | p1 | +| test.c:16:19:16:41 | __builtin_offsetof | semmle.label | __builtin_offsetof | +| test.c:17:17:17:26 | sizeof() | semmle.label | sizeof() | +| test.c:18:26:18:31 | offset | semmle.label | offset | +| test.c:23:9:23:12 | size | semmle.label | size | +| test.c:25:9:25:18 | sizeof() | semmle.label | sizeof() | +| test.c:27:17:27:26 | sizeof() | semmle.label | sizeof() | +| test.c:29:6:29:11 | offset | semmle.label | offset | +subpaths +#select +| test.c:9:9:9:10 | p1 | test.c:16:19:16:41 | __builtin_offsetof | test.c:9:9:9:10 | p1 | Scaled integer used in pointer arithmetic. | +| test.c:18:26:18:31 | offset | test.c:16:19:16:41 | __builtin_offsetof | test.c:18:26:18:31 | offset | Scaled integer used in pointer arithmetic. | +| test.c:23:9:23:12 | size | test.c:17:17:17:26 | sizeof() | test.c:23:9:23:12 | size | Scaled integer used in pointer arithmetic. | +| test.c:25:9:25:18 | sizeof() | test.c:25:9:25:18 | sizeof() | test.c:25:9:25:18 | sizeof() | Scaled integer used in pointer arithmetic. | +| test.c:27:17:27:26 | sizeof() | test.c:27:17:27:26 | sizeof() | test.c:27:17:27:26 | sizeof() | Scaled integer used in pointer arithmetic. | diff --git a/c/cert/test/rules/CON40-C/AtomicVariableTwiceInExpression.expected.qcc b/c/cert/test/rules/CON40-C/AtomicVariableTwiceInExpression.expected.qcc new file mode 100644 index 0000000000..7a37b9424d --- /dev/null +++ b/c/cert/test/rules/CON40-C/AtomicVariableTwiceInExpression.expected.qcc @@ -0,0 +1,6 @@ +| test.c:7:18:7:39 | ATOMIC_VAR_INIT(VALUE) | Atomic variable possibly referred to twice in an $@. | test.c:33:3:33:10 | ... += ... | expression | +| test.c:7:18:7:39 | ATOMIC_VAR_INIT(VALUE) | Atomic variable possibly referred to twice in an $@. | test.c:34:3:34:13 | ... = ... | expression | +| test.c:11:3:11:23 | atomic_store(PTR,VAL) | Atomic variable possibly referred to twice in an $@. | test.c:11:3:11:23 | atomic_store(PTR,VAL) | expression | +| test.c:12:3:12:35 | atomic_store_explicit(PTR,VAL,MO) | Atomic variable possibly referred to twice in an $@. | test.c:12:3:12:35 | atomic_store_explicit(PTR,VAL,MO) | expression | +| test.c:25:3:25:49 | atomic_compare_exchange_weak(PTR,VAL,DES) | Atomic variable possibly referred to twice in an $@. | test.c:25:3:25:49 | atomic_compare_exchange_weak(PTR,VAL,DES) | expression | +| test.c:26:3:27:42 | atomic_compare_exchange_weak_explicit(PTR,VAL,DES,SUC,FAIL) | Atomic variable possibly referred to twice in an $@. | test.c:26:3:27:42 | atomic_compare_exchange_weak_explicit(PTR,VAL,DES,SUC,FAIL) | expression | diff --git a/c/cert/test/rules/CON41-C/WrapFunctionsThatCanFailSpuriouslyInLoop.expected.qcc b/c/cert/test/rules/CON41-C/WrapFunctionsThatCanFailSpuriouslyInLoop.expected.qcc new file mode 100644 index 0000000000..56c78a0189 --- /dev/null +++ b/c/cert/test/rules/CON41-C/WrapFunctionsThatCanFailSpuriouslyInLoop.expected.qcc @@ -0,0 +1,4 @@ +| test.c:6:8:6:46 | atomic_compare_exchange_weak(PTR,VAL,DES) | Function that can spuriously fail not wrapped in a loop. | +| test.c:10:3:10:41 | atomic_compare_exchange_weak(PTR,VAL,DES) | Function that can spuriously fail not wrapped in a loop. | +| test.c:12:8:13:47 | atomic_compare_exchange_weak_explicit(PTR,VAL,DES,SUC,FAIL) | Function that can spuriously fail not wrapped in a loop. | +| test.c:17:3:17:56 | atomic_compare_exchange_weak_explicit(PTR,VAL,DES,SUC,FAIL) | Function that can spuriously fail not wrapped in a loop. | diff --git a/c/cert/test/rules/ERR30-C/ErrnoReadBeforeReturn.expected.qcc b/c/cert/test/rules/ERR30-C/ErrnoReadBeforeReturn.expected.qcc new file mode 100644 index 0000000000..55ce78368f --- /dev/null +++ b/c/cert/test/rules/ERR30-C/ErrnoReadBeforeReturn.expected.qcc @@ -0,0 +1,3 @@ +| test.c:69:7:69:11 | * ... | Do not read `errno` before checking the return value of function $@. | test.c:68:3:68:7 | call to ftell | call to ftell | +| test.c:69:7:69:11 | call to __get_errno_ptr | Do not read `errno` before checking the return value of function $@. | test.c:68:3:68:7 | call to ftell | call to ftell | +| test.c:70:5:70:10 | call to perror | Do not read `errno` before checking the return value of function $@. | test.c:68:3:68:7 | call to ftell | call to ftell | diff --git a/c/cert/test/rules/FIO32-C/DoNotPerformFileOperationsOnDevices.expected.qcc b/c/cert/test/rules/FIO32-C/DoNotPerformFileOperationsOnDevices.expected.qcc new file mode 100644 index 0000000000..d885a5b207 --- /dev/null +++ b/c/cert/test/rules/FIO32-C/DoNotPerformFileOperationsOnDevices.expected.qcc @@ -0,0 +1,40 @@ +edges +| test.c:20:15:20:23 | array to pointer conversion | test.c:21:8:21:16 | (const char *)... | +| test.c:20:15:20:23 | array to pointer conversion | test.c:21:8:21:16 | file_name | +| test.c:20:15:20:23 | array to pointer conversion | test.c:21:8:21:16 | file_name indirection | +| test.c:20:15:20:23 | file_name | test.c:21:8:21:16 | (const char *)... | +| test.c:20:15:20:23 | file_name | test.c:21:8:21:16 | file_name | +| test.c:20:15:20:23 | file_name | test.c:21:8:21:16 | file_name indirection | +| test.c:20:15:20:23 | scanf output argument | test.c:21:8:21:16 | (const char *)... | +| test.c:20:15:20:23 | scanf output argument | test.c:21:8:21:16 | file_name | +| test.c:20:15:20:23 | scanf output argument | test.c:21:8:21:16 | file_name indirection | +| test.c:45:15:45:23 | array to pointer conversion | test.c:46:29:46:37 | (LPCTSTR)... | +| test.c:45:15:45:23 | array to pointer conversion | test.c:46:29:46:37 | file_name | +| test.c:45:15:45:23 | array to pointer conversion | test.c:46:29:46:37 | file_name indirection | +| test.c:45:15:45:23 | file_name | test.c:46:29:46:37 | (LPCTSTR)... | +| test.c:45:15:45:23 | file_name | test.c:46:29:46:37 | file_name | +| test.c:45:15:45:23 | file_name | test.c:46:29:46:37 | file_name indirection | +| test.c:45:15:45:23 | scanf output argument | test.c:46:29:46:37 | (LPCTSTR)... | +| test.c:45:15:45:23 | scanf output argument | test.c:46:29:46:37 | file_name | +| test.c:45:15:45:23 | scanf output argument | test.c:46:29:46:37 | file_name indirection | +subpaths +nodes +| test.c:20:15:20:23 | array to pointer conversion | semmle.label | array to pointer conversion | +| test.c:20:15:20:23 | file_name | semmle.label | file_name | +| test.c:20:15:20:23 | scanf output argument | semmle.label | scanf output argument | +| test.c:21:8:21:16 | (const char *)... | semmle.label | (const char *)... | +| test.c:21:8:21:16 | (const char *)... | semmle.label | (const char *)... | +| test.c:21:8:21:16 | file_name | semmle.label | file_name | +| test.c:21:8:21:16 | file_name indirection | semmle.label | file_name indirection | +| test.c:21:8:21:16 | file_name indirection | semmle.label | file_name indirection | +| test.c:45:15:45:23 | array to pointer conversion | semmle.label | array to pointer conversion | +| test.c:45:15:45:23 | file_name | semmle.label | file_name | +| test.c:45:15:45:23 | scanf output argument | semmle.label | scanf output argument | +| test.c:46:29:46:37 | (LPCTSTR)... | semmle.label | (LPCTSTR)... | +| test.c:46:29:46:37 | (LPCTSTR)... | semmle.label | (LPCTSTR)... | +| test.c:46:29:46:37 | file_name | semmle.label | file_name | +| test.c:46:29:46:37 | file_name indirection | semmle.label | file_name indirection | +| test.c:46:29:46:37 | file_name indirection | semmle.label | file_name indirection | +#select +| test.c:21:8:21:16 | file_name | test.c:20:15:20:23 | file_name | test.c:21:8:21:16 | file_name | This argument to a file access function is derived from $@ and then passed to func(file_name), which calls fopen(__filename) | test.c:20:15:20:23 | file_name | user input (scanf) | +| test.c:46:29:46:37 | file_name | test.c:45:15:45:23 | file_name | test.c:46:29:46:37 | file_name | This argument to a file access function is derived from $@ and then passed to CreateFile(lpFileName) | test.c:45:15:45:23 | file_name | user input (scanf) | From e4f899d925bb0f2266a6d17ab2c2a7d65b6590d7 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Tue, 4 Apr 2023 16:32:00 +0200 Subject: [PATCH 02/34] Compilation issue with RULE-1-2 --- c/misra/test/rules/RULE-1-2/test.c.gcc | 409 +++++++++++++++++++++++++ c/misra/test/rules/RULE-1-2/test.c.qcc | 409 +++++++++++++++++++++++++ 2 files changed, 818 insertions(+) create mode 100644 c/misra/test/rules/RULE-1-2/test.c.gcc create mode 100644 c/misra/test/rules/RULE-1-2/test.c.qcc diff --git a/c/misra/test/rules/RULE-1-2/test.c.gcc b/c/misra/test/rules/RULE-1-2/test.c.gcc new file mode 100644 index 0000000000..624d1d67d8 --- /dev/null +++ b/c/misra/test/rules/RULE-1-2/test.c.gcc @@ -0,0 +1,409 @@ +#include +#include +// Note: Clang aims to support both clang and gcc extensions. +// This test case has been designed using lists compiled from: +// - https://clang.llvm.org/docs/LanguageExtensions.html +// - https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins +#ifdef __has_builtin // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_constexpr_builtin // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_feature // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_extension // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_c_attribute // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_attribute // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_declspec_attribute // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __is_identifier // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_include // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_include_next // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_warning // NON_COMPLIANT[FALSE_NEGATIVE] +#endif + +// Reference: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros +#define A __BASE_FILE__ // NON_COMPLIANT +#define B __FILE_NAME__ // NON_COMPLIANT +#define C __COUNTER__ // NON_COMPLIANT +#define D __INCLUDE_LEVEL__ // NON_COMPLIANT +#define E__TIMESTAMP__ // NON_COMPLIANT +#define F __clang__ // NON_COMPLIANT +#define G __clang_major__ // NON_COMPLIANT +#define H __clang_minor__ // NON_COMPLIANT +#define I __clang_patchlevel__ // NON_COMPLIANT +#define J __clang_version__ // NON_COMPLIANT +#define K __clang_literal_encoding__ // NON_COMPLIANT +#define L __clang_wide_literal_encoding__ // NON_COMPLIANT + +// Requires additional compiler flags to change the architecture +// typedef __attribute__((neon_vector_type(8))) int8_t int8x8_t; +// typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t; + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes +typedef int int4 __attribute__((vector_size(4 * sizeof(int)))); // NON_COMPLIANT +typedef int v4si __attribute__((__vector_size__(16))); // NON_COMPLIANT +typedef float float4 __attribute__((ext_vector_type(4))); // NON_COMPLIANT +typedef float float2 __attribute__((ext_vector_type(2))); // NON_COMPLIANT + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs +void gf1() { + ({ // NON_COMPLIANT + int y = 1; + int z; + if (y > 0) + z = y; + else + z = -y; + z; + }); +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Local-Labels.html#Local-Labels +void gf2() { + // __label__ found; // NON_COMPLIANT[FALSE_NEGATIVE] -- local labels not + // supported by clang +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html#Labels-as-Values +void gf3() { + void *ptr; + // goto *ptr; // NON_COMPLIANT[FALSE_NEGATIVE] -- not supported in clang +} + +// Referfence: +// https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html#Nested-Functions +void gf4() { + // void gf4a(){ // NON_COMPLIANT[FALSE_NEGATIVE] -- not supported in clang + // + // } +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Nonlocal-Gotos.html#Nonlocal-Gotos +void gf5() { + __builtin_setjmp(0); // NON_COMPLIANT + __builtin_longjmp(0, 1); // NON_COMPLIANT +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Constructing-Calls.html#Constructing-Calls +void gf6() { + // not supported by clang + //__builtin_apply_args(); // NON_COMPLIANT[FALSE_NEGATIVE] + //__builtin_apply(0, 0, 0); // NON_COMPLIANT[FALSE_NEGATIVE] + //__builtin_return(0); // NON_COMPLIANT[FALSE_NEGATIVE] + //__builtin_va_arg_pack(); // NON_COMPLIANT[FALSE_NEGATIVE] + //__builtin_va_arg_pack_len(); // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals +void gf7() { + int a = 0 ?: 0; // NON_COMPLIANT +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Typeof.html#Typeof +void gf8() { // not supported by qcc + // typeof(int *); // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128 +void gf9() { + __int128 a; // NON_COMPLIANT +} +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Long-Long.html#Long-Long +void gf10() { + long long int a; // NON_COMPLIANT +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Complex.html#Complex +void gf11() { + __real__(0); // NON_COMPLIANT[FALSE_NEGATIVE] + __imag__(0); // NON_COMPLIANT[FALSE_NEGATIVE] +} + +void gf12() {} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html#Floating-Types +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html#Decimal-Float +void gf13() { + // not supported on clang + //_Decimal32 a; // NON_COMPLIANT[FALSE_NEGATIVE] + //_Decimal64 b; // NON_COMPLIANT[FALSE_NEGATIVE] + //_Decimal128 c; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Complex.html#Complex +void gf14() { + // Do not work in clang + // typedef _Complex float __attribute__((mode(TC))) _Complex128; // + // NON_COMPLIANT[FALSE_NEGATIVE] typedef _Complex float + // __attribute__((mode(XC))) _Complex80; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Hex-Floats.html#Hex-Floats +void gf15() { + float f = 0x1.fp3; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html#Zero-Length +void gf16() { + char contents[0]; // NON_COMPLIANT +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html#Named-Address-Spaces +void gf17() { + // const __flash char ** p; // NON_COMPLIANT[FALSE_NEGATIVE] -- not supported + // in clang +} + +void gf18() { + // not supported by extractor - checked by looking for flags. + + // short _Fract, _Fract; // NON_COMPLIANT[FALSE_NEGATIVE] - + // long _Fract; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +struct gf19 {}; // NON_COMPLIANT + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length +void gf20(int n) { + // struct S { int x[n]; }; // NON_COMPLIANT[FALSE_NEGATIVE] - will never be + // supported in clang +} +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html#Variadic-Macros +#define gf21(format, args...) \ + printf(format, args) // NON_COMPLIANT[FALSE_NEGATIVE] -- note + // the issue here is explicitly naming the arguments. +#define gf21a(format, ...) printf(format, __VA_ARGS__) // COMPLIANT + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Escaped-Newlines.html#Escaped-Newlines +#define gf22 \ + "a" \ + \ +"b" // NON_COMPLIANT[FALSE_NEGATIVE] - additional spaces after a backslash -- + // stripped by extractor +#define gf22a \ + "a" \ + "b" // COMPLIANT + +void gf24(int f, int g) { + float beat_freqs[2] = {f - g, f + g}; // NON_COMPLIANT +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length +void gf25t(int N, int M, double out[M][N], // NON_COMPLIANT + const double in[N][M]); // NON_COMPLIANT +void gf25() { + double x[3][2]; + double y[2][3]; + gf25t(3, 2, y, + x); // in ISO C the const qualifier is formally attached + // to the element type of the array and not the array itself +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html#Compound-Literals +struct gf26t { + int a; + char b[2]; +} gf26v; +void gf26(int x, int y) { + gf26v = ((struct gf26t){ + x + y, 'z', 0}); // NON_COMPLIANT[FALSE_NEGATIVE] - compound literal +} +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html#Case-Ranges +void gf28() { + int a; + + // switch(a){ + // case: 0 ... 5: // NON_COMPLIANT[FALSE_NEGATIVE] - Not supported in + // clang. + // ;; + // break; + // default: + // ;; + // break; + // } +} + +union gf29u { + int i; + double j; +}; + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Cast-to-Union.html#Cast-to-Union +void gf29() { + int x; + int y; + union gf29u z; + z = (union gf29u)x; // NON_COMPLIANT[FALSE_NEGATIVE] + z = (union gf29u)y; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#Function-Attributes +__attribute__((access(read_only, 1))) int +gf30(const char *); // NON_COMPLIANT -- attributes are not portable. + +extern int __attribute__((alias("var_target"))) +gf31; // NON_COMPLIANT -- attributes are not portable. + +struct __attribute__((aligned(8))) gf32 { + short f[3]; +}; // NON_COMPLIANT -- attributes are not portable. + +void gf33() { +gf33l: + __attribute__((cold, unused)); // NON_COMPLIANT + return; +} + +enum gf34 { + oldval __attribute__((deprecated)), // NON_COMPLIANT + newval +}; + +void gf35() { + int x; + // __attribute__((assume(x == 42))); // NON_COMPLIANT[FALSE_NEGATIVE] - Not + // supported in clang + + switch (x) { + case 1: + printf(""); + __attribute__((fallthrough)); // NON_COMPLIANT + case 2: + break; + } +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Dollar-Signs.html#Dollar-Signs +void gf37() { + int a$1; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Character-Escapes.html#Character-Escapes +void gf38() { + const char *c = "test\e"; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +struct gf39s { + int x; + char y; +} gf39v; + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Alignment.html#Alignment +void gf39() { + __alignof__(gf39v.x); // NON_COMPLIANT +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Incomplete-Enums.html#Incomplete-Enums +// enum gf40 {}; // NON_COMPLIANT[FALSE_NEGATIVE] - not supported in clang + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html#Function-Names +void gf41() { + printf("__FUNCTION__ = %s\n", __FUNCTION__); // NON_COMPLIANT[FALSE_NEGATIVE] + printf("__PRETTY_FUNCTION__ = %s\n", + __PRETTY_FUNCTION__); // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins +void gf42() { + __builtin_extract_return_addr(0); // NON_COMPLIANT + __builtin_frob_return_addr(0); // NON_COMPLIANT + __builtin_frame_address(0); // NON_COMPLIANT +} + +struct gf43s { + int x; + char y; +} gf43v; + +void gf43() { + __builtin_offsetof(struct gf43s, x); // NON_COMPLIANT +} + +struct gf44s { + int x; + char y; +} gf44v; + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins +void gf44() { + int i; + __sync_fetch_and_add(&i, 0); // NON_COMPLIANT + __sync_fetch_and_sub(&i, 0); // NON_COMPLIANT + __sync_fetch_and_or(&i, 0); // NON_COMPLIANT + __sync_fetch_and_and(&i, 0); // NON_COMPLIANT + __sync_fetch_and_xor(&i, 0); // NON_COMPLIANT + __sync_fetch_and_nand(&i, 0); // NON_COMPLIANT + __sync_add_and_fetch(&i, 0); // NON_COMPLIANT + __sync_sub_and_fetch(&i, 0); // NON_COMPLIANT + __sync_or_and_fetch(&i, 0); // NON_COMPLIANT + __sync_and_and_fetch(&i, 0); // NON_COMPLIANT + __sync_xor_and_fetch(&i, 0); // NON_COMPLIANT + __sync_nand_and_fetch(&i, 0); // NON_COMPLIANT + + __sync_bool_compare_and_swap(&i, 0, 0); + __sync_val_compare_and_swap(&i, 0, 0); + __sync_lock_test_and_set(&i, 0, 0); + __sync_lock_release(&i, 0); +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html#Binary-constants +void gf45() { + int i = 0b101010; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Thread-Local.html#Thread-Local +__thread int gf46; // NON_COMPLIANT[FALSE_NEGATIVE] + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html#Unnamed-Fields +void gf47() { // NON_COMPLIANT in versions < C11. + struct { + int a; + union { + int b; + float c; + }; + int d; + } f; +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins +void gf48() { + __builtin_alloca( + 0); // NON_COMPLIANT (all __builtin functions are non-compliant.) +} \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-2/test.c.qcc b/c/misra/test/rules/RULE-1-2/test.c.qcc new file mode 100644 index 0000000000..624d1d67d8 --- /dev/null +++ b/c/misra/test/rules/RULE-1-2/test.c.qcc @@ -0,0 +1,409 @@ +#include +#include +// Note: Clang aims to support both clang and gcc extensions. +// This test case has been designed using lists compiled from: +// - https://clang.llvm.org/docs/LanguageExtensions.html +// - https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins +#ifdef __has_builtin // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_constexpr_builtin // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_feature // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_extension // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_c_attribute // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_attribute // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_declspec_attribute // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __is_identifier // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_include // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_include_next // NON_COMPLIANT[FALSE_NEGATIVE] +#endif +#ifdef __has_warning // NON_COMPLIANT[FALSE_NEGATIVE] +#endif + +// Reference: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros +#define A __BASE_FILE__ // NON_COMPLIANT +#define B __FILE_NAME__ // NON_COMPLIANT +#define C __COUNTER__ // NON_COMPLIANT +#define D __INCLUDE_LEVEL__ // NON_COMPLIANT +#define E__TIMESTAMP__ // NON_COMPLIANT +#define F __clang__ // NON_COMPLIANT +#define G __clang_major__ // NON_COMPLIANT +#define H __clang_minor__ // NON_COMPLIANT +#define I __clang_patchlevel__ // NON_COMPLIANT +#define J __clang_version__ // NON_COMPLIANT +#define K __clang_literal_encoding__ // NON_COMPLIANT +#define L __clang_wide_literal_encoding__ // NON_COMPLIANT + +// Requires additional compiler flags to change the architecture +// typedef __attribute__((neon_vector_type(8))) int8_t int8x8_t; +// typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t; + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes +typedef int int4 __attribute__((vector_size(4 * sizeof(int)))); // NON_COMPLIANT +typedef int v4si __attribute__((__vector_size__(16))); // NON_COMPLIANT +typedef float float4 __attribute__((ext_vector_type(4))); // NON_COMPLIANT +typedef float float2 __attribute__((ext_vector_type(2))); // NON_COMPLIANT + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs +void gf1() { + ({ // NON_COMPLIANT + int y = 1; + int z; + if (y > 0) + z = y; + else + z = -y; + z; + }); +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Local-Labels.html#Local-Labels +void gf2() { + // __label__ found; // NON_COMPLIANT[FALSE_NEGATIVE] -- local labels not + // supported by clang +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html#Labels-as-Values +void gf3() { + void *ptr; + // goto *ptr; // NON_COMPLIANT[FALSE_NEGATIVE] -- not supported in clang +} + +// Referfence: +// https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html#Nested-Functions +void gf4() { + // void gf4a(){ // NON_COMPLIANT[FALSE_NEGATIVE] -- not supported in clang + // + // } +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Nonlocal-Gotos.html#Nonlocal-Gotos +void gf5() { + __builtin_setjmp(0); // NON_COMPLIANT + __builtin_longjmp(0, 1); // NON_COMPLIANT +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Constructing-Calls.html#Constructing-Calls +void gf6() { + // not supported by clang + //__builtin_apply_args(); // NON_COMPLIANT[FALSE_NEGATIVE] + //__builtin_apply(0, 0, 0); // NON_COMPLIANT[FALSE_NEGATIVE] + //__builtin_return(0); // NON_COMPLIANT[FALSE_NEGATIVE] + //__builtin_va_arg_pack(); // NON_COMPLIANT[FALSE_NEGATIVE] + //__builtin_va_arg_pack_len(); // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals +void gf7() { + int a = 0 ?: 0; // NON_COMPLIANT +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Typeof.html#Typeof +void gf8() { // not supported by qcc + // typeof(int *); // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128 +void gf9() { + __int128 a; // NON_COMPLIANT +} +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Long-Long.html#Long-Long +void gf10() { + long long int a; // NON_COMPLIANT +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Complex.html#Complex +void gf11() { + __real__(0); // NON_COMPLIANT[FALSE_NEGATIVE] + __imag__(0); // NON_COMPLIANT[FALSE_NEGATIVE] +} + +void gf12() {} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html#Floating-Types +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html#Decimal-Float +void gf13() { + // not supported on clang + //_Decimal32 a; // NON_COMPLIANT[FALSE_NEGATIVE] + //_Decimal64 b; // NON_COMPLIANT[FALSE_NEGATIVE] + //_Decimal128 c; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Complex.html#Complex +void gf14() { + // Do not work in clang + // typedef _Complex float __attribute__((mode(TC))) _Complex128; // + // NON_COMPLIANT[FALSE_NEGATIVE] typedef _Complex float + // __attribute__((mode(XC))) _Complex80; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Hex-Floats.html#Hex-Floats +void gf15() { + float f = 0x1.fp3; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html#Zero-Length +void gf16() { + char contents[0]; // NON_COMPLIANT +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html#Named-Address-Spaces +void gf17() { + // const __flash char ** p; // NON_COMPLIANT[FALSE_NEGATIVE] -- not supported + // in clang +} + +void gf18() { + // not supported by extractor - checked by looking for flags. + + // short _Fract, _Fract; // NON_COMPLIANT[FALSE_NEGATIVE] - + // long _Fract; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +struct gf19 {}; // NON_COMPLIANT + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length +void gf20(int n) { + // struct S { int x[n]; }; // NON_COMPLIANT[FALSE_NEGATIVE] - will never be + // supported in clang +} +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html#Variadic-Macros +#define gf21(format, args...) \ + printf(format, args) // NON_COMPLIANT[FALSE_NEGATIVE] -- note + // the issue here is explicitly naming the arguments. +#define gf21a(format, ...) printf(format, __VA_ARGS__) // COMPLIANT + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Escaped-Newlines.html#Escaped-Newlines +#define gf22 \ + "a" \ + \ +"b" // NON_COMPLIANT[FALSE_NEGATIVE] - additional spaces after a backslash -- + // stripped by extractor +#define gf22a \ + "a" \ + "b" // COMPLIANT + +void gf24(int f, int g) { + float beat_freqs[2] = {f - g, f + g}; // NON_COMPLIANT +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length +void gf25t(int N, int M, double out[M][N], // NON_COMPLIANT + const double in[N][M]); // NON_COMPLIANT +void gf25() { + double x[3][2]; + double y[2][3]; + gf25t(3, 2, y, + x); // in ISO C the const qualifier is formally attached + // to the element type of the array and not the array itself +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html#Compound-Literals +struct gf26t { + int a; + char b[2]; +} gf26v; +void gf26(int x, int y) { + gf26v = ((struct gf26t){ + x + y, 'z', 0}); // NON_COMPLIANT[FALSE_NEGATIVE] - compound literal +} +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html#Case-Ranges +void gf28() { + int a; + + // switch(a){ + // case: 0 ... 5: // NON_COMPLIANT[FALSE_NEGATIVE] - Not supported in + // clang. + // ;; + // break; + // default: + // ;; + // break; + // } +} + +union gf29u { + int i; + double j; +}; + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Cast-to-Union.html#Cast-to-Union +void gf29() { + int x; + int y; + union gf29u z; + z = (union gf29u)x; // NON_COMPLIANT[FALSE_NEGATIVE] + z = (union gf29u)y; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#Function-Attributes +__attribute__((access(read_only, 1))) int +gf30(const char *); // NON_COMPLIANT -- attributes are not portable. + +extern int __attribute__((alias("var_target"))) +gf31; // NON_COMPLIANT -- attributes are not portable. + +struct __attribute__((aligned(8))) gf32 { + short f[3]; +}; // NON_COMPLIANT -- attributes are not portable. + +void gf33() { +gf33l: + __attribute__((cold, unused)); // NON_COMPLIANT + return; +} + +enum gf34 { + oldval __attribute__((deprecated)), // NON_COMPLIANT + newval +}; + +void gf35() { + int x; + // __attribute__((assume(x == 42))); // NON_COMPLIANT[FALSE_NEGATIVE] - Not + // supported in clang + + switch (x) { + case 1: + printf(""); + __attribute__((fallthrough)); // NON_COMPLIANT + case 2: + break; + } +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Dollar-Signs.html#Dollar-Signs +void gf37() { + int a$1; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Character-Escapes.html#Character-Escapes +void gf38() { + const char *c = "test\e"; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +struct gf39s { + int x; + char y; +} gf39v; + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Alignment.html#Alignment +void gf39() { + __alignof__(gf39v.x); // NON_COMPLIANT +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Incomplete-Enums.html#Incomplete-Enums +// enum gf40 {}; // NON_COMPLIANT[FALSE_NEGATIVE] - not supported in clang + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html#Function-Names +void gf41() { + printf("__FUNCTION__ = %s\n", __FUNCTION__); // NON_COMPLIANT[FALSE_NEGATIVE] + printf("__PRETTY_FUNCTION__ = %s\n", + __PRETTY_FUNCTION__); // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins +void gf42() { + __builtin_extract_return_addr(0); // NON_COMPLIANT + __builtin_frob_return_addr(0); // NON_COMPLIANT + __builtin_frame_address(0); // NON_COMPLIANT +} + +struct gf43s { + int x; + char y; +} gf43v; + +void gf43() { + __builtin_offsetof(struct gf43s, x); // NON_COMPLIANT +} + +struct gf44s { + int x; + char y; +} gf44v; + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins +void gf44() { + int i; + __sync_fetch_and_add(&i, 0); // NON_COMPLIANT + __sync_fetch_and_sub(&i, 0); // NON_COMPLIANT + __sync_fetch_and_or(&i, 0); // NON_COMPLIANT + __sync_fetch_and_and(&i, 0); // NON_COMPLIANT + __sync_fetch_and_xor(&i, 0); // NON_COMPLIANT + __sync_fetch_and_nand(&i, 0); // NON_COMPLIANT + __sync_add_and_fetch(&i, 0); // NON_COMPLIANT + __sync_sub_and_fetch(&i, 0); // NON_COMPLIANT + __sync_or_and_fetch(&i, 0); // NON_COMPLIANT + __sync_and_and_fetch(&i, 0); // NON_COMPLIANT + __sync_xor_and_fetch(&i, 0); // NON_COMPLIANT + __sync_nand_and_fetch(&i, 0); // NON_COMPLIANT + + __sync_bool_compare_and_swap(&i, 0, 0); + __sync_val_compare_and_swap(&i, 0, 0); + __sync_lock_test_and_set(&i, 0, 0); + __sync_lock_release(&i, 0); +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html#Binary-constants +void gf45() { + int i = 0b101010; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Thread-Local.html#Thread-Local +__thread int gf46; // NON_COMPLIANT[FALSE_NEGATIVE] + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html#Unnamed-Fields +void gf47() { // NON_COMPLIANT in versions < C11. + struct { + int a; + union { + int b; + float c; + }; + int d; + } f; +} + +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins +void gf48() { + __builtin_alloca( + 0); // NON_COMPLIANT (all __builtin functions are non-compliant.) +} \ No newline at end of file From 40f0b39f0ef549d858680f62345a2a7e02f83088 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Tue, 11 Apr 2023 20:47:31 +0200 Subject: [PATCH 03/34] EXP39-C add `.expected.qcc` file RULE-21-4 `setjmp` and `longjmp` can be macros or functions --- ...eViaPointerOfIncompatibleType.expected.qcc | 62 +++++++++++++++++++ .../StandardHeaderFileUsedSetjmph.ql | 61 +++++++++--------- ...StandardHeaderFileUsedSetjmph.expected.qcc | 2 + 3 files changed, 93 insertions(+), 32 deletions(-) create mode 100644 c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected.qcc create mode 100644 c/misra/test/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.expected.qcc diff --git a/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected.qcc b/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected.qcc new file mode 100644 index 0000000000..b327629aae --- /dev/null +++ b/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected.qcc @@ -0,0 +1,62 @@ +edges +| test.c:49:8:49:9 | s3 | test.c:50:8:50:9 | s1 | +| test.c:60:16:60:18 | E1A | test.c:61:16:61:17 | e1 | +| test.c:60:16:60:18 | E1A | test.c:65:10:65:12 | & ... | +| test.c:68:22:68:22 | v | test.c:68:41:68:41 | v | +| test.c:72:13:72:15 | & ... | test.c:68:22:68:22 | v | +| test.c:74:13:74:15 | & ... | test.c:68:22:68:22 | v | +| test.c:97:32:97:37 | call to malloc | test.c:98:40:98:41 | s2 | +| test.c:97:32:97:37 | call to malloc | test.c:98:40:98:41 | s2 | +| test.c:98:32:98:38 | call to realloc | test.c:99:3:99:4 | s3 | +| test.c:98:32:98:38 | call to realloc | test.c:100:10:100:11 | s3 | +| test.c:98:40:98:41 | s2 | test.c:98:32:98:38 | call to realloc | +nodes +| file:///opt/qcc/qnx-sdp/target/qnx7/usr/include/stdlib.h:98:42:98:47 | __func | semmle.label | __func | +| file:///opt/qcc/qnx-sdp/target/qnx7/usr/include/stdlib.h:98:50:98:53 | 0 | semmle.label | 0 | +| test.c:6:19:6:20 | & ... | semmle.label | & ... | +| test.c:11:10:11:11 | & ... | semmle.label | & ... | +| test.c:13:17:13:19 | & ... | semmle.label | & ... | +| test.c:15:17:15:19 | & ... | semmle.label | & ... | +| test.c:19:18:19:20 | & ... | semmle.label | & ... | +| test.c:20:20:20:22 | & ... | semmle.label | & ... | +| test.c:22:11:22:13 | & ... | semmle.label | & ... | +| test.c:27:17:27:19 | & ... | semmle.label | & ... | +| test.c:28:10:28:12 | & ... | semmle.label | & ... | +| test.c:29:13:29:15 | & ... | semmle.label | & ... | +| test.c:30:19:30:21 | & ... | semmle.label | & ... | +| test.c:31:16:31:18 | & ... | semmle.label | & ... | +| test.c:47:8:47:9 | s2 | semmle.label | s2 | +| test.c:49:8:49:9 | s3 | semmle.label | s3 | +| test.c:49:8:49:9 | s3 | semmle.label | s3 | +| test.c:50:8:50:9 | s1 | semmle.label | s1 | +| test.c:60:16:60:18 | E1A | semmle.label | E1A | +| test.c:60:16:60:18 | E1A | semmle.label | E1A | +| test.c:61:16:61:17 | e1 | semmle.label | e1 | +| test.c:65:10:65:12 | & ... | semmle.label | & ... | +| test.c:68:22:68:22 | v | semmle.label | v | +| test.c:68:41:68:41 | v | semmle.label | v | +| test.c:72:13:72:15 | & ... | semmle.label | & ... | +| test.c:72:13:72:15 | & ... | semmle.label | & ... | +| test.c:74:13:74:15 | & ... | semmle.label | & ... | +| test.c:74:13:74:15 | & ... | semmle.label | & ... | +| test.c:97:32:97:37 | call to malloc | semmle.label | call to malloc | +| test.c:97:32:97:37 | call to malloc | semmle.label | call to malloc | +| test.c:98:32:98:38 | call to realloc | semmle.label | call to realloc | +| test.c:98:32:98:38 | call to realloc | semmle.label | call to realloc | +| test.c:98:32:98:38 | call to realloc | semmle.label | call to realloc | +| test.c:98:40:98:41 | s2 | semmle.label | s2 | +| test.c:98:40:98:41 | s2 | semmle.label | s2 | +| test.c:99:3:99:4 | s3 | semmle.label | s3 | +| test.c:100:10:100:11 | s3 | semmle.label | s3 | +subpaths +#select +| test.c:6:19:6:20 | & ... | test.c:6:19:6:20 | & ... | test.c:6:19:6:20 | & ... | Cast from float to int results in an incompatible pointer base type. | +| test.c:11:10:11:11 | & ... | test.c:11:10:11:11 | & ... | test.c:11:10:11:11 | & ... | Cast from short[2] to int results in an incompatible pointer base type. | +| test.c:13:17:13:19 | & ... | test.c:13:17:13:19 | & ... | test.c:13:17:13:19 | & ... | Cast from short[2] to short[4] results in an incompatible pointer base type. | +| test.c:19:18:19:20 | & ... | test.c:19:18:19:20 | & ... | test.c:19:18:19:20 | & ... | Cast from char to signed char results in an incompatible pointer base type. | +| test.c:30:19:30:21 | & ... | test.c:30:19:30:21 | & ... | test.c:30:19:30:21 | & ... | Cast from int to unsigned int results in an incompatible pointer base type. | +| test.c:47:8:47:9 | s2 | test.c:47:8:47:9 | s2 | test.c:47:8:47:9 | s2 | Cast from struct to struct results in an incompatible pointer base type. | +| test.c:49:8:49:9 | s3 | test.c:49:8:49:9 | s3 | test.c:49:8:49:9 | s3 | Cast from S1 to struct results in an incompatible pointer base type. | +| test.c:50:8:50:9 | s1 | test.c:50:8:50:9 | s1 | test.c:50:8:50:9 | s1 | Cast from struct to S1 results in an incompatible pointer base type. | +| test.c:68:41:68:41 | v | test.c:72:13:72:15 | & ... | test.c:68:41:68:41 | v | Cast from float to int results in an incompatible pointer base type. | +| test.c:99:3:99:4 | s3 | test.c:98:40:98:41 | s2 | test.c:99:3:99:4 | s3 | Cast from S2 to S3 results in an incompatible pointer base type. | diff --git a/c/misra/src/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.ql b/c/misra/src/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.ql index 01b0ed44b1..a48c8ad9fe 100644 --- a/c/misra/src/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.ql +++ b/c/misra/src/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.ql @@ -10,35 +10,32 @@ * external/misra/obligation/required */ -import cpp -import codingstandards.c.misra - -class SetJmp extends Macro { - SetJmp() { - this.hasName("setjmp") and - this.getFile().getAbsolutePath().matches("%setjmp.h") - } -} - -class LongJmp extends Function { - LongJmp() { - this.hasName("longjmp") and - this.getFile().getAbsolutePath().matches("%setjmp.h") - } -} - -from Locatable use, string name -where - not isExcluded(use, BannedPackage::standardHeaderFileUsedSetjmphQuery()) and - ( - exists(SetJmp setjmp | - use = setjmp.getAnInvocation() and - name = "setjmp" - ) - or - exists(LongJmp longjmp | - use = longjmp.getACallToThisFunction() and - name = "longjmp" - ) - ) -select use, "Use of " + name + "." + import cpp + import codingstandards.c.misra + + class SetJmp extends Locatable { + string name; + + SetJmp() { + this.getFile().getAbsolutePath().matches("%setjmp.h") and + name = [this.(Macro).getName(), this.(Function).getName()] and + name = ["setjmp", "longjmp"] + } + + Locatable getAnInvocation() { + result = this.(Macro).getAnInvocation() or + result = this.(Function).getACallToThisFunction() + } + + string getName() { result = name } + } + + from Locatable use, string name + where + not isExcluded(use, BannedPackage::standardHeaderFileUsedSetjmphQuery()) and + exists(SetJmp jmp | + use = jmp.getAnInvocation() and + name = jmp.getName() + ) + select use, "Use of " + name + "." + \ No newline at end of file diff --git a/c/misra/test/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.expected.qcc b/c/misra/test/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.expected.qcc new file mode 100644 index 0000000000..8e01c974ee --- /dev/null +++ b/c/misra/test/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.expected.qcc @@ -0,0 +1,2 @@ +| test.c:7:7:7:17 | setjmp(__env) | Use of setjmp. | +| test.c:8:3:8:9 | call to longjmp | Use of longjmp. | From d78c6fbb1711cadc80b72cb16a66c7dbd427c5e0 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 12 Apr 2023 00:50:41 +0200 Subject: [PATCH 04/34] RULE-21-4: `longjmp` can be a macro or a function --- .../StandardHeaderFileUsedSetjmph.ql | 70 +++++++++++-------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/c/misra/src/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.ql b/c/misra/src/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.ql index a48c8ad9fe..6de73499c0 100644 --- a/c/misra/src/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.ql +++ b/c/misra/src/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.ql @@ -10,32 +10,44 @@ * external/misra/obligation/required */ - import cpp - import codingstandards.c.misra - - class SetJmp extends Locatable { - string name; - - SetJmp() { - this.getFile().getAbsolutePath().matches("%setjmp.h") and - name = [this.(Macro).getName(), this.(Function).getName()] and - name = ["setjmp", "longjmp"] - } - - Locatable getAnInvocation() { - result = this.(Macro).getAnInvocation() or - result = this.(Function).getACallToThisFunction() - } - - string getName() { result = name } - } - - from Locatable use, string name - where - not isExcluded(use, BannedPackage::standardHeaderFileUsedSetjmphQuery()) and - exists(SetJmp jmp | - use = jmp.getAnInvocation() and - name = jmp.getName() - ) - select use, "Use of " + name + "." - \ No newline at end of file +import cpp +import codingstandards.c.misra + +abstract class Jmp extends Locatable { + string name; + + Jmp() { + this.getFile().getAbsolutePath().matches("%setjmp.h") and + name = [this.(Macro).getName(), this.(Function).getName()] + } + + Locatable getAnInvocation() { + result = this.(Macro).getAnInvocation() or + result = this.(Function).getACallToThisFunction() + } + + string getName() { result = name } +} + +class SetJmp extends Jmp { + SetJmp() { + name = "setjmp" and + this.(Macro).getName() = name + } +} + +class LongJmp extends Jmp { + LongJmp() { + name = "longjmp" and + [this.(Macro).getName(), this.(Function).getName()] = name + } +} + +from Locatable use, string name +where + not isExcluded(use, BannedPackage::standardHeaderFileUsedSetjmphQuery()) and + exists(Jmp jmp | + use = jmp.getAnInvocation() and + name = jmp.getName() + ) +select use, "Use of " + name + "." From b461260b808fe67b7efdeb6f057ac642d955e749 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 12 Apr 2023 01:56:50 +0200 Subject: [PATCH 05/34] RULE-21-4: fix `qcc` expected file --- .../rules/RULE-21-4/StandardHeaderFileUsedSetjmph.expected.qcc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/misra/test/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.expected.qcc b/c/misra/test/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.expected.qcc index 8e01c974ee..c72d7d4e20 100644 --- a/c/misra/test/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.expected.qcc +++ b/c/misra/test/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.expected.qcc @@ -1,2 +1,2 @@ | test.c:7:7:7:17 | setjmp(__env) | Use of setjmp. | -| test.c:8:3:8:9 | call to longjmp | Use of longjmp. | +| test.c:8:3:8:17 | longjmp(__env,__val) | Use of longjmp. | From 46c3332dd68d19ed9efb1b225ebd80d4a5ebd687 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 12 Apr 2023 15:47:18 +0200 Subject: [PATCH 06/34] ENV32-C: exit functions can be macros --- .../ENV32-C/ExitHandlersMustReturnNormally.ql | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/c/cert/src/rules/ENV32-C/ExitHandlersMustReturnNormally.ql b/c/cert/src/rules/ENV32-C/ExitHandlersMustReturnNormally.ql index 27b6ca2b8e..1b360ca0d8 100644 --- a/c/cert/src/rules/ENV32-C/ExitHandlersMustReturnNormally.ql +++ b/c/cert/src/rules/ENV32-C/ExitHandlersMustReturnNormally.ql @@ -14,14 +14,26 @@ import cpp import codingstandards.c.cert -class ExitFunction extends Function { - ExitFunction() { this.hasGlobalName(["_Exit", "exit", "quick_exit", "longjmp"]) } +/** + * Exit function or macro. + */ +class Exit extends Locatable { + Exit() { + ["_Exit", "exit", "quick_exit", "longjmp"] = [this.(Function).getName(), this.(Macro).getName()] + } } -class ExitFunctionCall extends FunctionCall { - ExitFunctionCall() { this.getTarget() instanceof ExitFunction } +class ExitExpr extends Expr { + ExitExpr() { + this.(FunctionCall).getTarget() instanceof Exit + or + any(MacroInvocation m | this = m.getExpr()).getMacro() instanceof Exit + } } +/** + * Functions that are registered as exit handlers. + */ class RegisteredAtexit extends FunctionAccess { RegisteredAtexit() { exists(FunctionCall ae | @@ -32,8 +44,8 @@ class RegisteredAtexit extends FunctionAccess { } /** - * Nodes of type Function, FunctionCall or FunctionAccess that \ - * are reachable from a redistered atexit handler and + * Nodes of type Function, FunctionCall, FunctionAccess or ExitExpr + * that are reachable from a registered atexit handler and * can reach an exit function. */ class InterestingNode extends ControlFlowNode { @@ -41,15 +53,17 @@ class InterestingNode extends ControlFlowNode { exists(Function f | ( this = f and - // exit functions are not part of edges - not this = any(ExitFunction ec) + // exit is not part of edges + not this instanceof Exit or this.(FunctionCall).getTarget() = f or this.(FunctionAccess).getTarget() = f + or + this.(ExitExpr).getEnclosingFunction() = f ) and - // reaches an exit function - f.calls*(any(ExitFunction e)) and + // reaches an `ExitExpr` + f.calls*(any(ExitExpr ee).getEnclosingFunction()) and // is reachable from a registered atexit function exists(RegisteredAtexit re | re.getTarget().calls*(f)) ) @@ -62,14 +76,12 @@ class InterestingNode extends ControlFlowNode { * `Function` and `FunctionCall` in their body. */ query predicate edges(InterestingNode a, InterestingNode b) { - a.(FunctionAccess).getTarget() = b - or - a.(FunctionCall).getTarget() = b - or + a.(FunctionAccess).getTarget() = b or + a.(FunctionCall).getTarget() = b or a.(Function).calls(_, b) } -from RegisteredAtexit hr, Function f, ExitFunctionCall e +from RegisteredAtexit hr, Function f, ExitExpr e where edges(hr, f) and edges+(f, e) select f, hr, e, "The function is $@ and $@. It must instead terminate by returning.", hr, "registered as `exit handler`", e, "calls an `exit function`" From c5e6c0044a5a598e08913d67e0151badbf4a7825 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 12 Apr 2023 17:01:35 +0200 Subject: [PATCH 07/34] ENV32-C: expectd.qcc file --- .../ExitHandlersMustReturnNormally.expected.qcc | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 c/cert/test/rules/ENV32-C/ExitHandlersMustReturnNormally.expected.qcc diff --git a/c/cert/test/rules/ENV32-C/ExitHandlersMustReturnNormally.expected.qcc b/c/cert/test/rules/ENV32-C/ExitHandlersMustReturnNormally.expected.qcc new file mode 100644 index 0000000000..227c023432 --- /dev/null +++ b/c/cert/test/rules/ENV32-C/ExitHandlersMustReturnNormally.expected.qcc @@ -0,0 +1,13 @@ +edges +| test.c:8:6:8:13 | exit1bad | test.c:11:5:11:8 | call to exit | +| test.c:20:14:20:21 | exit1bad | test.c:8:6:8:13 | exit1bad | +| test.c:41:6:41:10 | exit2 | test.c:42:3:42:17 | call to siglongjmp | +| test.c:46:21:46:25 | exit2 | test.c:41:6:41:10 | exit2 | +| test.c:62:6:62:17 | exit3_helper | test.c:62:27:62:41 | call to siglongjmp | +| test.c:64:6:64:10 | exit3 | test.c:65:3:65:14 | call to exit3_helper | +| test.c:65:3:65:14 | call to exit3_helper | test.c:62:6:62:17 | exit3_helper | +| test.c:69:14:69:18 | exit3 | test.c:64:6:64:10 | exit3 | +#select +| test.c:8:6:8:13 | exit1bad | test.c:20:14:20:21 | exit1bad | test.c:11:5:11:8 | call to exit | The function is $@ and $@. It must instead terminate by returning. | test.c:20:14:20:21 | exit1bad | registered as `exit handler` | test.c:11:5:11:8 | call to exit | calls an `exit function` | +| test.c:41:6:41:10 | exit2 | test.c:46:21:46:25 | exit2 | test.c:42:3:42:17 | call to siglongjmp | The function is $@ and $@. It must instead terminate by returning. | test.c:46:21:46:25 | exit2 | registered as `exit handler` | test.c:42:3:42:17 | call to siglongjmp | calls an `exit function` | +| test.c:64:6:64:10 | exit3 | test.c:69:14:69:18 | exit3 | test.c:62:27:62:41 | call to siglongjmp | The function is $@ and $@. It must instead terminate by returning. | test.c:69:14:69:18 | exit3 | registered as `exit handler` | test.c:62:27:62:41 | call to siglongjmp | calls an `exit function` | From 01661b93ab6b7e48b5d66cc92d5a0cff37e6759f Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 12 Apr 2023 19:42:31 +0200 Subject: [PATCH 08/34] FIO34-C: `qcc` support library can access `stdin` or `_Stdin` by reference --- .../codingstandards/cpp/ReadErrorsAndEOF.qll | 17 +++++----- .../cpp/standardlibrary/FileAccess.qll | 32 +++++++++++-------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/ReadErrorsAndEOF.qll b/cpp/common/src/codingstandards/cpp/ReadErrorsAndEOF.qll index 2cf701c7f6..c3c433d20d 100644 --- a/cpp/common/src/codingstandards/cpp/ReadErrorsAndEOF.qll +++ b/cpp/common/src/codingstandards/cpp/ReadErrorsAndEOF.qll @@ -5,7 +5,11 @@ import codingstandards.cpp.standardlibrary.FileAccess /** * any call to function `feof()` or `ferror()` */ -abstract class FeofFerrorCall extends FunctionCall { } +abstract class FeofFerrorCall extends FileAccess { + override VariableAccess getFileExpr() { + result = [this.getArgument(0), this.getArgument(0).(AddressOfExpr).getAnOperand()] + } +} class FeofCall extends FeofFerrorCall { FeofCall() { this.getTarget().hasGlobalName("feof") } @@ -15,11 +19,6 @@ class FerrorCall extends FeofFerrorCall { FerrorCall() { this.getTarget().hasGlobalName("ferror") } } -pragma[inline] -predicate accessSameTarget(VariableAccess va1, VariableAccess va2) { - va1.getTarget() = va2.getTarget() -} - predicate isShortCircuitedEdge(ControlFlowNode fst, ControlFlowNode snd) { fst = any(LogicalAndExpr andOp).getLeftOperand() and snd = fst.getAFalseSuccessor() or @@ -36,7 +35,7 @@ ControlFlowNode feofUnchecked(InBandErrorReadFunctionCall read) { not isShortCircuitedEdge(mid, result) and result = mid.getASuccessor() and //Stop recursion on call to feof/ferror on the correct file - not accessSameTarget(result.(FeofCall).getArgument(0), read.getFileExpr()) + not sameFileSource(result.(FeofCall), read) ) } @@ -50,7 +49,7 @@ ControlFlowNode ferrorUnchecked(InBandErrorReadFunctionCall read) { not isShortCircuitedEdge(mid, result) and result = mid.getASuccessor() and //Stop recursion on call to ferror on the correct file - not accessSameTarget(result.(FerrorCall).getArgument(0), read.getFileExpr()) + not sameFileSource(result.(FerrorCall), read) ) } @@ -112,6 +111,6 @@ predicate missingEOFWEOFChecks(InBandErrorReadFunctionCall read) { // another char is read before the comparison to EOF exists(FileReadFunctionCall fc | macroUnchecked(read) = fc and - accessSameTarget(read.getFileExpr(), fc.getFileExpr()) + sameFileSource(read, fc) ) } diff --git a/cpp/common/src/codingstandards/cpp/standardlibrary/FileAccess.qll b/cpp/common/src/codingstandards/cpp/standardlibrary/FileAccess.qll index bd5522e3eb..0ffd7f3ec9 100644 --- a/cpp/common/src/codingstandards/cpp/standardlibrary/FileAccess.qll +++ b/cpp/common/src/codingstandards/cpp/standardlibrary/FileAccess.qll @@ -98,7 +98,7 @@ class FOpenCall extends FunctionCall { } abstract class FileAccess extends FunctionCall { - abstract Expr getFileExpr(); + abstract VariableAccess getFileExpr(); } pragma[inline] @@ -114,17 +114,17 @@ class ImplicitFileAccess extends FileAccess { string fileName; ImplicitFileAccess() { - fileName = "stdin" and + fileName = ["stdin", "_Stdin"] and this.getTarget().hasGlobalName(["getchar", "getwchar", "scanf", "scanf_s"]) or - fileName = "stdout" and + fileName = ["stdout", "_Stdout"] and this.getTarget().hasGlobalName(["printf", "printf_s", "puts", "putchar", "putwchar"]) or - fileName = "stderr" and this.getTarget().hasGlobalName("perror") + fileName = ["stderr", "_Stderr"] and this.getTarget().hasGlobalName("perror") } /** The expression corresponding to the accessed file */ - override Expr getFileExpr() { + override VariableAccess getFileExpr() { fileName = result.(VariableAccess).getTarget().(GlobalVariable).toString() or fileName = result.findRootCause().(Macro).getName() } @@ -141,10 +141,10 @@ class InBandErrorReadFunctionCall extends FileAccess { } /** The expression corresponding to the accessed file */ - override Expr getFileExpr() { + override VariableAccess getFileExpr() { if this instanceof ImplicitFileAccess then result = this.(ImplicitFileAccess).getFileExpr() - else result = this.getArgument(0) + else result = [this.getArgument(0), this.getArgument(0).(AddressOfExpr).getAnOperand()] } } @@ -167,10 +167,11 @@ class FileReadFunctionCall extends FileAccess { } /** The expression corresponding to the accessed file */ - override Expr getFileExpr() { + override VariableAccess getFileExpr() { if this instanceof ImplicitFileAccess then result = this.(ImplicitFileAccess).getFileExpr() - else result = this.getArgument(filePos) + else + result = [this.getArgument(filePos), this.getArgument(filePos).(AddressOfExpr).getAnOperand()] } } @@ -195,10 +196,11 @@ class FileWriteFunctionCall extends FileAccess { } /** The expression corresponding to the accessed file */ - override Expr getFileExpr() { + override VariableAccess getFileExpr() { if this instanceof ImplicitFileAccess then result = this.(ImplicitFileAccess).getFileExpr() - else result = this.getArgument(filePos) + else + result = [this.getArgument(filePos), this.getArgument(filePos).(AddressOfExpr).getAnOperand()] } } @@ -209,7 +211,9 @@ class FileCloseFunctionCall extends FileAccess { FileCloseFunctionCall() { this.getTarget().hasGlobalName("fclose") } /** The expression corresponding to the accessed file */ - override Expr getFileExpr() { result = this.getArgument(0) } + override VariableAccess getFileExpr() { + result = [this.getArgument(0), this.getArgument(0).(AddressOfExpr).getAnOperand()] + } } /** @@ -221,5 +225,7 @@ class FilePositioningFunctionCall extends FileAccess { } /** The expression corresponding to the accessed file */ - override Expr getFileExpr() { result = this.getArgument(0) } + override VariableAccess getFileExpr() { + result = [this.getArgument(0), this.getArgument(0).(AddressOfExpr).getAnOperand()] + } } From 13a5c61c1dcfd184923bac7e2afefe53870d0527 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 12 Apr 2023 19:55:48 +0200 Subject: [PATCH 09/34] ERR33-C: library can access stdin by reference --- .../src/rules/ERR33-C/DetectAndHandleStandardLibraryErrors.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/cert/src/rules/ERR33-C/DetectAndHandleStandardLibraryErrors.ql b/c/cert/src/rules/ERR33-C/DetectAndHandleStandardLibraryErrors.ql index d7ca143519..6641fe8a52 100644 --- a/c/cert/src/rules/ERR33-C/DetectAndHandleStandardLibraryErrors.ql +++ b/c/cert/src/rules/ERR33-C/DetectAndHandleStandardLibraryErrors.ql @@ -441,7 +441,7 @@ ControlFlowNode ferrorNotchecked(FileWriteFunctionCall write) { not isShortCircuitedEdge(mid, result) and result = mid.getASuccessor() and //Stop recursion on call to ferror on the correct file - not accessSameTarget(result.(FerrorCall).getArgument(0), write.getFileExpr()) + not sameFileSource(result.(FerrorCall), write) ) } From 39982762a0e0dce1a3d51b524557c296b751280c Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 12 Apr 2023 20:09:50 +0200 Subject: [PATCH 10/34] FIO47-C: Add `.expected.qcc` file --- .../WrongTypeFormatArguments.expected.qcc | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 c/cert/test/rules/FIO47-C/WrongTypeFormatArguments.expected.qcc diff --git a/c/cert/test/rules/FIO47-C/WrongTypeFormatArguments.expected.qcc b/c/cert/test/rules/FIO47-C/WrongTypeFormatArguments.expected.qcc new file mode 100644 index 0000000000..f6a8f57da8 --- /dev/null +++ b/c/cert/test/rules/FIO47-C/WrongTypeFormatArguments.expected.qcc @@ -0,0 +1,90 @@ +| test.c:376:17:376:30 | v_intmax_t_ptr | This argument should be of type 'int *' but is of type 'long *' | +| test.c:378:17:378:28 | v_size_t_ptr | This argument should be of type 'int *' but is of type 'unsigned long *' | +| test.c:380:17:380:31 | v_ptrdiff_t_ptr | This argument should be of type 'int *' but is of type 'long *' | +| test.c:417:17:417:26 | v_char_ptr | This argument should be of type 'int' but is of type 'char *' | +| test.c:421:18:421:27 | v_char_ptr | This argument should be of type 'int' but is of type 'char *' | +| test.c:425:16:425:25 | v_char_ptr | This argument should be of type 'int' but is of type 'char *' | +| test.c:426:17:426:26 | v_char_ptr | This argument should be of type 'int' but is of type 'char *' | +| test.c:427:18:427:27 | v_char_ptr | This argument should be of type 'int' but is of type 'char *' | +| test.c:428:17:428:26 | v_char_ptr | This argument should be of type 'long' but is of type 'char *' | +| test.c:429:18:429:27 | v_char_ptr | This argument should be of type 'long long' but is of type 'char *' | +| test.c:430:17:430:26 | v_char_ptr | This argument should be of type 'intmax_t' but is of type 'char *' | +| test.c:432:17:432:26 | v_char_ptr | This argument should be of type 'ptrdiff_t' but is of type 'char *' | +| test.c:434:16:434:25 | v_char_ptr | This argument should be of type 'int' but is of type 'char *' | +| test.c:435:17:435:26 | v_char_ptr | This argument should be of type 'int' but is of type 'char *' | +| test.c:436:18:436:27 | v_char_ptr | This argument should be of type 'int' but is of type 'char *' | +| test.c:437:17:437:26 | v_char_ptr | This argument should be of type 'long' but is of type 'char *' | +| test.c:438:18:438:27 | v_char_ptr | This argument should be of type 'long long' but is of type 'char *' | +| test.c:439:17:439:26 | v_char_ptr | This argument should be of type 'intmax_t' but is of type 'char *' | +| test.c:441:17:441:26 | v_char_ptr | This argument should be of type 'ptrdiff_t' but is of type 'char *' | +| test.c:443:16:443:25 | v_char_ptr | This argument should be of type 'unsigned int' but is of type 'char *' | +| test.c:444:17:444:26 | v_char_ptr | This argument should be of type 'unsigned int' but is of type 'char *' | +| test.c:445:18:445:27 | v_char_ptr | This argument should be of type 'unsigned int' but is of type 'char *' | +| test.c:446:17:446:26 | v_char_ptr | This argument should be of type 'unsigned long' but is of type 'char *' | +| test.c:447:18:447:27 | v_char_ptr | This argument should be of type 'unsigned long long' but is of type 'char *' | +| test.c:450:17:450:26 | v_char_ptr | This argument should be of type 'size_t' but is of type 'char *' | +| test.c:454:16:454:25 | v_char_ptr | This argument should be of type 'unsigned int' but is of type 'char *' | +| test.c:455:17:455:26 | v_char_ptr | This argument should be of type 'unsigned int' but is of type 'char *' | +| test.c:456:18:456:27 | v_char_ptr | This argument should be of type 'unsigned int' but is of type 'char *' | +| test.c:457:17:457:26 | v_char_ptr | This argument should be of type 'unsigned long' but is of type 'char *' | +| test.c:458:18:458:27 | v_char_ptr | This argument should be of type 'unsigned long long' but is of type 'char *' | +| test.c:461:17:461:26 | v_char_ptr | This argument should be of type 'size_t' but is of type 'char *' | +| test.c:465:16:465:25 | v_char_ptr | This argument should be of type 'unsigned int' but is of type 'char *' | +| test.c:466:17:466:26 | v_char_ptr | This argument should be of type 'unsigned int' but is of type 'char *' | +| test.c:467:18:467:27 | v_char_ptr | This argument should be of type 'unsigned int' but is of type 'char *' | +| test.c:468:17:468:26 | v_char_ptr | This argument should be of type 'unsigned long' but is of type 'char *' | +| test.c:469:18:469:27 | v_char_ptr | This argument should be of type 'unsigned long long' but is of type 'char *' | +| test.c:472:17:472:26 | v_char_ptr | This argument should be of type 'size_t' but is of type 'char *' | +| test.c:476:16:476:25 | v_char_ptr | This argument should be of type 'unsigned int' but is of type 'char *' | +| test.c:477:17:477:26 | v_char_ptr | This argument should be of type 'unsigned int' but is of type 'char *' | +| test.c:478:18:478:27 | v_char_ptr | This argument should be of type 'unsigned int' but is of type 'char *' | +| test.c:479:17:479:26 | v_char_ptr | This argument should be of type 'unsigned long' but is of type 'char *' | +| test.c:480:18:480:27 | v_char_ptr | This argument should be of type 'unsigned long long' but is of type 'char *' | +| test.c:483:17:483:26 | v_char_ptr | This argument should be of type 'size_t' but is of type 'char *' | +| test.c:487:16:487:25 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:488:17:488:26 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:489:18:489:27 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:490:17:490:26 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:492:16:492:25 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:493:17:493:26 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:494:18:494:27 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:495:17:495:26 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:497:16:497:25 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:498:17:498:26 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:499:18:499:27 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:500:17:500:26 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:502:16:502:25 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:503:17:503:26 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:504:18:504:27 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:505:17:505:26 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:507:16:507:25 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:508:17:508:26 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:509:18:509:27 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:510:17:510:26 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:512:16:512:25 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:513:17:513:26 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:514:18:514:27 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:515:17:515:26 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:517:16:517:25 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:518:17:518:26 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:519:18:519:27 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:520:17:520:26 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:522:16:522:25 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:523:17:523:26 | v_char_ptr | This argument should be of type 'double' but is of type 'char *' | +| test.c:524:18:524:27 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:525:17:525:26 | v_char_ptr | This argument should be of type 'long double' but is of type 'char *' | +| test.c:527:16:527:25 | v_char_ptr | This argument should be of type 'char' but is of type 'char *' | +| test.c:528:17:528:26 | v_char_ptr | This argument should be of type 'wchar_t' but is of type 'char *' | +| test.c:530:16:530:20 | v_int | This argument should be of type 'char *' but is of type 'int' | +| test.c:531:17:531:21 | v_int | This argument should be of type 'wchar_t *' but is of type 'int' | +| test.c:533:16:533:20 | v_int | This argument should be of type 'void *' but is of type 'int' | +| test.c:535:16:535:20 | v_int | This argument should be of type 'int *' but is of type 'int' | +| test.c:536:17:536:21 | v_int | This argument should be of type 'short *' but is of type 'int' | +| test.c:537:18:537:22 | v_int | This argument should be of type 'char *' but is of type 'int' | +| test.c:538:17:538:21 | v_int | This argument should be of type 'long *' but is of type 'int' | +| test.c:539:18:539:22 | v_int | This argument should be of type 'long long *' but is of type 'int' | +| test.c:540:17:540:21 | v_int | This argument should be of type 'int *' but is of type 'int' | +| test.c:541:17:541:21 | v_int | This argument should be of type 'int *' but is of type 'int' | +| test.c:542:17:542:21 | v_int | This argument should be of type 'int *' but is of type 'int' | +| test.c:544:16:544:25 | v_char_ptr | This argument should be of type 'wchar_t' but is of type 'char *' | +| test.c:546:16:546:20 | v_int | This argument should be of type 'wchar_t *' but is of type 'int' | From 63c9c7cee8db7da34d3ebd1177b7940af71b1e2b Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 12 Apr 2023 21:28:13 +0200 Subject: [PATCH 11/34] Undo changes to FileAccess.qll --- .../cpp/standardlibrary/FileAccess.qll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/standardlibrary/FileAccess.qll b/cpp/common/src/codingstandards/cpp/standardlibrary/FileAccess.qll index 0ffd7f3ec9..194c4ade81 100644 --- a/cpp/common/src/codingstandards/cpp/standardlibrary/FileAccess.qll +++ b/cpp/common/src/codingstandards/cpp/standardlibrary/FileAccess.qll @@ -98,7 +98,7 @@ class FOpenCall extends FunctionCall { } abstract class FileAccess extends FunctionCall { - abstract VariableAccess getFileExpr(); + abstract Expr getFileExpr(); } pragma[inline] @@ -124,7 +124,7 @@ class ImplicitFileAccess extends FileAccess { } /** The expression corresponding to the accessed file */ - override VariableAccess getFileExpr() { + override Expr getFileExpr() { fileName = result.(VariableAccess).getTarget().(GlobalVariable).toString() or fileName = result.findRootCause().(Macro).getName() } @@ -141,7 +141,7 @@ class InBandErrorReadFunctionCall extends FileAccess { } /** The expression corresponding to the accessed file */ - override VariableAccess getFileExpr() { + override Expr getFileExpr() { if this instanceof ImplicitFileAccess then result = this.(ImplicitFileAccess).getFileExpr() else result = [this.getArgument(0), this.getArgument(0).(AddressOfExpr).getAnOperand()] @@ -167,7 +167,7 @@ class FileReadFunctionCall extends FileAccess { } /** The expression corresponding to the accessed file */ - override VariableAccess getFileExpr() { + override Expr getFileExpr() { if this instanceof ImplicitFileAccess then result = this.(ImplicitFileAccess).getFileExpr() else @@ -196,7 +196,7 @@ class FileWriteFunctionCall extends FileAccess { } /** The expression corresponding to the accessed file */ - override VariableAccess getFileExpr() { + override Expr getFileExpr() { if this instanceof ImplicitFileAccess then result = this.(ImplicitFileAccess).getFileExpr() else @@ -225,7 +225,7 @@ class FilePositioningFunctionCall extends FileAccess { } /** The expression corresponding to the accessed file */ - override VariableAccess getFileExpr() { + override Expr getFileExpr() { result = [this.getArgument(0), this.getArgument(0).(AddressOfExpr).getAnOperand()] } } From 3b70892e409a946b2f08cef2f0a0987f4e1506a2 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 13 Apr 2023 00:24:55 +0200 Subject: [PATCH 12/34] FIO-46: file as expression --- .../donotaccessaclosedfile/DoNotAccessAClosedFile.qll | 2 +- .../codingstandards/cpp/standardlibrary/FileAccess.qll | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/rules/donotaccessaclosedfile/DoNotAccessAClosedFile.qll b/cpp/common/src/codingstandards/cpp/rules/donotaccessaclosedfile/DoNotAccessAClosedFile.qll index bea25d6ffa..83266ed524 100644 --- a/cpp/common/src/codingstandards/cpp/rules/donotaccessaclosedfile/DoNotAccessAClosedFile.qll +++ b/cpp/common/src/codingstandards/cpp/rules/donotaccessaclosedfile/DoNotAccessAClosedFile.qll @@ -27,7 +27,7 @@ predicate accessSameVariable(VariableAccess va1, VariableAccess va2) { va1.getTarget() = va2.getTarget() } -SubBasicBlock followsFileClose(SubBasicBlock source, VariableAccess closedFile) { +SubBasicBlock followsFileClose(SubBasicBlock source, Expr closedFile) { result = source or exists(SubBasicBlock mid | diff --git a/cpp/common/src/codingstandards/cpp/standardlibrary/FileAccess.qll b/cpp/common/src/codingstandards/cpp/standardlibrary/FileAccess.qll index 194c4ade81..58d93de1a9 100644 --- a/cpp/common/src/codingstandards/cpp/standardlibrary/FileAccess.qll +++ b/cpp/common/src/codingstandards/cpp/standardlibrary/FileAccess.qll @@ -114,18 +114,18 @@ class ImplicitFileAccess extends FileAccess { string fileName; ImplicitFileAccess() { - fileName = ["stdin", "_Stdin"] and + fileName = "stdin" and this.getTarget().hasGlobalName(["getchar", "getwchar", "scanf", "scanf_s"]) or - fileName = ["stdout", "_Stdout"] and + fileName = "stdout" and this.getTarget().hasGlobalName(["printf", "printf_s", "puts", "putchar", "putwchar"]) or - fileName = ["stderr", "_Stderr"] and this.getTarget().hasGlobalName("perror") + fileName = "stderr" and this.getTarget().hasGlobalName("perror") } /** The expression corresponding to the accessed file */ override Expr getFileExpr() { - fileName = result.(VariableAccess).getTarget().(GlobalVariable).toString() or + result = any(MacroInvocation mi | mi.getMacroName() = fileName).getExpr() or fileName = result.findRootCause().(Macro).getName() } } From 3cef6ca0c78f8ac0961509610f5deabaa6438486 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 13 Apr 2023 01:14:34 +0200 Subject: [PATCH 13/34] STR34-C: Add `.expected.qcc` file based on the `gcc` one --- ...CharBeforeConvertingToLargerSizes.expected.qcc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.qcc diff --git a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.qcc b/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.qcc new file mode 100644 index 0000000000..1cf143a196 --- /dev/null +++ b/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.qcc @@ -0,0 +1,15 @@ +| test.c:7:7:7:14 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:28:3:28:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:29:3:29:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:31:3:31:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:32:3:32:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:33:3:33:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:34:3:34:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:35:3:35:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:36:3:36:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:37:3:37:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:38:3:38:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:39:3:39:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:40:3:40:14 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:42:11:42:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:43:11:43:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | From ced2ee97ad0f80dfeb5c03ae0a44c69a22dec628 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 13 Apr 2023 01:21:48 +0200 Subject: [PATCH 14/34] STR34-C: fix `.expected.qcc` file --- .../CastCharBeforeConvertingToLargerSizes.expected.qcc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.qcc b/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.qcc index 1cf143a196..fec6522014 100644 --- a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.qcc +++ b/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.qcc @@ -11,5 +11,5 @@ | test.c:38:3:38:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:39:3:39:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:40:3:40:14 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:42:11:42:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:43:11:43:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:42:3:42:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:43:3:43:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | From c9a42838515dcab36d743877d4466d920effd67c Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 13 Apr 2023 21:42:59 +0200 Subject: [PATCH 15/34] Add tempfiles for matrix testing --- c/cert/test/rules/FIO34-C/tempfile | 0 c/cert/test/rules/FIO46-C/tempfile | 0 c/common/test/rules/donotaccessaclosedfile/tempfile | 0 c/misra/test/rules/RULE-22-6/tempfile | 0 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 c/cert/test/rules/FIO34-C/tempfile create mode 100644 c/cert/test/rules/FIO46-C/tempfile create mode 100644 c/common/test/rules/donotaccessaclosedfile/tempfile create mode 100644 c/misra/test/rules/RULE-22-6/tempfile diff --git a/c/cert/test/rules/FIO34-C/tempfile b/c/cert/test/rules/FIO34-C/tempfile new file mode 100644 index 0000000000..e69de29bb2 diff --git a/c/cert/test/rules/FIO46-C/tempfile b/c/cert/test/rules/FIO46-C/tempfile new file mode 100644 index 0000000000..e69de29bb2 diff --git a/c/common/test/rules/donotaccessaclosedfile/tempfile b/c/common/test/rules/donotaccessaclosedfile/tempfile new file mode 100644 index 0000000000..e69de29bb2 diff --git a/c/misra/test/rules/RULE-22-6/tempfile b/c/misra/test/rules/RULE-22-6/tempfile new file mode 100644 index 0000000000..e69de29bb2 From ef7d9497c7317962ccc9de9232c0b8131d6a07c6 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 13 Apr 2023 22:00:01 +0200 Subject: [PATCH 16/34] Add `.expected.qcc` for `donotaccessaclosedfile` --- .../DoNotAccessAClosedFile.expected.qcc | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 c/common/test/rules/donotaccessaclosedfile/DoNotAccessAClosedFile.expected.qcc diff --git a/c/common/test/rules/donotaccessaclosedfile/DoNotAccessAClosedFile.expected.qcc b/c/common/test/rules/donotaccessaclosedfile/DoNotAccessAClosedFile.expected.qcc new file mode 100644 index 0000000000..24d904e104 --- /dev/null +++ b/c/common/test/rules/donotaccessaclosedfile/DoNotAccessAClosedFile.expected.qcc @@ -0,0 +1,11 @@ +| test.c:6:3:6:8 | call to printf | Access of closed file& ... which was closed at $@ | test.c:4:3:4:8 | call to fclose | this location. | +| test.c:7:3:7:6 | call to puts | Access of closed file& ... which was closed at $@ | test.c:4:3:4:8 | call to fclose | this location. | +| test.c:16:13:16:18 | _Stderr | Access of closed file& ... which was closed at $@ | test.c:13:3:13:8 | call to fclose | this location. | +| test.c:17:3:17:8 | call to perror | Access of closed file& ... which was closed at $@ | test.c:13:3:13:8 | call to fclose | this location. | +| test.c:24:8:24:12 | _Stdin | Access of closed file& ... which was closed at $@ | test.c:22:3:22:8 | call to fclose | this location. | +| test.c:25:3:25:9 | call to getchar | Access of closed file& ... which was closed at $@ | test.c:22:3:22:8 | call to fclose | this location. | +| test.c:34:18:34:18 | f | Access of closed filef which was closed at $@ | test.c:31:3:31:8 | call to fclose | this location. | +| test.c:35:15:35:15 | f | Access of closed filef which was closed at $@ | test.c:31:3:31:8 | call to fclose | this location. | +| test.c:70:11:70:12 | fp | Access of closed filefp which was closed at $@ | test.c:69:3:69:8 | call to fclose | this location. | +| test.c:71:7:71:8 | fp | Access of closed filefp which was closed at $@ | test.c:69:3:69:8 | call to fclose | this location. | +| test.c:81:17:81:17 | f | Access of closed filef which was closed at $@ | test.c:80:3:80:8 | call to fclose | this location. | From c01c254733cfe9eb5a41fe9d43f0082138128c37 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Fri, 14 Apr 2023 11:08:33 -0400 Subject: [PATCH 17/34] fixed for shared queries. --- scripts/matrix_testing/Get-CompilerSpecificFiles.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/matrix_testing/Get-CompilerSpecificFiles.ps1 b/scripts/matrix_testing/Get-CompilerSpecificFiles.ps1 index 6197a05650..0d867cf095 100644 --- a/scripts/matrix_testing/Get-CompilerSpecificFiles.ps1 +++ b/scripts/matrix_testing/Get-CompilerSpecificFiles.ps1 @@ -31,7 +31,7 @@ function Get-CompilerSpecificFiles { $f } - foreach($f in (Get-ChildItem -Filter "$Query.expected.$Configuration" $TestDirectory)){ + foreach($f in (Get-ChildItem -Filter "*.expected.$Configuration" $TestDirectory)){ Write-Host "Found file $f..." $f } From 333ae99e9a83962c58c5e839f7596843469da7bb Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Fri, 14 Apr 2023 13:15:21 -0400 Subject: [PATCH 18/34] more fixes --- scripts/matrix_testing/CreateMatrixTestReport.ps1 | 8 +++++++- scripts/matrix_testing/Get-CompilerSpecificFiles.ps1 | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/matrix_testing/CreateMatrixTestReport.ps1 b/scripts/matrix_testing/CreateMatrixTestReport.ps1 index d306a3f0d9..d80e87e426 100644 --- a/scripts/matrix_testing/CreateMatrixTestReport.ps1 +++ b/scripts/matrix_testing/CreateMatrixTestReport.ps1 @@ -321,7 +321,13 @@ $jobRows = $queriesToCheck | ForEach-Object -ThrottleLimit $NumThreads -Parallel ########################################################### # Push context ########################################################### - $fileSet = (Get-CompilerSpecificFiles -Configuration $using:Configuration -Language $using:Language -TestDirectory $testDirectory -Query $CurrentQueryName) + + if ($q.shared_implementation_short_name) { + $fileSet = (Get-CompilerSpecificFiles -Configuration $using:Configuration -Language $using:Language -TestDirectory $testDirectory -Query $q.shared_implementation_short_name) + } + else { + $fileSet = (Get-CompilerSpecificFiles -Configuration $using:Configuration -Language $using:Language -TestDirectory $testDirectory -Query $CurrentQueryName) + } if($fileSet){ $context = Push-CompilerSpecificFiles -Configuration $using:Configuration -Language $using:Language -FileSet $fileSet diff --git a/scripts/matrix_testing/Get-CompilerSpecificFiles.ps1 b/scripts/matrix_testing/Get-CompilerSpecificFiles.ps1 index 0d867cf095..6197a05650 100644 --- a/scripts/matrix_testing/Get-CompilerSpecificFiles.ps1 +++ b/scripts/matrix_testing/Get-CompilerSpecificFiles.ps1 @@ -31,7 +31,7 @@ function Get-CompilerSpecificFiles { $f } - foreach($f in (Get-ChildItem -Filter "*.expected.$Configuration" $TestDirectory)){ + foreach($f in (Get-ChildItem -Filter "$Query.expected.$Configuration" $TestDirectory)){ Write-Host "Found file $f..." $f } From 6d7ce9ed3d5903a51eebdcd68b692fbbe369549d Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Fri, 14 Apr 2023 13:21:33 -0400 Subject: [PATCH 19/34] issue issue --- .github/workflows/dispatch-matrix-test-on-comment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dispatch-matrix-test-on-comment.yml b/.github/workflows/dispatch-matrix-test-on-comment.yml index 5d391539e0..bb307864c6 100644 --- a/.github/workflows/dispatch-matrix-test-on-comment.yml +++ b/.github/workflows/dispatch-matrix-test-on-comment.yml @@ -35,7 +35,7 @@ jobs: token: ${{ secrets.RELEASE_ENGINEERING_TOKEN }} repository: github/codeql-coding-standards-release-engineering event-type: matrix-test - client-payload: '{"pr": "${{ github.event.number }}"}' + client-payload: '{"pr": "${{ github.event.issue.number }}"}' - uses: actions/github-script@v6 if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-matrix') }} From d9bdde839539616b8d01e029090d96ed2628dfe8 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Tue, 18 Apr 2023 15:26:36 +0200 Subject: [PATCH 20/34] RULE-10-6: Fix output string format --- c/cert/test/rules/FIO46-C/tempfile | 0 c/common/test/rules/donotaccessaclosedfile/tempfile | 0 .../src/rules/RULE-10-6/AssignmentToWiderEssentialType.ql | 2 +- .../rules/RULE-10-6/AssignmentToWiderEssentialType.expected | 6 +++--- c/misra/test/rules/RULE-22-6/tempfile | 0 5 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 c/cert/test/rules/FIO46-C/tempfile delete mode 100644 c/common/test/rules/donotaccessaclosedfile/tempfile delete mode 100644 c/misra/test/rules/RULE-22-6/tempfile diff --git a/c/cert/test/rules/FIO46-C/tempfile b/c/cert/test/rules/FIO46-C/tempfile deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/c/common/test/rules/donotaccessaclosedfile/tempfile b/c/common/test/rules/donotaccessaclosedfile/tempfile deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/c/misra/src/rules/RULE-10-6/AssignmentToWiderEssentialType.ql b/c/misra/src/rules/RULE-10-6/AssignmentToWiderEssentialType.ql index bc1133c784..09e731ba71 100644 --- a/c/misra/src/rules/RULE-10-6/AssignmentToWiderEssentialType.ql +++ b/c/misra/src/rules/RULE-10-6/AssignmentToWiderEssentialType.ql @@ -26,4 +26,4 @@ where // Assignment to a different type category is prohibited by Rule 10.3, so we only report cases // where the assignment is to the same type category. getEssentialTypeCategory(lValueType) = getEssentialTypeCategory(compositeEssentialType) -select ce, "Assignment to wider essential type: $@." +select ce, "Assignment to wider essential type `" + lValueType.getName() + "`." diff --git a/c/misra/test/rules/RULE-10-6/AssignmentToWiderEssentialType.expected b/c/misra/test/rules/RULE-10-6/AssignmentToWiderEssentialType.expected index 0813de0e7c..6bae1a0a39 100644 --- a/c/misra/test/rules/RULE-10-6/AssignmentToWiderEssentialType.expected +++ b/c/misra/test/rules/RULE-10-6/AssignmentToWiderEssentialType.expected @@ -1,3 +1,3 @@ -| test.c:5:9:5:17 | ... + ... | Assignment to wider essential type: $@. | -| test.c:7:24:7:32 | ... + ... | Assignment to wider essential type: $@. | -| test.c:8:27:8:35 | ... + ... | Assignment to wider essential type: $@. | +| test.c:5:9:5:17 | ... + ... | Assignment to wider essential type `unsigned int`. | +| test.c:7:24:7:32 | ... + ... | Assignment to wider essential type `unsigned int`. | +| test.c:8:27:8:35 | ... + ... | Assignment to wider essential type `unsigned int`. | diff --git a/c/misra/test/rules/RULE-22-6/tempfile b/c/misra/test/rules/RULE-22-6/tempfile deleted file mode 100644 index e69de29bb2..0000000000 From 4cd4896903bad49994290affff8b283fc4cb267d Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Fri, 21 Apr 2023 21:57:26 +0200 Subject: [PATCH 21/34] STR37-C: toupper/tolower add support for macro implementation using array expression --- cpp/common/src/codingstandards/cpp/CharFunctions.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cpp/common/src/codingstandards/cpp/CharFunctions.qll b/cpp/common/src/codingstandards/cpp/CharFunctions.qll index bb47f77101..0782dbbcaa 100644 --- a/cpp/common/src/codingstandards/cpp/CharFunctions.qll +++ b/cpp/common/src/codingstandards/cpp/CharFunctions.qll @@ -54,6 +54,12 @@ private class CToOrIsCharMacroInvocation extends MacroInvocation, UseOfToOrIsCha result = ae.getArrayOffset().getFullyConverted().(Conversion).getExpr() ) or + // For the "toupper/tolower" APIs, QNX expands to an array access + exists(ArrayExpr ae | + ae = getExpr() and + result = ae.getArrayOffset().getFullyConverted().(Conversion).getExpr() + ) + or // For the tolower/toupper cases, a secondary macro is expanded exists(MacroInvocation mi | mi.getParentInvocation() = this and From f21c5cfdf9a4da4f6172908707ca9471841b1f40 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Fri, 21 Apr 2023 23:35:49 +0200 Subject: [PATCH 22/34] EXP43-C: Add explicitly mentioned functions --- ...sAliasedPointerToRestrictQualifiedParam.ql | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/c/cert/src/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.ql b/c/cert/src/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.ql index 32e50b2112..ee73a07fd8 100644 --- a/c/cert/src/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.ql +++ b/c/cert/src/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.ql @@ -25,9 +25,26 @@ class FunctionWithRestrictParameters extends Function { Parameter restrictPtrParam; FunctionWithRestrictParameters() { - restrictPtrParam = this.getAParameter() and restrictPtrParam.getUnspecifiedType() instanceof PointerOrArrayType and - restrictPtrParam.getType().hasSpecifier("restrict") + ( + restrictPtrParam.getType().hasSpecifier(["restrict"]) and + restrictPtrParam = this.getAParameter() + or + this.hasGlobalName(["strcpy", "strncpy", "strcat", "strncat", "memcpy"]) and + restrictPtrParam = this.getParameter([0, 1]) + or + this.hasGlobalName(["strcpy_s", "strncpy_s", "strcat_s", "strncat_s", "memcpy_s"]) and + restrictPtrParam = this.getParameter([0, 2]) + or + this.hasGlobalName(["strtok_s"]) and + restrictPtrParam = this.getAParameter() + or + this.hasGlobalName(["printf", "printf_s", "scanf", "scanf_s"]) and + restrictPtrParam = this.getParameter(0) + or + this.hasGlobalName(["sprintf", "sprintf_s", "snprintf", "snprintf_s"]) and + restrictPtrParam = this.getParameter(3) + ) } Parameter getARestrictPtrParam() { result = restrictPtrParam } From 723c25e32e5c3f30249bd284c53b73075c2217cf Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Fri, 21 Apr 2023 23:59:16 +0200 Subject: [PATCH 23/34] Create tempfile --- c/cert/test/rules/EXP43-C/tempfile | 1 + 1 file changed, 1 insertion(+) create mode 100644 c/cert/test/rules/EXP43-C/tempfile diff --git a/c/cert/test/rules/EXP43-C/tempfile b/c/cert/test/rules/EXP43-C/tempfile new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/c/cert/test/rules/EXP43-C/tempfile @@ -0,0 +1 @@ + From 1ad13b0417d66af7ca58eef24bc7bba77f9cd222 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Fri, 21 Apr 2023 23:59:27 +0200 Subject: [PATCH 24/34] Create tempfile --- c/cert/test/rules/STR37-C/tempfile | 1 + 1 file changed, 1 insertion(+) create mode 100644 c/cert/test/rules/STR37-C/tempfile diff --git a/c/cert/test/rules/STR37-C/tempfile b/c/cert/test/rules/STR37-C/tempfile new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/c/cert/test/rules/STR37-C/tempfile @@ -0,0 +1 @@ + From 6f659753ac91cd93409fb0ff9c5308d709faed75 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Sat, 22 Apr 2023 00:34:11 +0200 Subject: [PATCH 25/34] gix expect file --- ...FunctionsRepresentableAsUChar.expected.qcc | 28 ++ c/misra/test/rules/RULE-1-2/test.c | 4 +- c/misra/test/rules/RULE-1-2/test.c.gcc | 409 ------------------ c/misra/test/rules/RULE-1-2/test.c.qcc | 409 ------------------ 4 files changed, 30 insertions(+), 820 deletions(-) create mode 100644 c/cert/test/rules/STR37-C/ToCharacterHandlingFunctionsRepresentableAsUChar.expected.qcc delete mode 100644 c/misra/test/rules/RULE-1-2/test.c.gcc delete mode 100644 c/misra/test/rules/RULE-1-2/test.c.qcc diff --git a/c/cert/test/rules/STR37-C/ToCharacterHandlingFunctionsRepresentableAsUChar.expected.qcc b/c/cert/test/rules/STR37-C/ToCharacterHandlingFunctionsRepresentableAsUChar.expected.qcc new file mode 100644 index 0000000000..7cbab798dc --- /dev/null +++ b/c/cert/test/rules/STR37-C/ToCharacterHandlingFunctionsRepresentableAsUChar.expected.qcc @@ -0,0 +1,28 @@ +| test.c:7:3:7:13 | isalnum(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:7:3:7:13 | (...) | Argument | +| test.c:8:3:8:13 | isalpha(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:8:3:8:13 | (...) | Argument | +| test.c:10:3:10:13 | isblank(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:10:3:10:13 | (...) | Argument | +| test.c:11:3:11:13 | iscntrl(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:11:3:11:13 | (...) | Argument | +| test.c:12:3:12:13 | isdigit(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:12:3:12:13 | (...) | Argument | +| test.c:13:3:13:13 | isgraph(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:13:3:13:13 | (...) | Argument | +| test.c:14:3:14:13 | islower(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:14:3:14:13 | (...) | Argument | +| test.c:15:3:15:13 | isprint(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:15:3:15:13 | (...) | Argument | +| test.c:16:3:16:13 | ispunct(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:16:3:16:13 | (...) | Argument | +| test.c:17:3:17:13 | isspace(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:17:3:17:13 | (...) | Argument | +| test.c:18:3:18:13 | isupper(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:18:3:18:13 | (...) | Argument | +| test.c:19:3:19:14 | isxdigit(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:19:3:19:14 | (...) | Argument | +| test.c:21:3:21:13 | toupper(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:21:3:21:13 | (...) | Argument | +| test.c:22:3:22:13 | tolower(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:22:3:22:13 | (...) | Argument | +| test.c:70:3:70:12 | isalnum(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:70:3:70:12 | (...) | Argument | +| test.c:71:3:71:12 | isalpha(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:71:3:71:12 | (...) | Argument | +| test.c:73:3:73:12 | isblank(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:73:3:73:12 | (...) | Argument | +| test.c:74:3:74:12 | iscntrl(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:74:3:74:12 | (...) | Argument | +| test.c:75:3:75:12 | isdigit(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:75:3:75:12 | (...) | Argument | +| test.c:76:3:76:12 | isgraph(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:76:3:76:12 | (...) | Argument | +| test.c:77:3:77:12 | islower(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:77:3:77:12 | (...) | Argument | +| test.c:78:3:78:12 | isprint(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:78:3:78:12 | (...) | Argument | +| test.c:79:3:79:12 | ispunct(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:79:3:79:12 | (...) | Argument | +| test.c:80:3:80:12 | isspace(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:80:3:80:12 | (...) | Argument | +| test.c:81:3:81:12 | isupper(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:81:3:81:12 | (...) | Argument | +| test.c:82:3:82:13 | isxdigit(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:82:3:82:13 | (...) | Argument | +| test.c:84:3:84:12 | toupper(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:84:3:84:12 | (...) | Argument | +| test.c:85:3:85:12 | tolower(c) | $@ to character-handling function may not be representable as an unsigned char. | test.c:85:3:85:12 | (...) | Argument | diff --git a/c/misra/test/rules/RULE-1-2/test.c b/c/misra/test/rules/RULE-1-2/test.c index 367570f7e7..86a3ae2f20 100644 --- a/c/misra/test/rules/RULE-1-2/test.c +++ b/c/misra/test/rules/RULE-1-2/test.c @@ -114,8 +114,8 @@ void gf7() { } // Reference: https://gcc.gnu.org/onlinedocs/gcc/Typeof.html#Typeof -void gf8() { - typeof(int *); // NON_COMPLIANT[FALSE_NEGATIVE] +void gf8() { // not supported by qcc gcc and clang + // typeof(int *); // NON_COMPLIANT[FALSE_NEGATIVE] } // Reference: diff --git a/c/misra/test/rules/RULE-1-2/test.c.gcc b/c/misra/test/rules/RULE-1-2/test.c.gcc deleted file mode 100644 index 624d1d67d8..0000000000 --- a/c/misra/test/rules/RULE-1-2/test.c.gcc +++ /dev/null @@ -1,409 +0,0 @@ -#include -#include -// Note: Clang aims to support both clang and gcc extensions. -// This test case has been designed using lists compiled from: -// - https://clang.llvm.org/docs/LanguageExtensions.html -// - https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins -#ifdef __has_builtin // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_constexpr_builtin // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_feature // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_extension // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_c_attribute // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_attribute // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_declspec_attribute // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __is_identifier // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_include // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_include_next // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_warning // NON_COMPLIANT[FALSE_NEGATIVE] -#endif - -// Reference: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros -#define A __BASE_FILE__ // NON_COMPLIANT -#define B __FILE_NAME__ // NON_COMPLIANT -#define C __COUNTER__ // NON_COMPLIANT -#define D __INCLUDE_LEVEL__ // NON_COMPLIANT -#define E__TIMESTAMP__ // NON_COMPLIANT -#define F __clang__ // NON_COMPLIANT -#define G __clang_major__ // NON_COMPLIANT -#define H __clang_minor__ // NON_COMPLIANT -#define I __clang_patchlevel__ // NON_COMPLIANT -#define J __clang_version__ // NON_COMPLIANT -#define K __clang_literal_encoding__ // NON_COMPLIANT -#define L __clang_wide_literal_encoding__ // NON_COMPLIANT - -// Requires additional compiler flags to change the architecture -// typedef __attribute__((neon_vector_type(8))) int8_t int8x8_t; -// typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t; - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes -typedef int int4 __attribute__((vector_size(4 * sizeof(int)))); // NON_COMPLIANT -typedef int v4si __attribute__((__vector_size__(16))); // NON_COMPLIANT -typedef float float4 __attribute__((ext_vector_type(4))); // NON_COMPLIANT -typedef float float2 __attribute__((ext_vector_type(2))); // NON_COMPLIANT - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs -void gf1() { - ({ // NON_COMPLIANT - int y = 1; - int z; - if (y > 0) - z = y; - else - z = -y; - z; - }); -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Local-Labels.html#Local-Labels -void gf2() { - // __label__ found; // NON_COMPLIANT[FALSE_NEGATIVE] -- local labels not - // supported by clang -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html#Labels-as-Values -void gf3() { - void *ptr; - // goto *ptr; // NON_COMPLIANT[FALSE_NEGATIVE] -- not supported in clang -} - -// Referfence: -// https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html#Nested-Functions -void gf4() { - // void gf4a(){ // NON_COMPLIANT[FALSE_NEGATIVE] -- not supported in clang - // - // } -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Nonlocal-Gotos.html#Nonlocal-Gotos -void gf5() { - __builtin_setjmp(0); // NON_COMPLIANT - __builtin_longjmp(0, 1); // NON_COMPLIANT -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Constructing-Calls.html#Constructing-Calls -void gf6() { - // not supported by clang - //__builtin_apply_args(); // NON_COMPLIANT[FALSE_NEGATIVE] - //__builtin_apply(0, 0, 0); // NON_COMPLIANT[FALSE_NEGATIVE] - //__builtin_return(0); // NON_COMPLIANT[FALSE_NEGATIVE] - //__builtin_va_arg_pack(); // NON_COMPLIANT[FALSE_NEGATIVE] - //__builtin_va_arg_pack_len(); // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals -void gf7() { - int a = 0 ?: 0; // NON_COMPLIANT -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Typeof.html#Typeof -void gf8() { // not supported by qcc - // typeof(int *); // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128 -void gf9() { - __int128 a; // NON_COMPLIANT -} -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Long-Long.html#Long-Long -void gf10() { - long long int a; // NON_COMPLIANT -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Complex.html#Complex -void gf11() { - __real__(0); // NON_COMPLIANT[FALSE_NEGATIVE] - __imag__(0); // NON_COMPLIANT[FALSE_NEGATIVE] -} - -void gf12() {} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html#Floating-Types -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html#Decimal-Float -void gf13() { - // not supported on clang - //_Decimal32 a; // NON_COMPLIANT[FALSE_NEGATIVE] - //_Decimal64 b; // NON_COMPLIANT[FALSE_NEGATIVE] - //_Decimal128 c; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Complex.html#Complex -void gf14() { - // Do not work in clang - // typedef _Complex float __attribute__((mode(TC))) _Complex128; // - // NON_COMPLIANT[FALSE_NEGATIVE] typedef _Complex float - // __attribute__((mode(XC))) _Complex80; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Hex-Floats.html#Hex-Floats -void gf15() { - float f = 0x1.fp3; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html#Zero-Length -void gf16() { - char contents[0]; // NON_COMPLIANT -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html#Named-Address-Spaces -void gf17() { - // const __flash char ** p; // NON_COMPLIANT[FALSE_NEGATIVE] -- not supported - // in clang -} - -void gf18() { - // not supported by extractor - checked by looking for flags. - - // short _Fract, _Fract; // NON_COMPLIANT[FALSE_NEGATIVE] - - // long _Fract; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -struct gf19 {}; // NON_COMPLIANT - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length -void gf20(int n) { - // struct S { int x[n]; }; // NON_COMPLIANT[FALSE_NEGATIVE] - will never be - // supported in clang -} -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html#Variadic-Macros -#define gf21(format, args...) \ - printf(format, args) // NON_COMPLIANT[FALSE_NEGATIVE] -- note - // the issue here is explicitly naming the arguments. -#define gf21a(format, ...) printf(format, __VA_ARGS__) // COMPLIANT - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Escaped-Newlines.html#Escaped-Newlines -#define gf22 \ - "a" \ - \ -"b" // NON_COMPLIANT[FALSE_NEGATIVE] - additional spaces after a backslash -- - // stripped by extractor -#define gf22a \ - "a" \ - "b" // COMPLIANT - -void gf24(int f, int g) { - float beat_freqs[2] = {f - g, f + g}; // NON_COMPLIANT -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length -void gf25t(int N, int M, double out[M][N], // NON_COMPLIANT - const double in[N][M]); // NON_COMPLIANT -void gf25() { - double x[3][2]; - double y[2][3]; - gf25t(3, 2, y, - x); // in ISO C the const qualifier is formally attached - // to the element type of the array and not the array itself -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html#Compound-Literals -struct gf26t { - int a; - char b[2]; -} gf26v; -void gf26(int x, int y) { - gf26v = ((struct gf26t){ - x + y, 'z', 0}); // NON_COMPLIANT[FALSE_NEGATIVE] - compound literal -} -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html#Case-Ranges -void gf28() { - int a; - - // switch(a){ - // case: 0 ... 5: // NON_COMPLIANT[FALSE_NEGATIVE] - Not supported in - // clang. - // ;; - // break; - // default: - // ;; - // break; - // } -} - -union gf29u { - int i; - double j; -}; - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Cast-to-Union.html#Cast-to-Union -void gf29() { - int x; - int y; - union gf29u z; - z = (union gf29u)x; // NON_COMPLIANT[FALSE_NEGATIVE] - z = (union gf29u)y; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#Function-Attributes -__attribute__((access(read_only, 1))) int -gf30(const char *); // NON_COMPLIANT -- attributes are not portable. - -extern int __attribute__((alias("var_target"))) -gf31; // NON_COMPLIANT -- attributes are not portable. - -struct __attribute__((aligned(8))) gf32 { - short f[3]; -}; // NON_COMPLIANT -- attributes are not portable. - -void gf33() { -gf33l: - __attribute__((cold, unused)); // NON_COMPLIANT - return; -} - -enum gf34 { - oldval __attribute__((deprecated)), // NON_COMPLIANT - newval -}; - -void gf35() { - int x; - // __attribute__((assume(x == 42))); // NON_COMPLIANT[FALSE_NEGATIVE] - Not - // supported in clang - - switch (x) { - case 1: - printf(""); - __attribute__((fallthrough)); // NON_COMPLIANT - case 2: - break; - } -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Dollar-Signs.html#Dollar-Signs -void gf37() { - int a$1; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Character-Escapes.html#Character-Escapes -void gf38() { - const char *c = "test\e"; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -struct gf39s { - int x; - char y; -} gf39v; - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Alignment.html#Alignment -void gf39() { - __alignof__(gf39v.x); // NON_COMPLIANT -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Incomplete-Enums.html#Incomplete-Enums -// enum gf40 {}; // NON_COMPLIANT[FALSE_NEGATIVE] - not supported in clang - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html#Function-Names -void gf41() { - printf("__FUNCTION__ = %s\n", __FUNCTION__); // NON_COMPLIANT[FALSE_NEGATIVE] - printf("__PRETTY_FUNCTION__ = %s\n", - __PRETTY_FUNCTION__); // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins -void gf42() { - __builtin_extract_return_addr(0); // NON_COMPLIANT - __builtin_frob_return_addr(0); // NON_COMPLIANT - __builtin_frame_address(0); // NON_COMPLIANT -} - -struct gf43s { - int x; - char y; -} gf43v; - -void gf43() { - __builtin_offsetof(struct gf43s, x); // NON_COMPLIANT -} - -struct gf44s { - int x; - char y; -} gf44v; - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins -void gf44() { - int i; - __sync_fetch_and_add(&i, 0); // NON_COMPLIANT - __sync_fetch_and_sub(&i, 0); // NON_COMPLIANT - __sync_fetch_and_or(&i, 0); // NON_COMPLIANT - __sync_fetch_and_and(&i, 0); // NON_COMPLIANT - __sync_fetch_and_xor(&i, 0); // NON_COMPLIANT - __sync_fetch_and_nand(&i, 0); // NON_COMPLIANT - __sync_add_and_fetch(&i, 0); // NON_COMPLIANT - __sync_sub_and_fetch(&i, 0); // NON_COMPLIANT - __sync_or_and_fetch(&i, 0); // NON_COMPLIANT - __sync_and_and_fetch(&i, 0); // NON_COMPLIANT - __sync_xor_and_fetch(&i, 0); // NON_COMPLIANT - __sync_nand_and_fetch(&i, 0); // NON_COMPLIANT - - __sync_bool_compare_and_swap(&i, 0, 0); - __sync_val_compare_and_swap(&i, 0, 0); - __sync_lock_test_and_set(&i, 0, 0); - __sync_lock_release(&i, 0); -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html#Binary-constants -void gf45() { - int i = 0b101010; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Thread-Local.html#Thread-Local -__thread int gf46; // NON_COMPLIANT[FALSE_NEGATIVE] - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html#Unnamed-Fields -void gf47() { // NON_COMPLIANT in versions < C11. - struct { - int a; - union { - int b; - float c; - }; - int d; - } f; -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins -void gf48() { - __builtin_alloca( - 0); // NON_COMPLIANT (all __builtin functions are non-compliant.) -} \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-2/test.c.qcc b/c/misra/test/rules/RULE-1-2/test.c.qcc deleted file mode 100644 index 624d1d67d8..0000000000 --- a/c/misra/test/rules/RULE-1-2/test.c.qcc +++ /dev/null @@ -1,409 +0,0 @@ -#include -#include -// Note: Clang aims to support both clang and gcc extensions. -// This test case has been designed using lists compiled from: -// - https://clang.llvm.org/docs/LanguageExtensions.html -// - https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins -#ifdef __has_builtin // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_constexpr_builtin // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_feature // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_extension // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_c_attribute // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_attribute // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_declspec_attribute // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __is_identifier // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_include // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_include_next // NON_COMPLIANT[FALSE_NEGATIVE] -#endif -#ifdef __has_warning // NON_COMPLIANT[FALSE_NEGATIVE] -#endif - -// Reference: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros -#define A __BASE_FILE__ // NON_COMPLIANT -#define B __FILE_NAME__ // NON_COMPLIANT -#define C __COUNTER__ // NON_COMPLIANT -#define D __INCLUDE_LEVEL__ // NON_COMPLIANT -#define E__TIMESTAMP__ // NON_COMPLIANT -#define F __clang__ // NON_COMPLIANT -#define G __clang_major__ // NON_COMPLIANT -#define H __clang_minor__ // NON_COMPLIANT -#define I __clang_patchlevel__ // NON_COMPLIANT -#define J __clang_version__ // NON_COMPLIANT -#define K __clang_literal_encoding__ // NON_COMPLIANT -#define L __clang_wide_literal_encoding__ // NON_COMPLIANT - -// Requires additional compiler flags to change the architecture -// typedef __attribute__((neon_vector_type(8))) int8_t int8x8_t; -// typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t; - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes -typedef int int4 __attribute__((vector_size(4 * sizeof(int)))); // NON_COMPLIANT -typedef int v4si __attribute__((__vector_size__(16))); // NON_COMPLIANT -typedef float float4 __attribute__((ext_vector_type(4))); // NON_COMPLIANT -typedef float float2 __attribute__((ext_vector_type(2))); // NON_COMPLIANT - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs -void gf1() { - ({ // NON_COMPLIANT - int y = 1; - int z; - if (y > 0) - z = y; - else - z = -y; - z; - }); -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Local-Labels.html#Local-Labels -void gf2() { - // __label__ found; // NON_COMPLIANT[FALSE_NEGATIVE] -- local labels not - // supported by clang -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html#Labels-as-Values -void gf3() { - void *ptr; - // goto *ptr; // NON_COMPLIANT[FALSE_NEGATIVE] -- not supported in clang -} - -// Referfence: -// https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html#Nested-Functions -void gf4() { - // void gf4a(){ // NON_COMPLIANT[FALSE_NEGATIVE] -- not supported in clang - // - // } -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Nonlocal-Gotos.html#Nonlocal-Gotos -void gf5() { - __builtin_setjmp(0); // NON_COMPLIANT - __builtin_longjmp(0, 1); // NON_COMPLIANT -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Constructing-Calls.html#Constructing-Calls -void gf6() { - // not supported by clang - //__builtin_apply_args(); // NON_COMPLIANT[FALSE_NEGATIVE] - //__builtin_apply(0, 0, 0); // NON_COMPLIANT[FALSE_NEGATIVE] - //__builtin_return(0); // NON_COMPLIANT[FALSE_NEGATIVE] - //__builtin_va_arg_pack(); // NON_COMPLIANT[FALSE_NEGATIVE] - //__builtin_va_arg_pack_len(); // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals -void gf7() { - int a = 0 ?: 0; // NON_COMPLIANT -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Typeof.html#Typeof -void gf8() { // not supported by qcc - // typeof(int *); // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128 -void gf9() { - __int128 a; // NON_COMPLIANT -} -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Long-Long.html#Long-Long -void gf10() { - long long int a; // NON_COMPLIANT -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Complex.html#Complex -void gf11() { - __real__(0); // NON_COMPLIANT[FALSE_NEGATIVE] - __imag__(0); // NON_COMPLIANT[FALSE_NEGATIVE] -} - -void gf12() {} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html#Floating-Types -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html#Decimal-Float -void gf13() { - // not supported on clang - //_Decimal32 a; // NON_COMPLIANT[FALSE_NEGATIVE] - //_Decimal64 b; // NON_COMPLIANT[FALSE_NEGATIVE] - //_Decimal128 c; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Complex.html#Complex -void gf14() { - // Do not work in clang - // typedef _Complex float __attribute__((mode(TC))) _Complex128; // - // NON_COMPLIANT[FALSE_NEGATIVE] typedef _Complex float - // __attribute__((mode(XC))) _Complex80; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Hex-Floats.html#Hex-Floats -void gf15() { - float f = 0x1.fp3; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html#Zero-Length -void gf16() { - char contents[0]; // NON_COMPLIANT -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html#Named-Address-Spaces -void gf17() { - // const __flash char ** p; // NON_COMPLIANT[FALSE_NEGATIVE] -- not supported - // in clang -} - -void gf18() { - // not supported by extractor - checked by looking for flags. - - // short _Fract, _Fract; // NON_COMPLIANT[FALSE_NEGATIVE] - - // long _Fract; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -struct gf19 {}; // NON_COMPLIANT - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length -void gf20(int n) { - // struct S { int x[n]; }; // NON_COMPLIANT[FALSE_NEGATIVE] - will never be - // supported in clang -} -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html#Variadic-Macros -#define gf21(format, args...) \ - printf(format, args) // NON_COMPLIANT[FALSE_NEGATIVE] -- note - // the issue here is explicitly naming the arguments. -#define gf21a(format, ...) printf(format, __VA_ARGS__) // COMPLIANT - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Escaped-Newlines.html#Escaped-Newlines -#define gf22 \ - "a" \ - \ -"b" // NON_COMPLIANT[FALSE_NEGATIVE] - additional spaces after a backslash -- - // stripped by extractor -#define gf22a \ - "a" \ - "b" // COMPLIANT - -void gf24(int f, int g) { - float beat_freqs[2] = {f - g, f + g}; // NON_COMPLIANT -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length -void gf25t(int N, int M, double out[M][N], // NON_COMPLIANT - const double in[N][M]); // NON_COMPLIANT -void gf25() { - double x[3][2]; - double y[2][3]; - gf25t(3, 2, y, - x); // in ISO C the const qualifier is formally attached - // to the element type of the array and not the array itself -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html#Compound-Literals -struct gf26t { - int a; - char b[2]; -} gf26v; -void gf26(int x, int y) { - gf26v = ((struct gf26t){ - x + y, 'z', 0}); // NON_COMPLIANT[FALSE_NEGATIVE] - compound literal -} -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html#Case-Ranges -void gf28() { - int a; - - // switch(a){ - // case: 0 ... 5: // NON_COMPLIANT[FALSE_NEGATIVE] - Not supported in - // clang. - // ;; - // break; - // default: - // ;; - // break; - // } -} - -union gf29u { - int i; - double j; -}; - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Cast-to-Union.html#Cast-to-Union -void gf29() { - int x; - int y; - union gf29u z; - z = (union gf29u)x; // NON_COMPLIANT[FALSE_NEGATIVE] - z = (union gf29u)y; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#Function-Attributes -__attribute__((access(read_only, 1))) int -gf30(const char *); // NON_COMPLIANT -- attributes are not portable. - -extern int __attribute__((alias("var_target"))) -gf31; // NON_COMPLIANT -- attributes are not portable. - -struct __attribute__((aligned(8))) gf32 { - short f[3]; -}; // NON_COMPLIANT -- attributes are not portable. - -void gf33() { -gf33l: - __attribute__((cold, unused)); // NON_COMPLIANT - return; -} - -enum gf34 { - oldval __attribute__((deprecated)), // NON_COMPLIANT - newval -}; - -void gf35() { - int x; - // __attribute__((assume(x == 42))); // NON_COMPLIANT[FALSE_NEGATIVE] - Not - // supported in clang - - switch (x) { - case 1: - printf(""); - __attribute__((fallthrough)); // NON_COMPLIANT - case 2: - break; - } -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Dollar-Signs.html#Dollar-Signs -void gf37() { - int a$1; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Character-Escapes.html#Character-Escapes -void gf38() { - const char *c = "test\e"; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -struct gf39s { - int x; - char y; -} gf39v; - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Alignment.html#Alignment -void gf39() { - __alignof__(gf39v.x); // NON_COMPLIANT -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Incomplete-Enums.html#Incomplete-Enums -// enum gf40 {}; // NON_COMPLIANT[FALSE_NEGATIVE] - not supported in clang - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html#Function-Names -void gf41() { - printf("__FUNCTION__ = %s\n", __FUNCTION__); // NON_COMPLIANT[FALSE_NEGATIVE] - printf("__PRETTY_FUNCTION__ = %s\n", - __PRETTY_FUNCTION__); // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins -void gf42() { - __builtin_extract_return_addr(0); // NON_COMPLIANT - __builtin_frob_return_addr(0); // NON_COMPLIANT - __builtin_frame_address(0); // NON_COMPLIANT -} - -struct gf43s { - int x; - char y; -} gf43v; - -void gf43() { - __builtin_offsetof(struct gf43s, x); // NON_COMPLIANT -} - -struct gf44s { - int x; - char y; -} gf44v; - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins -void gf44() { - int i; - __sync_fetch_and_add(&i, 0); // NON_COMPLIANT - __sync_fetch_and_sub(&i, 0); // NON_COMPLIANT - __sync_fetch_and_or(&i, 0); // NON_COMPLIANT - __sync_fetch_and_and(&i, 0); // NON_COMPLIANT - __sync_fetch_and_xor(&i, 0); // NON_COMPLIANT - __sync_fetch_and_nand(&i, 0); // NON_COMPLIANT - __sync_add_and_fetch(&i, 0); // NON_COMPLIANT - __sync_sub_and_fetch(&i, 0); // NON_COMPLIANT - __sync_or_and_fetch(&i, 0); // NON_COMPLIANT - __sync_and_and_fetch(&i, 0); // NON_COMPLIANT - __sync_xor_and_fetch(&i, 0); // NON_COMPLIANT - __sync_nand_and_fetch(&i, 0); // NON_COMPLIANT - - __sync_bool_compare_and_swap(&i, 0, 0); - __sync_val_compare_and_swap(&i, 0, 0); - __sync_lock_test_and_set(&i, 0, 0); - __sync_lock_release(&i, 0); -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html#Binary-constants -void gf45() { - int i = 0b101010; // NON_COMPLIANT[FALSE_NEGATIVE] -} - -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Thread-Local.html#Thread-Local -__thread int gf46; // NON_COMPLIANT[FALSE_NEGATIVE] - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html#Unnamed-Fields -void gf47() { // NON_COMPLIANT in versions < C11. - struct { - int a; - union { - int b; - float c; - }; - int d; - } f; -} - -// Reference: -// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins -void gf48() { - __builtin_alloca( - 0); // NON_COMPLIANT (all __builtin functions are non-compliant.) -} \ No newline at end of file From 8f35e453ade51ebf94b153fa79b5c0dd25d5b941 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 24 Apr 2023 16:13:47 +0200 Subject: [PATCH 26/34] RULE-11-1 RULE-11-2 RULE-11-5: Add support for alternative NULL pointer definition --- c/common/src/codingstandards/c/Pointers.qll | 2 ++ c/misra/src/rules/RULE-11-1/tempfile | 0 c/misra/src/rules/RULE-11-2/tempfile | 0 c/misra/src/rules/RULE-11-5/tempfile | 0 4 files changed, 2 insertions(+) create mode 100644 c/misra/src/rules/RULE-11-1/tempfile create mode 100644 c/misra/src/rules/RULE-11-2/tempfile create mode 100644 c/misra/src/rules/RULE-11-5/tempfile diff --git a/c/common/src/codingstandards/c/Pointers.qll b/c/common/src/codingstandards/c/Pointers.qll index 86e2c02d30..458c2271eb 100644 --- a/c/common/src/codingstandards/c/Pointers.qll +++ b/c/common/src/codingstandards/c/Pointers.qll @@ -68,6 +68,8 @@ predicate isNullPointerConstant(Expr e) { e instanceof Zero and c.getType() instanceof VoidPointerType ) + or + isNullPointerConstant(e.(Conversion).getExpr()) } predicate isCastNullPointerConstant(Cast c) { diff --git a/c/misra/src/rules/RULE-11-1/tempfile b/c/misra/src/rules/RULE-11-1/tempfile new file mode 100644 index 0000000000..e69de29bb2 diff --git a/c/misra/src/rules/RULE-11-2/tempfile b/c/misra/src/rules/RULE-11-2/tempfile new file mode 100644 index 0000000000..e69de29bb2 diff --git a/c/misra/src/rules/RULE-11-5/tempfile b/c/misra/src/rules/RULE-11-5/tempfile new file mode 100644 index 0000000000..e69de29bb2 From ca07311db9cdcb08ebb3409c4bb23ae188b4d89b Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 24 Apr 2023 16:48:59 +0200 Subject: [PATCH 27/34] STR32-C STR38-C: - removed links to library internals - documented false positives due to extractor errors --- .../DoNotConfuseNarrowAndWideFunctions.ql | 5 +- ...dToFunctionThatExpectsAString.expected.qcc | 15 ++++ c/cert/test/rules/STR32-C/test.c.qcc | 87 +++++++++++++++++++ ...oNotConfuseNarrowAndWideFunctions.expected | 24 ++--- ...ConfuseNarrowAndWideFunctions.expected.qcc | 9 ++ c/cert/test/rules/STR38-C/copy.c.qcc | 35 ++++++++ c/cert/test/rules/STR38-C/test.c | 8 +- rule_packages/c/Strings1.json | 5 +- rule_packages/c/Strings3.json | 5 +- 9 files changed, 170 insertions(+), 23 deletions(-) create mode 100644 c/cert/test/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.expected.qcc create mode 100644 c/cert/test/rules/STR32-C/test.c.qcc create mode 100644 c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected.qcc create mode 100644 c/cert/test/rules/STR38-C/copy.c.qcc diff --git a/c/cert/src/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.ql b/c/cert/src/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.ql index efc8889e16..a45f7ec7e1 100644 --- a/c/cert/src/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.ql +++ b/c/cert/src/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.ql @@ -63,6 +63,5 @@ where c instanceof WideToNarrowCast and actual = "wide" and expected = "narrow" ) select call, - "Call to function $@ with a " + actual + " character string $@ where a " + expected + - " character string $@ is expected.", call.getTarget(), call.getTarget().getName(), arg, - "argument", p, "parameter" + "Call to function `" + call.getTarget().getName() + "` with a " + actual + + " character string $@ where a " + expected + " character string is expected.", arg, "argument" diff --git a/c/cert/test/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.expected.qcc b/c/cert/test/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.expected.qcc new file mode 100644 index 0000000000..fe51f625a8 --- /dev/null +++ b/c/cert/test/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.expected.qcc @@ -0,0 +1,15 @@ +| test.c:19:3:19:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:7:20:7:24 | Co | this expression | +| test.c:20:3:20:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:7:20:7:24 | Co | this expression | +| test.c:22:3:22:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:13:3:13:9 | call to strncpy | this expression | +| test.c:23:3:23:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:13:3:13:9 | call to strncpy | this expression | +| test.c:24:3:24:8 | call to strlen | String modified by $@ is passed to function expecting a null-terminated string. | test.c:13:3:13:9 | call to strncpy | this expression | +| test.c:46:3:46:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:41:3:41:10 | call to snprintf | this expression | +| test.c:47:3:47:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:41:3:41:10 | call to snprintf | this expression | +| test.c:55:3:55:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:53:3:53:9 | call to strncat | this expression | +| test.c:56:3:56:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:53:3:53:9 | call to strncat | this expression | +| test.c:62:3:62:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:60:20:60:24 | Co | this expression | +| test.c:63:3:63:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:60:20:60:24 | Co | this expression | +| test.c:75:3:75:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:72:20:72:24 | Co | this expression | +| test.c:76:3:76:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:72:20:72:24 | Co | this expression | +| test.c:85:3:85:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:83:3:83:9 | call to strncpy | this expression | +| test.c:86:3:86:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:83:3:83:9 | call to strncpy | this expression | diff --git a/c/cert/test/rules/STR32-C/test.c.qcc b/c/cert/test/rules/STR32-C/test.c.qcc new file mode 100644 index 0000000000..1c6761a701 --- /dev/null +++ b/c/cert/test/rules/STR32-C/test.c.qcc @@ -0,0 +1,87 @@ +#include +#include +#include + +void f1() { + char a1_nt[7] = "CodeQL"; // is null terminated + char a1_nnt[3] = "Cod"; // is NOT null termianted + + char a1[9]; + char a2[10]; + char a9[10]; + + strncpy(a2, a1, 5); // not null terminated because n < length(src) + strncpy(a9, a1, 10); // is null terminated; n > length(src) + + printf("%s", a1_nt); // COMPLIANT + printf(a1_nt); // COMPLIANT + + printf("%s", a1_nnt); // NON_COMPLIANT + printf(a1_nnt); // NON_COMPLIANT + + printf("%s", a2); // NON_COMPLIANT + printf(a2); // NON_COMPLIANT + strlen(a2); // NON_COMPLIANT + + printf(a9); // COMPLIANT + printf(a9); // COMPLIANT + + wchar_t wa1_nt[7] = L"CodeQL"; // is null terminated + wchar_t wa1_nnt[3] = L"Cod"; // is NOT null termianted + wprintf(wa1_nt); // COMPLIANT + // FALSE_NEGATIVES due to https://github.com/github/codeql/issues/12914 + wprintf(wa1_nnt); // NON_COMPLIANT[FALSE_NEGATIVE] +} + +void f2() { + char a1[10]; + char a2[10]; + + snprintf(a1, 10, "CodeQL %d", 3); // will be null terminated + snprintf(a2, 11, "CodeQL %d", 3); // will not be null terminated + + printf("%s", a1); // COMPLIANT + printf(a1); // COMPLIANT + + printf("%s", a2); // NON_COMPLIANT + printf(a2); // NON_COMPLIANT +} + +void f3() { + char a1[2]; + + strncat(a1, "CodeQL", 5); // will not be null terminated + + printf(a1); // NON_COMPLIANT + printf("%s", a1); // NON_COMPLIANT +} + +void f4() { + char a1_nnt[3] = "Cod"; // is NOT null termianted + + printf("%s", a1_nnt); // NON_COMPLIANT + printf(a1_nnt); // NON_COMPLIANT + + a1_nnt[2] = '\0'; + + printf("%s", a1_nnt); // COMPLIANT + printf(a1_nnt); // COMPLIANT +} + +f5() { + char a1_nnt[3] = "Cod"; // is NOT null termianted + char a2[10] = "CodeQL"; + + printf("%s", a1_nnt); // NON_COMPLIANT + printf(a1_nnt); // NON_COMPLIANT + + a1_nnt[2] = '\0'; + + printf("%s", a1_nnt); // COMPLIANT + printf(a1_nnt); // COMPLIANT + + strncpy(a1_nnt, a2, 1); // not null terminated because n < length(src) + + printf("%s", a1_nnt); // NON_COMPLIANT + printf(a1_nnt); // NON_COMPLIANT +} \ No newline at end of file diff --git a/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected b/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected index f9499d3be5..4c60f39f02 100644 --- a/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected +++ b/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected @@ -1,12 +1,12 @@ -| test.c:15:3:15:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string $@ is expected. | test.c:6:7:6:13 | strncpy | strncpy | test.c:15:11:15:12 | w2 | argument | test.c:6:15:6:18 | (unnamed parameter 0) | parameter | -| test.c:15:3:15:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string $@ is expected. | test.c:6:7:6:13 | strncpy | strncpy | test.c:15:15:15:16 | w1 | argument | test.c:6:33:6:42 | (unnamed parameter 1) | parameter | -| test.c:16:3:16:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string $@ is expected. | test.c:6:7:6:13 | strncpy | strncpy | test.c:16:11:16:12 | w2 | argument | test.c:6:15:6:18 | (unnamed parameter 0) | parameter | -| test.c:26:3:26:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string $@ is expected. | test.c:7:10:7:16 | wcsncpy | wcsncpy | test.c:26:11:26:12 | n2 | argument | test.c:7:18:7:24 | (unnamed parameter 0) | parameter | -| test.c:26:3:26:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string $@ is expected. | test.c:7:10:7:16 | wcsncpy | wcsncpy | test.c:26:15:26:16 | n1 | argument | test.c:7:45:7:51 | (unnamed parameter 1) | parameter | -| test.c:27:3:27:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string $@ is expected. | test.c:7:10:7:16 | wcsncpy | wcsncpy | test.c:27:15:27:16 | n1 | argument | test.c:7:45:7:51 | (unnamed parameter 1) | parameter | -| test.c:32:3:32:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string $@ is expected. | test.c:6:7:6:13 | strncpy | strncpy | test.c:32:11:32:12 | w2 | argument | test.c:6:15:6:18 | (unnamed parameter 0) | parameter | -| test.c:32:3:32:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string $@ is expected. | test.c:6:7:6:13 | strncpy | strncpy | test.c:32:15:32:16 | w1 | argument | test.c:6:33:6:42 | (unnamed parameter 1) | parameter | -| test.c:33:3:33:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string $@ is expected. | test.c:6:7:6:13 | strncpy | strncpy | test.c:33:11:33:12 | w2 | argument | test.c:6:15:6:18 | (unnamed parameter 0) | parameter | -| test.c:36:3:36:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string $@ is expected. | test.c:7:10:7:16 | wcsncpy | wcsncpy | test.c:36:11:36:12 | n2 | argument | test.c:7:18:7:24 | (unnamed parameter 0) | parameter | -| test.c:36:3:36:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string $@ is expected. | test.c:7:10:7:16 | wcsncpy | wcsncpy | test.c:36:15:36:16 | n1 | argument | test.c:7:45:7:51 | (unnamed parameter 1) | parameter | -| test.c:37:3:37:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string $@ is expected. | test.c:7:10:7:16 | wcsncpy | wcsncpy | test.c:37:15:37:16 | n1 | argument | test.c:7:45:7:51 | (unnamed parameter 1) | parameter | +| test.c:11:3:11:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:11:3:11:9 | call to strncpy | strncpy | test.c:11:11:11:12 | w2 | argument | +| test.c:11:3:11:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:11:3:11:9 | call to strncpy | strncpy | test.c:11:15:11:16 | w1 | argument | +| test.c:12:3:12:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:12:3:12:9 | call to strncpy | strncpy | test.c:12:11:12:12 | w2 | argument | +| test.c:22:3:22:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:22:3:22:9 | call to wcsncpy | wcsncpy | test.c:22:11:22:12 | n2 | argument | +| test.c:22:3:22:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:22:3:22:9 | call to wcsncpy | wcsncpy | test.c:22:15:22:16 | n1 | argument | +| test.c:23:3:23:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:23:3:23:9 | call to wcsncpy | wcsncpy | test.c:23:15:23:16 | n1 | argument | +| test.c:28:3:28:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:28:3:28:9 | call to strncpy | strncpy | test.c:28:11:28:12 | w2 | argument | +| test.c:28:3:28:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:28:3:28:9 | call to strncpy | strncpy | test.c:28:15:28:16 | w1 | argument | +| test.c:29:3:29:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:29:3:29:9 | call to strncpy | strncpy | test.c:29:11:29:12 | w2 | argument | +| test.c:32:3:32:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:32:3:32:9 | call to wcsncpy | wcsncpy | test.c:32:11:32:12 | n2 | argument | +| test.c:32:3:32:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:32:3:32:9 | call to wcsncpy | wcsncpy | test.c:32:15:32:16 | n1 | argument | +| test.c:33:3:33:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:33:3:33:9 | call to wcsncpy | wcsncpy | test.c:33:15:33:16 | n1 | argument | diff --git a/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected.qcc b/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected.qcc new file mode 100644 index 0000000000..2a4d8fe027 --- /dev/null +++ b/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected.qcc @@ -0,0 +1,9 @@ +| test.c:22:3:22:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:22:3:22:9 | call to wcsncpy | wcsncpy | test.c:22:11:22:12 | n2 | argument | +| test.c:22:3:22:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:22:3:22:9 | call to wcsncpy | wcsncpy | test.c:22:15:22:16 | n1 | argument | +| test.c:23:3:23:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:23:3:23:9 | call to wcsncpy | wcsncpy | test.c:23:15:23:16 | n1 | argument | +| test.c:28:3:28:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:28:3:28:9 | call to strncpy | strncpy | test.c:28:11:28:12 | w2 | argument | +| test.c:28:3:28:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:28:3:28:9 | call to strncpy | strncpy | test.c:28:15:28:16 | w1 | argument | +| test.c:29:3:29:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:29:3:29:9 | call to strncpy | strncpy | test.c:29:11:29:12 | w2 | argument | +| test.c:32:3:32:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:32:3:32:9 | call to wcsncpy | wcsncpy | test.c:32:11:32:12 | n2 | argument | +| test.c:32:3:32:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:32:3:32:9 | call to wcsncpy | wcsncpy | test.c:32:15:32:16 | n1 | argument | +| test.c:33:3:33:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:33:3:33:9 | call to wcsncpy | wcsncpy | test.c:33:15:33:16 | n1 | argument | diff --git a/c/cert/test/rules/STR38-C/copy.c.qcc b/c/cert/test/rules/STR38-C/copy.c.qcc new file mode 100644 index 0000000000..59f8891e0a --- /dev/null +++ b/c/cert/test/rules/STR38-C/copy.c.qcc @@ -0,0 +1,35 @@ +#include +#include +#include + +void f1() { + wchar_t w1[] = L"codeql"; + wchar_t w2[] = L"codeql"; + char n1[] = "codeql"; + char n2[] = "codeql"; + // FALSE_NEGATIVES due to https://github.com/github/codeql/issues/12914 + strncpy(w2, w1, 1); // NON_COMPLIANT[FALSE_NEGATIVE] (2x) + strncpy(w2, n1, 1); // NON_COMPLIANT[FALSE_NEGATIVE] (1x) + strncpy(n2, n1, 1); // COMPLIANT +} + +void f2() { + wchar_t w1[] = L"codeql"; + wchar_t w2[] = L"codeql"; + char n1[] = "codeql"; + char n2[] = "codeql"; + + wcsncpy(n2, n1, 1); // NON_COMPLIANT (2x) + wcsncpy(w2, n1, 1); // NON_COMPLIANT (1x) + wcsncpy(w2, w1, 1); // COMPLIANT +} + +void f3(wchar_t *w1, wchar_t *w2, char *n1, char *n2) { + strncpy(w2, w1, 1); // NON_COMPLIANT (2x) + strncpy(w2, n1, 1); // NON_COMPLIANT (1x) + strncpy(n2, n1, 1); // COMPLIANT + + wcsncpy(n2, n1, 1); // NON_COMPLIANT (2x) + wcsncpy(w2, n1, 1); // NON_COMPLIANT (1x) + wcsncpy(w2, w1, 1); // COMPLIANT +} \ No newline at end of file diff --git a/c/cert/test/rules/STR38-C/test.c b/c/cert/test/rules/STR38-C/test.c index e4464a6d71..99bfc22b1b 100644 --- a/c/cert/test/rules/STR38-C/test.c +++ b/c/cert/test/rules/STR38-C/test.c @@ -1,10 +1,6 @@ #include - -// defined in and but we get absolute -// paths using the current alert so they are defined here. -// to prevent absolute paths from being generated. -char *strncpy(char *__restrict, const char *__restrict, size_t); -wchar_t *wcsncpy(wchar_t *__restrict, const wchar_t *__restrict, size_t); +#include +#include void f1() { wchar_t w1[] = L"codeql"; diff --git a/rule_packages/c/Strings1.json b/rule_packages/c/Strings1.json index a0347aefc2..39529df3cc 100644 --- a/rule_packages/c/Strings1.json +++ b/rule_packages/c/Strings1.json @@ -58,7 +58,10 @@ "tags": [ "correctness", "security" - ] + ], + "implementation_scope": { + "description": "Wide character types are not handled correctly on the `aarch64le` architecture. This can lead to false negative alerts." + } } ], "title": "Do not pass a non-null-terminated character sequence to a library function that expects a string" diff --git a/rule_packages/c/Strings3.json b/rule_packages/c/Strings3.json index dff9744cdd..9456f4b422 100644 --- a/rule_packages/c/Strings3.json +++ b/rule_packages/c/Strings3.json @@ -35,7 +35,10 @@ "tags": [ "correctness", "security" - ] + ], + "implementation_scope": { + "description": "Wide character types are not handled correctly on the `aarch64le` architecture. This can lead to false negative alerts." + } } ], "title": "Do not confuse narrow and wide character strings and functions" From f8a3ce9737c57322cf94d9a5563ee1ec5963ee7b Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 24 Apr 2023 17:19:18 +0200 Subject: [PATCH 28/34] Add `change_notes` file --- .../NonNullTerminatedToFunctionThatExpectsAString.md | 2 +- .../rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.md | 2 +- .../2023-04-24-fix-compatibility-issues-with-qnx.md | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 change_notes/2023-04-24-fix-compatibility-issues-with-qnx.md diff --git a/c/cert/src/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.md b/c/cert/src/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.md index 62ebcc2db9..cfe024adc7 100644 --- a/c/cert/src/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.md +++ b/c/cert/src/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.md @@ -271,7 +271,7 @@ CWE-123 – STR31-C = ## Implementation notes -None +Wide character types are not handled correctly on the `aarch64le` architecture. This can lead to false negative alerts. ## References diff --git a/c/cert/src/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.md b/c/cert/src/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.md index 3c08369681..504bd764ac 100644 --- a/c/cert/src/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.md +++ b/c/cert/src/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.md @@ -131,7 +131,7 @@ Search for vulnerabilities resulting from the violation of this rule on the [CER ## Implementation notes -None +Wide character types are not handled correctly on the `aarch64le` architecture. This can lead to false negative alerts. ## References diff --git a/change_notes/2023-04-24-fix-compatibility-issues-with-qnx.md b/change_notes/2023-04-24-fix-compatibility-issues-with-qnx.md new file mode 100644 index 0000000000..1eb65975f8 --- /dev/null +++ b/change_notes/2023-04-24-fix-compatibility-issues-with-qnx.md @@ -0,0 +1,9 @@ +* Fix compatibility issues with the `qcc` compiler and standard headers: + * `RULE-21-4`: `longjmp` can be implmented as macro + * `ENV32-C`: exit functions can be implmented as macro + * `ERR33-C` `FIO34-C` `FIO46-C` `RULE-22-6`: the library files `ReadErrorsAndEOF.qll` `DoNotAccessAClosedFile.qll` `FileAccess.qll` have been updated to support different definitions of IO related functions and macros + * `RULE-10-6`: Fix output string format + * `STR37-C`: add support for a different `tolower/toupper` macro implementation + * `EXP43-C`: add explicit support for library functions that are mentioned in the rule description + * `RULE-11-1` `RULE-11-2` `RULE-11-5`: support for a different NULL pointer definition + * `STR38-C`: removed links to library internals in the output message \ No newline at end of file From 8c0b1bf495a8c306e72e90d72fb976ba727657ce Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 24 Apr 2023 17:54:22 +0200 Subject: [PATCH 29/34] STR38-C: fix expected file --- ...tConfuseNarrowAndWideFunctions.expected.qcc | 18 +++++++++--------- .../rules/STR38-C/{copy.c.qcc => test.c.qcc} | 0 2 files changed, 9 insertions(+), 9 deletions(-) rename c/cert/test/rules/STR38-C/{copy.c.qcc => test.c.qcc} (100%) diff --git a/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected.qcc b/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected.qcc index 2a4d8fe027..6652d20c4e 100644 --- a/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected.qcc +++ b/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected.qcc @@ -1,9 +1,9 @@ -| test.c:22:3:22:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:22:3:22:9 | call to wcsncpy | wcsncpy | test.c:22:11:22:12 | n2 | argument | -| test.c:22:3:22:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:22:3:22:9 | call to wcsncpy | wcsncpy | test.c:22:15:22:16 | n1 | argument | -| test.c:23:3:23:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:23:3:23:9 | call to wcsncpy | wcsncpy | test.c:23:15:23:16 | n1 | argument | -| test.c:28:3:28:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:28:3:28:9 | call to strncpy | strncpy | test.c:28:11:28:12 | w2 | argument | -| test.c:28:3:28:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:28:3:28:9 | call to strncpy | strncpy | test.c:28:15:28:16 | w1 | argument | -| test.c:29:3:29:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:29:3:29:9 | call to strncpy | strncpy | test.c:29:11:29:12 | w2 | argument | -| test.c:32:3:32:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:32:3:32:9 | call to wcsncpy | wcsncpy | test.c:32:11:32:12 | n2 | argument | -| test.c:32:3:32:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:32:3:32:9 | call to wcsncpy | wcsncpy | test.c:32:15:32:16 | n1 | argument | -| test.c:33:3:33:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:33:3:33:9 | call to wcsncpy | wcsncpy | test.c:33:15:33:16 | n1 | argument | +| copy.c:22:3:22:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | copy.c:22:11:22:12 | n2 | argument | +| copy.c:22:3:22:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | copy.c:22:15:22:16 | n1 | argument | +| copy.c:23:3:23:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | copy.c:23:15:23:16 | n1 | argument | +| copy.c:28:3:28:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | copy.c:28:11:28:12 | w2 | argument | +| copy.c:28:3:28:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | copy.c:28:15:28:16 | w1 | argument | +| copy.c:29:3:29:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | copy.c:29:11:29:12 | w2 | argument | +| copy.c:32:3:32:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | copy.c:32:11:32:12 | n2 | argument | +| copy.c:32:3:32:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | copy.c:32:15:32:16 | n1 | argument | +| copy.c:33:3:33:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | copy.c:33:15:33:16 | n1 | argument | diff --git a/c/cert/test/rules/STR38-C/copy.c.qcc b/c/cert/test/rules/STR38-C/test.c.qcc similarity index 100% rename from c/cert/test/rules/STR38-C/copy.c.qcc rename to c/cert/test/rules/STR38-C/test.c.qcc From 868114743fad1252a621eb42b0bb57c9d500e55c Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 24 Apr 2023 18:10:12 +0200 Subject: [PATCH 30/34] Fix expected file --- ...tConfuseNarrowAndWideFunctions.expected.qcc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected.qcc b/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected.qcc index 6652d20c4e..704cff7a94 100644 --- a/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected.qcc +++ b/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected.qcc @@ -1,9 +1,9 @@ -| copy.c:22:3:22:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | copy.c:22:11:22:12 | n2 | argument | -| copy.c:22:3:22:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | copy.c:22:15:22:16 | n1 | argument | -| copy.c:23:3:23:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | copy.c:23:15:23:16 | n1 | argument | -| copy.c:28:3:28:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | copy.c:28:11:28:12 | w2 | argument | -| copy.c:28:3:28:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | copy.c:28:15:28:16 | w1 | argument | -| copy.c:29:3:29:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | copy.c:29:11:29:12 | w2 | argument | -| copy.c:32:3:32:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | copy.c:32:11:32:12 | n2 | argument | -| copy.c:32:3:32:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | copy.c:32:15:32:16 | n1 | argument | -| copy.c:33:3:33:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | copy.c:33:15:33:16 | n1 | argument | +| test.c:22:3:22:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | test.c:22:11:22:12 | n2 | argument | +| test.c:22:3:22:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | test.c:22:15:22:16 | n1 | argument | +| test.c:23:3:23:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | test.c:23:15:23:16 | n1 | argument | +| test.c:28:3:28:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | test.c:28:11:28:12 | w2 | argument | +| test.c:28:3:28:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | test.c:28:15:28:16 | w1 | argument | +| test.c:29:3:29:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | test.c:29:11:29:12 | w2 | argument | +| test.c:32:3:32:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | test.c:32:11:32:12 | n2 | argument | +| test.c:32:3:32:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | test.c:32:15:32:16 | n1 | argument | +| test.c:33:3:33:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | test.c:33:15:33:16 | n1 | argument | From b3b003025f810e86f9dccedf63f4fbd0d7c42eae Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 24 Apr 2023 18:51:52 +0200 Subject: [PATCH 31/34] Removing temp files --- c/cert/test/rules/EXP43-C/tempfile | 1 - c/cert/test/rules/FIO34-C/tempfile | 0 c/cert/test/rules/STR37-C/tempfile | 1 - c/misra/src/rules/RULE-11-1/tempfile | 0 c/misra/src/rules/RULE-11-2/tempfile | 0 c/misra/src/rules/RULE-11-5/tempfile | 0 6 files changed, 2 deletions(-) delete mode 100644 c/cert/test/rules/EXP43-C/tempfile delete mode 100644 c/cert/test/rules/FIO34-C/tempfile delete mode 100644 c/cert/test/rules/STR37-C/tempfile delete mode 100644 c/misra/src/rules/RULE-11-1/tempfile delete mode 100644 c/misra/src/rules/RULE-11-2/tempfile delete mode 100644 c/misra/src/rules/RULE-11-5/tempfile diff --git a/c/cert/test/rules/EXP43-C/tempfile b/c/cert/test/rules/EXP43-C/tempfile deleted file mode 100644 index 8b13789179..0000000000 --- a/c/cert/test/rules/EXP43-C/tempfile +++ /dev/null @@ -1 +0,0 @@ - diff --git a/c/cert/test/rules/FIO34-C/tempfile b/c/cert/test/rules/FIO34-C/tempfile deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/c/cert/test/rules/STR37-C/tempfile b/c/cert/test/rules/STR37-C/tempfile deleted file mode 100644 index 8b13789179..0000000000 --- a/c/cert/test/rules/STR37-C/tempfile +++ /dev/null @@ -1 +0,0 @@ - diff --git a/c/misra/src/rules/RULE-11-1/tempfile b/c/misra/src/rules/RULE-11-1/tempfile deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/c/misra/src/rules/RULE-11-2/tempfile b/c/misra/src/rules/RULE-11-2/tempfile deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/c/misra/src/rules/RULE-11-5/tempfile b/c/misra/src/rules/RULE-11-5/tempfile deleted file mode 100644 index e69de29bb2..0000000000 From ba2b58a9f335e9462aa19b1a19861352a6e68e36 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 24 Apr 2023 21:21:36 +0200 Subject: [PATCH 32/34] STR38-C: fix expected file --- ...oNotConfuseNarrowAndWideFunctions.expected | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected b/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected index 4c60f39f02..e575109ede 100644 --- a/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected +++ b/c/cert/test/rules/STR38-C/DoNotConfuseNarrowAndWideFunctions.expected @@ -1,12 +1,12 @@ -| test.c:11:3:11:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:11:3:11:9 | call to strncpy | strncpy | test.c:11:11:11:12 | w2 | argument | -| test.c:11:3:11:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:11:3:11:9 | call to strncpy | strncpy | test.c:11:15:11:16 | w1 | argument | -| test.c:12:3:12:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:12:3:12:9 | call to strncpy | strncpy | test.c:12:11:12:12 | w2 | argument | -| test.c:22:3:22:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:22:3:22:9 | call to wcsncpy | wcsncpy | test.c:22:11:22:12 | n2 | argument | -| test.c:22:3:22:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:22:3:22:9 | call to wcsncpy | wcsncpy | test.c:22:15:22:16 | n1 | argument | -| test.c:23:3:23:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:23:3:23:9 | call to wcsncpy | wcsncpy | test.c:23:15:23:16 | n1 | argument | -| test.c:28:3:28:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:28:3:28:9 | call to strncpy | strncpy | test.c:28:11:28:12 | w2 | argument | -| test.c:28:3:28:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:28:3:28:9 | call to strncpy | strncpy | test.c:28:15:28:16 | w1 | argument | -| test.c:29:3:29:9 | call to strncpy | Call to function $@ with a wide character string $@ where a narrow character string parameter is expected. | test.c:29:3:29:9 | call to strncpy | strncpy | test.c:29:11:29:12 | w2 | argument | -| test.c:32:3:32:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:32:3:32:9 | call to wcsncpy | wcsncpy | test.c:32:11:32:12 | n2 | argument | -| test.c:32:3:32:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:32:3:32:9 | call to wcsncpy | wcsncpy | test.c:32:15:32:16 | n1 | argument | -| test.c:33:3:33:9 | call to wcsncpy | Call to function $@ with a narrow character string $@ where a wide character string parameter is expected. | test.c:33:3:33:9 | call to wcsncpy | wcsncpy | test.c:33:15:33:16 | n1 | argument | +| test.c:11:3:11:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | test.c:11:11:11:12 | w2 | argument | +| test.c:11:3:11:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | test.c:11:15:11:16 | w1 | argument | +| test.c:12:3:12:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | test.c:12:11:12:12 | w2 | argument | +| test.c:22:3:22:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | test.c:22:11:22:12 | n2 | argument | +| test.c:22:3:22:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | test.c:22:15:22:16 | n1 | argument | +| test.c:23:3:23:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | test.c:23:15:23:16 | n1 | argument | +| test.c:28:3:28:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | test.c:28:11:28:12 | w2 | argument | +| test.c:28:3:28:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | test.c:28:15:28:16 | w1 | argument | +| test.c:29:3:29:9 | call to strncpy | Call to function `strncpy` with a wide character string $@ where a narrow character string is expected. | test.c:29:11:29:12 | w2 | argument | +| test.c:32:3:32:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | test.c:32:11:32:12 | n2 | argument | +| test.c:32:3:32:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | test.c:32:15:32:16 | n1 | argument | +| test.c:33:3:33:9 | call to wcsncpy | Call to function `wcsncpy` with a narrow character string $@ where a wide character string is expected. | test.c:33:15:33:16 | n1 | argument | From 0cbf676eadce8e1429d3b080207035c6af13b92a Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Tue, 25 Apr 2023 11:38:38 -0400 Subject: [PATCH 33/34] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 057877578c..b5a13c696f 100644 --- a/README.md +++ b/README.md @@ -50,3 +50,5 @@ All header files in [c/common/test/includes/standard-library](./c/common/test/in --- 1This repository incorporates portions of the SEI CERT® Coding Standards available at https://wiki.sei.cmu.edu/confluence/display/seccode/SEI+CERT+Coding+Standards; however, such use does not necessarily constitute or imply an endorsement, recommendation, or favoring by Carnegie Mellon University or its Software Engineering Institute. + + From 248683a2be15893c10953d027fe004be4e8c44bc Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 26 Apr 2023 10:58:20 +0200 Subject: [PATCH 34/34] Fix clang compilation issues: Fix test files for RULE-1-3 and CON38-C --- .../test.c | 2 -- c/misra/test/rules/RULE-1-3/test.c.clang | 25 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 c/misra/test/rules/RULE-1-3/test.c.clang diff --git a/c/common/test/rules/preservesafetywhenusingconditionvariables/test.c b/c/common/test/rules/preservesafetywhenusingconditionvariables/test.c index 0134a1fd6d..2c6028f0ae 100644 --- a/c/common/test/rules/preservesafetywhenusingconditionvariables/test.c +++ b/c/common/test/rules/preservesafetywhenusingconditionvariables/test.c @@ -29,7 +29,6 @@ void f1() { } mtx_destroy(&mxl); - return 0; } void f2() { @@ -48,5 +47,4 @@ void f2() { } mtx_destroy(&mxl); - return 0; } diff --git a/c/misra/test/rules/RULE-1-3/test.c.clang b/c/misra/test/rules/RULE-1-3/test.c.clang new file mode 100644 index 0000000000..380a0cb512 --- /dev/null +++ b/c/misra/test/rules/RULE-1-3/test.c.clang @@ -0,0 +1,25 @@ +// void main(void) { // COMPLIANT does not compile in clang +// } + +int ____codeql_coding_standards_m1(int argc, char **argv) { // NON_COMPLIANT + return 0; +} + +void ____codeql_coding_standards_m2(char *argc, char **argv) { // NON_COMPLIANT +} + +int ____codeql_coding_standards_m3(int argc, char *argv) { // NON_COMPLIANT + return 0; +} + +int ____codeql_coding_standards_m4() { // NON_COMPLIANT + return 0; +} + +int ____codeql_coding_standards_m5(int argc, int *argv) { // NON_COMPLIANT + return 0; +} + +int ____codeql_coding_standards_m6(int argc, int **argv) { // NON_COMPLIANT + return 0; +}