From 293450ffff25b1326b692b705ab94192826b77e9 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Wed, 22 Mar 2023 10:28:44 -0400 Subject: [PATCH 01/13] work --- .../LanguageExtensionsShouldNotBeUsed.ql | 7 +- c/misra/test/rules/RULE-1-2/test.c | 163 ++++++++++-------- rule_packages/c/Language2.json | 23 +-- rules.csv | 2 +- 4 files changed, 93 insertions(+), 102 deletions(-) diff --git a/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql b/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql index 8da2c09947..662b20d330 100644 --- a/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql +++ b/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql @@ -14,8 +14,9 @@ import cpp import codingstandards.c.misra +import codingstandards.c.Extensions -from +from CCompilerExtension e where - not isExcluded(x, Language2Package::languageExtensionsShouldNotBeUsedQuery()) and -select + not isExcluded(e, Language2Package::languageExtensionsShouldNotBeUsedQuery()) +select e, "Is a compiler extension and is not portable to other compilers." diff --git a/c/misra/test/rules/RULE-1-2/test.c b/c/misra/test/rules/RULE-1-2/test.c index f71fb1ac4f..435f366ff8 100644 --- a/c/misra/test/rules/RULE-1-2/test.c +++ b/c/misra/test/rules/RULE-1-2/test.c @@ -9,6 +9,7 @@ // - 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 #endif #ifdef __has_constexpr_builtin // NON_COMPLIANT @@ -32,6 +33,7 @@ #ifdef __has_warning // NON_COMPLIANT #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 @@ -45,24 +47,22 @@ #define K __clang_literal_encoding__ // NON_COMPLIANT #define L __clang_wide_literal_encoding__ // NON_COMPLIANT -typedef float float4 __attribute__((ext_vector_type(4))); // NON_COMPLIANT -typedef float float2 __attribute__((ext_vector_type(2))); // 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 -//// GCC features + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs void gf1() { - ({ + ({ // NON_COMPLIANT int y = 1; - int z; // NON_COMPLIANT + int z; if (y > 0) z = y; else @@ -71,149 +71,154 @@ void gf1() { }); } +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Local-Labels.html#Local-Labels void gf2() { - // __label__ found; -- local labels not supported by clang + // __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; -- not supported in clang + // 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(){ -- not supported in clang + // 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(); - //__builtin_apply(0, 0, 0); - //__builtin_return(0); - //__builtin_va_arg_pack(); - //__builtin_va_arg_pack_len(); + //__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() { - typeof(int *); // NON_COMPLIANT + 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 - __imag__(0); // NON_COMPLIANT + __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; - //_Decimal64 b; - //_Decimal128 c; + //_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() { - // Not sure how to get this to work. - // typedef _Complex float __attribute__((mode(TC))) _Complex128; - // typedef _Complex float __attribute__((mode(XC))) _Complex80; + // 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 + 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; // not supported in clang + // 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; - // long _Fract; + // 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]; }; // will never be supported in clang + // 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 -- note the issue here is explicitly + printf(format, args) // NON_COMPLIANT // 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 - additional spaces after a backslash +"b" // NON_COMPLIANT[FALSE_NEGATIVE] - additional spaces after a backslash -- stripped by extractor #define gf22a \ "a" \ "b" // COMPLIANT -struct gf23s { - int a[1]; -}; -struct gf23s gf23f(); -void gf23() { - gf23f().a[0]; // NON_COMPLIANT in C90 -} - void gf24(int f, int g) { float beat_freqs[2] = {f - g, f + g}; // NON_COMPLIANT } -void gf25t(int N, int M, double out[M][N], const double in[N][M]); +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length +void gf25t(int N, int M, double out[M][N], const double in[N][M]); // NON_COMPLIANT[FALSE_NEGATIVE] void gf25() { double x[3][2]; double y[2][3]; gf25t(3, 2, y, - x); // NON_COMPLIANT - in ISO C the const qualifier is formally attached + 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 - compound literal -} - -void gf27() { - int a[6] = {[4] = 29, [2] = 15}; // NON_COMPLIANT in C90. + 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: // Not supported in clang. + // case: 0 ... 5: // NON_COMPLIANT[FALSE_NEGATIVE] - Not supported in clang. // ;; // break; // default: @@ -227,16 +232,19 @@ union gf29u { 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 - z = (union gf29u)y; // NON_COMPLIANT + z = (union gf29u)x; // NON_COMPLIANT[FALSE_NEGATIVE] + z = (union gf29u)y; // NON_COMPLIANT[FALSE_NEGATIVE] } -__attribute__((access(read_only, 1))) int -gf30(const char *); // NON_COMPLIANT -- attributes are not portable. +// 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. @@ -258,7 +266,7 @@ enum gf34 { void gf35() { int x; - // __attribute__((assume(x == 42))); - Not supported in clang + // __attribute__((assume(x == 42))); // NON_COMPLIANT[FALSE_NEGATIVE] - Not supported in clang switch (x) { case 1: @@ -269,21 +277,14 @@ void gf35() { } } -// Not supported in clang. -// int gf36 (uid_t); - -// int -// gf36 (int x) -// { -// return x == 0; -// } - +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Dollar-Signs.html#Dollar-Signs void gf37() { - int a$1; // NON_COMPLIANT + 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 + const char *c = "test\e"; // NON_COMPLIANT[FALSE_NEGATIVE] } struct gf39s { @@ -291,21 +292,26 @@ struct gf39s { char y; } gf39v; +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Alignment.html#Alignment void gf39() { __alignof__(gf39v.x); // NON_COMPLIANT } -// enum gf40 {}; // not supported in clang +// 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 - printf("__PRETTY_FUNCTION__ = %s\n", __PRETTY_FUNCTION__); // NON_COMPLIANT + 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); - __builtin_frob_return_addr(0); - __builtin_frame_address(0); + __builtin_extract_return_addr(0); // NON_COMPLIANT + __builtin_frob_return_addr(0); // NON_COMPLIANT + __builtin_frame_address(0); // NON_COMPLIANT } struct gf43s { @@ -322,6 +328,7 @@ struct gf44s { 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 @@ -343,12 +350,15 @@ void gf44() { __sync_lock_release(&i, 0); } +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html#Binary-constants void gf45() { - int i = 0b101010; // NON_COMPLIANT + int i = 0b101010; // NON_COMPLIANT[FALSE_NEGATIVE] } -__thread int gf46; // NON_COMPLIANT +// 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; @@ -360,6 +370,7 @@ void gf47() { // NON_COMPLIANT in versions < C11. } 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/rule_packages/c/Language2.json b/rule_packages/c/Language2.json index 2fc720b57d..9dc4f72866 100644 --- a/rule_packages/c/Language2.json +++ b/rule_packages/c/Language2.json @@ -20,28 +20,7 @@ } ], "title": "All usage of assembly language should be documented" - }, - "RULE-1-2": { - "properties": { - "obligation": "advisory" - }, - "queries": [ - { - "description": "Language extensions can have inconsistent behavior and should not be used.", - "kind": "problem", - "name": "Language extensions should not be used", - "precision": "high", - "severity": "error", - "short_name": "LanguageExtensionsShouldNotBeUsed", - "tags": [ - "maintainability", - "readability", - "correctness" - ] - } - ], - "title": "Language extensions should not be used" - }, + }, "RULE-1-4": { "properties": { "obligation": "required" diff --git a/rules.csv b/rules.csv index 8031503680..429f9ede8f 100644 --- a/rules.csv +++ b/rules.csv @@ -617,7 +617,7 @@ c,MISRA-C-2012,DIR-4-12,Yes,Required,,,Dynamic memory allocation shall not be us c,MISRA-C-2012,DIR-4-13,Yes,Advisory,,,Functions which are designed to provide operations on a resource should be called in an appropriate sequence,,Contracts,Hard, c,MISRA-C-2012,DIR-4-14,Yes,Required,,,The validity of values received from external sources shall be checked,,Contracts,Hard, c,MISRA-C-2012,RULE-1-1,No,Required,,,"The program shall contain no violations of the standard C syntax and constraints, and shall not exceed the implementation's translation limits",,Language,Easy,"This should be checked via the compiler output, rather than CodeQL, which adds unnecessary steps." -c,MISRA-C-2012,RULE-1-2,Yes,Advisory,,,Language extensions should not be used,,Language2,Hard, +c,MISRA-C-2012,RULE-1-2,Yes,Advisory,,,Language extensions should not be used,,Language3,Hard, c,MISRA-C-2012,RULE-1-3,Yes,Required,,,There shall be no occurrence of undefined or critical unspecified behaviour,,Language3,Hard, c,MISRA-C-2012,RULE-1-4,Yes,Required,,,Emergent language features shall not be used,,Language2,Medium, c,MISRA-C-2012,RULE-2-1,Yes,Required,,,A project shall not contain unreachable code,M0-1-1,DeadCode,Import, From 58383ae8c8daa1aa1c77b449824a8a47a093756e Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Wed, 22 Mar 2023 10:28:51 -0400 Subject: [PATCH 02/13] work --- c/common/src/codingstandards/c/Extensions.qll | 106 ++++++++++++++++++ .../src/codingstandards/cpp/Extensions.qll | 4 + 2 files changed, 110 insertions(+) create mode 100644 c/common/src/codingstandards/c/Extensions.qll create mode 100644 cpp/common/src/codingstandards/cpp/Extensions.qll diff --git a/c/common/src/codingstandards/c/Extensions.qll b/c/common/src/codingstandards/c/Extensions.qll new file mode 100644 index 0000000000..fbadda35a5 --- /dev/null +++ b/c/common/src/codingstandards/c/Extensions.qll @@ -0,0 +1,106 @@ +import cpp +import codingstandards.cpp.Extensions + +/** + * Common base class for modeling compiler extensions. + */ +abstract class CCompilerExtension extends CompilerExtension { } + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins +abstract class CConditionalDefineExtension extends CCompilerExtension, PreprocessorIfdef { + CConditionalDefineExtension() { + exists(toString().indexOf("__has_builtin")) or + exists(toString().indexOf("__has_constexpr_builtin")) or + exists(toString().indexOf("__has_feature")) or + exists(toString().indexOf("__has_extension")) or + exists(toString().indexOf("__has_attribute")) or + exists(toString().indexOf("__has_declspec_attribute")) or + exists(toString().indexOf("__is_identifier")) or + exists(toString().indexOf("__has_include")) or + exists(toString().indexOf("__has_include_next")) or + exists(toString().indexOf("__has_warning")) + } +} + +// Reference: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros +class CMacroBasedExtension extends CCompilerExtension, Macro { + CMacroBasedExtension() { + getBody() in [ + "__BASE_FILE__", "__FILE_NAME__", "__COUNTER__", "__INCLUDE_LEVEL__", "_TIMESTAMP__", + "__clang__", "__clang_major__", "__clang_minor__", "__clang_patchlevel__", + "__clang_version__", "__clang_literal_encoding__", "__clang_wide_literal_encoding__" + ] + } +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes +class CAttributeExtension extends CCompilerExtension, Attribute { + CAttributeExtension() { + getName() in [ + "ext_vector_type", "vector_size", "access", "aligned", "deprecated", "cold", "unused", + "fallthrough", "read_only", "alias" + ] + } +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins +class CFunctionExtension extends CCompilerExtension, FunctionCall { + CFunctionExtension() { + // these must be somewhat broad because of how they vary + // in implementation / naming + getTarget().getName().indexOf("__sync_fetch") = 0 or + getTarget().getName().indexOf("__sync_add") = 0 or + getTarget().getName().indexOf("__sync_sub") = 0 or + getTarget().getName().indexOf("__sync_or") = 0 or + getTarget().getName().indexOf("__sync_and") = 0 or + getTarget().getName().indexOf("__sync_xor") = 0 or + getTarget().getName().indexOf("__sync_nand") = 0 or + getTarget().getName().indexOf("__sync_bool") = 0 or + getTarget().getName().indexOf("__sync_val") = 0 or + getTarget().getName().indexOf("__sync_lock") = 0 or + // the built-in extensions + getTarget().getName().indexOf("__builtin_") = 0 + } +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Alignment.html#Alignment +class CFunctionLikeExtension extends CCompilerExtension, AlignofExprOperator { + CFunctionLikeExtension() { exists(getValueText().indexOf("__alignof__")) } +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs +class CStmtExprExtension extends CCompilerExtension, StmtExpr {} + +// Use of ternary like the following: `int a = 0 ?: 0;` where the +// one of the branches is omitted +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals +class CTerseTernaryExtension extends CCompilerExtension, ConditionalExpr { + CTerseTernaryExtension() { getCondition() = getElse() or getCondition() = getThen() } +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128 +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html#Decimal-Float +class CRealTypeExtensionExtension extends CCompilerExtension, RealNumberType { + CRealTypeExtensionExtension() { + this instanceof Decimal128Type or + this instanceof Decimal32Type or + this instanceof Decimal64Type or + this instanceof Float128Type + } +} +// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128 +class CIntegerTypeExtension extends CCompilerExtension, Int128Type {} + +class CZeroLengthArraysExtension extends CCompilerExtension, DeclarationEntry { + CZeroLengthArraysExtension() { getType().(ArrayType).getArraySize() = 0 } +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html#Empty-Structures +class CEmptyStructExtension extends CCompilerExtension, Struct { + CEmptyStructExtension() { not exists(getAMember(_)) } +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length +class CVariableLengthArraysExtension extends CCompilerExtension, DeclarationEntry { + CVariableLengthArraysExtension() { not getType().(ArrayType).hasArraySize() } +} diff --git a/cpp/common/src/codingstandards/cpp/Extensions.qll b/cpp/common/src/codingstandards/cpp/Extensions.qll new file mode 100644 index 0000000000..5ab04257bf --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/Extensions.qll @@ -0,0 +1,4 @@ +import cpp + +abstract class CompilerExtension extends Locatable {} +abstract class CPPCompilerExtension extends CompilerExtension {} \ No newline at end of file From 6a1b3460037b07f4782b1d8fa29c3d7fd98f0bc8 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Wed, 22 Mar 2023 10:35:58 -0400 Subject: [PATCH 03/13] files --- .vscode/tasks.json | 1 + .../LanguageExtensionsShouldNotBeUsed.ql | 15 +++---- .../RULE-1-3/OccurrenceOfUndefinedBehavior.ql | 20 +++++++++ .../OccurrenceOfUndefinedBehavior.expected | 1 + .../OccurrenceOfUndefinedBehavior.qlref | 1 + .../cpp/exclusions/c/Language3.qll | 42 ++++++++++++++++++ .../cpp/exclusions/c/RuleMetadata.qll | 3 ++ rule_packages/c/Language3.json | 44 +++++++++++++++++++ 8 files changed, 119 insertions(+), 8 deletions(-) create mode 100644 c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql create mode 100644 c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.expected create mode 100644 c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.qlref create mode 100644 cpp/common/src/codingstandards/cpp/exclusions/c/Language3.qll create mode 100644 rule_packages/c/Language3.json diff --git a/.vscode/tasks.json b/.vscode/tasks.json index eed07a49b3..7beb906f11 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -223,6 +223,7 @@ "Lambdas", "Language1", "Language2", + "Language3", "Literals", "Loops", "Macros", diff --git a/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql b/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql index 662b20d330..da7b7918aa 100644 --- a/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql +++ b/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql @@ -1,22 +1,21 @@ /** * @id c/misra/language-extensions-should-not-be-used * @name RULE-1-2: Language extensions should not be used - * @description Language extensions can have inconsistent behavior and should not be used. + * @description Language extensions are not portable to other compilers and should not be used. * @kind problem * @precision high * @problem.severity error * @tags external/misra/id/rule-1-2 * maintainability * readability - * correctness * external/misra/obligation/advisory */ - -import cpp -import codingstandards.c.misra -import codingstandards.c.Extensions + import cpp + import codingstandards.c.misra + import codingstandards.c.Extensions from CCompilerExtension e where - not isExcluded(e, Language2Package::languageExtensionsShouldNotBeUsedQuery()) -select e, "Is a compiler extension and is not portable to other compilers." + not isExcluded(e, Language3Package::languageExtensionsShouldNotBeUsedQuery()) + select e, "Is a compiler extension and is not portable to other compilers." + diff --git a/c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql b/c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql new file mode 100644 index 0000000000..a00d207d65 --- /dev/null +++ b/c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql @@ -0,0 +1,20 @@ +/** + * @id c/misra/occurrence-of-undefined-behavior + * @name RULE-1-3: There shall be no occurrence of undefined or critical unspecified behavior + * @description Relying on undefined or unspecified behavior can result in unreliable programs. + * @kind problem + * @precision high + * @problem.severity error + * @tags external/misra/id/rule-1-3 + * maintainability + * readability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra + +from +where + not isExcluded(x, Language3Package::occurrenceOfUndefinedBehaviorQuery()) and +select diff --git a/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.expected b/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.expected new file mode 100644 index 0000000000..2ec1a0ac6c --- /dev/null +++ b/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.expected @@ -0,0 +1 @@ +No expected results have yet been specified \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.qlref b/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.qlref new file mode 100644 index 0000000000..b579db05b1 --- /dev/null +++ b/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.qlref @@ -0,0 +1 @@ +rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Language3.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Language3.qll new file mode 100644 index 0000000000..fe057f3b00 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Language3.qll @@ -0,0 +1,42 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype Language3Query = + TLanguageExtensionsShouldNotBeUsedQuery() or + TOccurrenceOfUndefinedBehaviorQuery() + +predicate isLanguage3QueryMetadata(Query query, string queryId, string ruleId) { + query = + // `Query` instance for the `languageExtensionsShouldNotBeUsed` query + Language3Package::languageExtensionsShouldNotBeUsedQuery() and + queryId = + // `@id` for the `languageExtensionsShouldNotBeUsed` query + "c/misra/language-extensions-should-not-be-used" and + ruleId = "RULE-1-2" + or + query = + // `Query` instance for the `occurrenceOfUndefinedBehavior` query + Language3Package::occurrenceOfUndefinedBehaviorQuery() and + queryId = + // `@id` for the `occurrenceOfUndefinedBehavior` query + "c/misra/occurrence-of-undefined-behavior" and + ruleId = "RULE-1-3" +} + +module Language3Package { + Query languageExtensionsShouldNotBeUsedQuery() { + //autogenerate `Query` type + result = + // `Query` type for `languageExtensionsShouldNotBeUsed` query + TQueryC(TLanguage3PackageQuery(TLanguageExtensionsShouldNotBeUsedQuery())) + } + + Query occurrenceOfUndefinedBehaviorQuery() { + //autogenerate `Query` type + result = + // `Query` type for `occurrenceOfUndefinedBehavior` query + TQueryC(TLanguage3PackageQuery(TOccurrenceOfUndefinedBehaviorQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll index 69fc7d2d07..25fd3c682a 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll @@ -22,6 +22,7 @@ import IO3 import IO4 import Language1 import Language2 +import Language3 import Misc import Pointers1 import Pointers2 @@ -59,6 +60,7 @@ newtype TCQuery = TIO4PackageQuery(IO4Query q) or TLanguage1PackageQuery(Language1Query q) or TLanguage2PackageQuery(Language2Query q) or + TLanguage3PackageQuery(Language3Query q) or TMiscPackageQuery(MiscQuery q) or TPointers1PackageQuery(Pointers1Query q) or TPointers2PackageQuery(Pointers2Query q) or @@ -96,6 +98,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId) { isIO4QueryMetadata(query, queryId, ruleId) or isLanguage1QueryMetadata(query, queryId, ruleId) or isLanguage2QueryMetadata(query, queryId, ruleId) or + isLanguage3QueryMetadata(query, queryId, ruleId) or isMiscQueryMetadata(query, queryId, ruleId) or isPointers1QueryMetadata(query, queryId, ruleId) or isPointers2QueryMetadata(query, queryId, ruleId) or diff --git a/rule_packages/c/Language3.json b/rule_packages/c/Language3.json new file mode 100644 index 0000000000..1c537fa667 --- /dev/null +++ b/rule_packages/c/Language3.json @@ -0,0 +1,44 @@ +{ + "MISRA-C-2012": { + "RULE-1-2": { + "properties": { + "obligation": "advisory" + }, + "queries": [ + { + "description": "Language extensions are not portable to other compilers and should not be used.", + "kind": "problem", + "name": "Language extensions should not be used", + "precision": "high", + "severity": "error", + "short_name": "LanguageExtensionsShouldNotBeUsed", + "tags": [ + "maintainability", + "readability" + ] + } + ], + "title": "Language extensions should not be used" + }, + "RULE-1-3": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "Relying on undefined or unspecified behavior can result in unreliable programs.", + "kind": "problem", + "name": "There shall be no occurrence of undefined or critical unspecified behavior", + "precision": "high", + "severity": "error", + "short_name": "OccurrenceOfUndefinedBehavior", + "tags": [ + "maintainability", + "readability" + ] + } + ], + "title": "There shall be no occurrence of undefined or critical unspecified behavior" + } + } +} \ No newline at end of file From def08936de334f90de17397c7fac1c7643eb0ff0 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Wed, 22 Mar 2023 10:36:11 -0400 Subject: [PATCH 04/13] update --- .../cpp/exclusions/c/Language2.qll | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Language2.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Language2.qll index 9d270d34be..0217551e59 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Language2.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Language2.qll @@ -5,7 +5,6 @@ import codingstandards.cpp.exclusions.RuleMetadata newtype Language2Query = TUsageOfAssemblyLanguageShouldBeDocumentedQuery() or - TLanguageExtensionsShouldNotBeUsedQuery() or TEmergentLanguageFeaturesUsedQuery() predicate isLanguage2QueryMetadata(Query query, string queryId, string ruleId) { @@ -17,14 +16,6 @@ predicate isLanguage2QueryMetadata(Query query, string queryId, string ruleId) { "c/misra/usage-of-assembly-language-should-be-documented" and ruleId = "DIR-4-2" or - query = - // `Query` instance for the `languageExtensionsShouldNotBeUsed` query - Language2Package::languageExtensionsShouldNotBeUsedQuery() and - queryId = - // `@id` for the `languageExtensionsShouldNotBeUsed` query - "c/misra/language-extensions-should-not-be-used" and - ruleId = "RULE-1-2" - or query = // `Query` instance for the `emergentLanguageFeaturesUsed` query Language2Package::emergentLanguageFeaturesUsedQuery() and @@ -42,13 +33,6 @@ module Language2Package { TQueryC(TLanguage2PackageQuery(TUsageOfAssemblyLanguageShouldBeDocumentedQuery())) } - Query languageExtensionsShouldNotBeUsedQuery() { - //autogenerate `Query` type - result = - // `Query` type for `languageExtensionsShouldNotBeUsed` query - TQueryC(TLanguage2PackageQuery(TLanguageExtensionsShouldNotBeUsedQuery())) - } - Query emergentLanguageFeaturesUsedQuery() { //autogenerate `Query` type result = From 8aee471a43bd112fa26c45f417f93801c677b21b Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Wed, 22 Mar 2023 10:37:14 -0400 Subject: [PATCH 05/13] formatting --- c/common/src/codingstandards/c/Extensions.qll | 7 ++++--- .../RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql | 13 ++++++------- cpp/common/src/codingstandards/cpp/Extensions.qll | 13 ++++++++++--- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/c/common/src/codingstandards/c/Extensions.qll b/c/common/src/codingstandards/c/Extensions.qll index fbadda35a5..7eb7b33c57 100644 --- a/c/common/src/codingstandards/c/Extensions.qll +++ b/c/common/src/codingstandards/c/Extensions.qll @@ -2,7 +2,7 @@ import cpp import codingstandards.cpp.Extensions /** - * Common base class for modeling compiler extensions. + * Common base class for modeling compiler extensions. */ abstract class CCompilerExtension extends CompilerExtension { } @@ -69,7 +69,7 @@ class CFunctionLikeExtension extends CCompilerExtension, AlignofExprOperator { } // Reference: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs -class CStmtExprExtension extends CCompilerExtension, StmtExpr {} +class CStmtExprExtension extends CCompilerExtension, StmtExpr { } // Use of ternary like the following: `int a = 0 ?: 0;` where the // one of the branches is omitted @@ -88,8 +88,9 @@ class CRealTypeExtensionExtension extends CCompilerExtension, RealNumberType { this instanceof Float128Type } } + // Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128 -class CIntegerTypeExtension extends CCompilerExtension, Int128Type {} +class CIntegerTypeExtension extends CCompilerExtension, Int128Type { } class CZeroLengthArraysExtension extends CCompilerExtension, DeclarationEntry { CZeroLengthArraysExtension() { getType().(ArrayType).getArraySize() = 0 } diff --git a/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql b/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql index da7b7918aa..f38e41a1b6 100644 --- a/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql +++ b/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql @@ -10,12 +10,11 @@ * readability * external/misra/obligation/advisory */ - import cpp - import codingstandards.c.misra - import codingstandards.c.Extensions -from CCompilerExtension e -where - not isExcluded(e, Language3Package::languageExtensionsShouldNotBeUsedQuery()) - select e, "Is a compiler extension and is not portable to other compilers." +import cpp +import codingstandards.c.misra +import codingstandards.c.Extensions +from CCompilerExtension e +where not isExcluded(e, Language3Package::languageExtensionsShouldNotBeUsedQuery()) +select e, "Is a compiler extension and is not portable to other compilers." diff --git a/cpp/common/src/codingstandards/cpp/Extensions.qll b/cpp/common/src/codingstandards/cpp/Extensions.qll index 5ab04257bf..5ca6cea4f6 100644 --- a/cpp/common/src/codingstandards/cpp/Extensions.qll +++ b/cpp/common/src/codingstandards/cpp/Extensions.qll @@ -1,4 +1,11 @@ -import cpp +import cpp -abstract class CompilerExtension extends Locatable {} -abstract class CPPCompilerExtension extends CompilerExtension {} \ No newline at end of file +/** + * Common base class for modeling compiler extensions. + */ +abstract class CompilerExtension extends Locatable { } + +/** + * Common base class for modeling compiler extensions in CPP. + */ +abstract class CPPCompilerExtension extends CompilerExtension { } From fa8c05c484fa38d3a5d2a158184fd1796dc4bb96 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Wed, 22 Mar 2023 11:39:33 -0400 Subject: [PATCH 06/13] much typing --- c/common/src/codingstandards/c/Extensions.qll | 24 ++- ...LanguageExtensionsShouldNotBeUsed.expected | 52 ++++- c/misra/test/rules/RULE-1-2/options | 1 + c/misra/test/rules/RULE-1-2/test.c | 179 +++++++++++------- rule_packages/c/Language3.json | 5 +- 5 files changed, 179 insertions(+), 82 deletions(-) create mode 100644 c/misra/test/rules/RULE-1-2/options diff --git a/c/common/src/codingstandards/c/Extensions.qll b/c/common/src/codingstandards/c/Extensions.qll index 7eb7b33c57..018359586e 100644 --- a/c/common/src/codingstandards/c/Extensions.qll +++ b/c/common/src/codingstandards/c/Extensions.qll @@ -80,17 +80,24 @@ class CTerseTernaryExtension extends CCompilerExtension, ConditionalExpr { // Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128 // Reference: https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html#Decimal-Float -class CRealTypeExtensionExtension extends CCompilerExtension, RealNumberType { +class CRealTypeExtensionExtension extends CCompilerExtension, DeclarationEntry { CRealTypeExtensionExtension() { - this instanceof Decimal128Type or - this instanceof Decimal32Type or - this instanceof Decimal64Type or - this instanceof Float128Type + getType() instanceof Decimal128Type or + getType() instanceof Decimal32Type or + getType() instanceof Decimal64Type or + getType() instanceof Float128Type } } // Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128 -class CIntegerTypeExtension extends CCompilerExtension, Int128Type { } +class CIntegerTypeExtension extends CCompilerExtension, DeclarationEntry { + CIntegerTypeExtension() { getType() instanceof Int128Type } +} + +// Reference: https://gcc.gnu.org/onlinedocs/gcc/Long-Long.html#Long-Long +class CLongLongType extends CCompilerExtension, DeclarationEntry { + CLongLongType() { getType() instanceof LongLongType } +} class CZeroLengthArraysExtension extends CCompilerExtension, DeclarationEntry { CZeroLengthArraysExtension() { getType().(ArrayType).getArraySize() = 0 } @@ -103,5 +110,8 @@ class CEmptyStructExtension extends CCompilerExtension, Struct { // Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length class CVariableLengthArraysExtension extends CCompilerExtension, DeclarationEntry { - CVariableLengthArraysExtension() { not getType().(ArrayType).hasArraySize() } + CVariableLengthArraysExtension() { + getType() instanceof ArrayType and + not getType().(ArrayType).hasArraySize() + } } diff --git a/c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.expected b/c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.expected index 2ec1a0ac6c..f9f034c980 100644 --- a/c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.expected +++ b/c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.expected @@ -1 +1,51 @@ -No expected results have yet been specified \ No newline at end of file +| test.c:34:1:34:23 | #define A __BASE_FILE__ | Is a compiler extension and is not portable to other compilers. | +| test.c:35:1:35:23 | #define B __FILE_NAME__ | Is a compiler extension and is not portable to other compilers. | +| test.c:36:1:36:21 | #define C __COUNTER__ | Is a compiler extension and is not portable to other compilers. | +| test.c:37:1:37:27 | #define D __INCLUDE_LEVEL__ | Is a compiler extension and is not portable to other compilers. | +| test.c:39:1:39:19 | #define F __clang__ | Is a compiler extension and is not portable to other compilers. | +| test.c:40:1:40:25 | #define G __clang_major__ | Is a compiler extension and is not portable to other compilers. | +| test.c:41:1:41:25 | #define H __clang_minor__ | Is a compiler extension and is not portable to other compilers. | +| test.c:42:1:42:30 | #define I __clang_patchlevel__ | Is a compiler extension and is not portable to other compilers. | +| test.c:43:1:43:27 | #define J __clang_version__ | Is a compiler extension and is not portable to other compilers. | +| test.c:44:1:44:36 | #define K __clang_literal_encoding__ | Is a compiler extension and is not portable to other compilers. | +| test.c:45:1:45:41 | #define L __clang_wide_literal_encoding__ | Is a compiler extension and is not portable to other compilers. | +| test.c:53:33:53:43 | vector_size | Is a compiler extension and is not portable to other compilers. | +| test.c:54:33:54:47 | vector_size | Is a compiler extension and is not portable to other compilers. | +| test.c:55:37:55:51 | ext_vector_type | Is a compiler extension and is not portable to other compilers. | +| test.c:56:37:56:51 | ext_vector_type | Is a compiler extension and is not portable to other compilers. | +| test.c:61:3:69:4 | (statement expression) | Is a compiler extension and is not portable to other compilers. | +| test.c:96:3:96:18 | call to __builtin_setjmp | Is a compiler extension and is not portable to other compilers. | +| test.c:97:3:97:19 | call to __builtin_longjmp | Is a compiler extension and is not portable to other compilers. | +| test.c:113:11:113:16 | ... ? ... : ... | Is a compiler extension and is not portable to other compilers. | +| test.c:124:12:124:12 | definition of a | Is a compiler extension and is not portable to other compilers. | +| test.c:128:17:128:17 | definition of a | Is a compiler extension and is not portable to other compilers. | +| test.c:165:8:165:15 | definition of contents | Is a compiler extension and is not portable to other compilers. | +| test.c:182:8:182:11 | gf19 | Is a compiler extension and is not portable to other compilers. | +| test.c:214:33:214:35 | declaration of out | Is a compiler extension and is not portable to other compilers. | +| test.c:215:25:215:26 | declaration of in | Is a compiler extension and is not portable to other compilers. | +| test.c:268:16:268:21 | access | Is a compiler extension and is not portable to other compilers. | +| test.c:271:27:271:31 | alias | Is a compiler extension and is not portable to other compilers. | +| test.c:274:23:274:29 | aligned | Is a compiler extension and is not portable to other compilers. | +| test.c:285:25:285:34 | deprecated | Is a compiler extension and is not portable to other compilers. | +| test.c:297:20:297:30 | fallthrough | Is a compiler extension and is not portable to other compilers. | +| test.c:321:3:321:22 | alignof() | Is a compiler extension and is not portable to other compilers. | +| test.c:340:3:340:31 | call to __builtin_extract_return_addr | Is a compiler extension and is not portable to other compilers. | +| test.c:341:3:341:28 | call to __builtin_frob_return_addr | Is a compiler extension and is not portable to other compilers. | +| test.c:342:3:342:25 | call to __builtin_frame_address | Is a compiler extension and is not portable to other compilers. | +| test.c:363:3:363:22 | call to __sync_fetch_and_add_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:364:3:364:22 | call to __sync_fetch_and_sub_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:365:3:365:21 | call to __sync_fetch_and_or_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:366:3:366:22 | call to __sync_fetch_and_and_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:367:3:367:22 | call to __sync_fetch_and_xor_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:368:3:368:23 | call to __sync_fetch_and_nand_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:369:3:369:22 | call to __sync_add_and_fetch_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:370:3:370:22 | call to __sync_sub_and_fetch_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:371:3:371:21 | call to __sync_or_and_fetch_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:372:3:372:22 | call to __sync_and_and_fetch_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:373:3:373:22 | call to __sync_xor_and_fetch_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:374:3:374:23 | call to __sync_nand_and_fetch_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:376:3:376:30 | call to __sync_bool_compare_and_swap_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:377:3:377:29 | call to __sync_val_compare_and_swap_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:378:3:378:26 | call to __sync_lock_test_and_set_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:379:3:379:21 | call to __sync_lock_release_4 | Is a compiler extension and is not portable to other compilers. | +| test.c:407:3:407:18 | call to __builtin_alloca | Is a compiler extension and is not portable to other compilers. | diff --git a/c/misra/test/rules/RULE-1-2/options b/c/misra/test/rules/RULE-1-2/options new file mode 100644 index 0000000000..ea7b68755d --- /dev/null +++ b/c/misra/test/rules/RULE-1-2/options @@ -0,0 +1 @@ +semmle-extractor-options:--clang -fhonor-infinity -std=c11 --edg --diag_error=implicit_func_decl -nostdinc -I../../../../common/test/includes/standard-library diff --git a/c/misra/test/rules/RULE-1-2/test.c b/c/misra/test/rules/RULE-1-2/test.c index 435f366ff8..367570f7e7 100644 --- a/c/misra/test/rules/RULE-1-2/test.c +++ b/c/misra/test/rules/RULE-1-2/test.c @@ -1,7 +1,3 @@ -// semmle-extractor-options:--clang -fhonor-infinity -std=c11 --edg --diag_error=implicit_func_decl -nostdinc -I../../../../common/test/includes/standard-library - -// do it on a translation unit -- flag first line - #include #include // Note: Clang aims to support both clang and gcc extensions. @@ -9,28 +5,29 @@ // - 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 +// 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 +#ifdef __has_constexpr_builtin // NON_COMPLIANT[FALSE_NEGATIVE] #endif -#ifdef __has_feature // NON_COMPLIANT +#ifdef __has_feature // NON_COMPLIANT[FALSE_NEGATIVE] #endif -#ifdef __has_extension // NON_COMPLIANT +#ifdef __has_extension // NON_COMPLIANT[FALSE_NEGATIVE] #endif -#ifdef __has_c_attribute // NON_COMPLIANT +#ifdef __has_c_attribute // NON_COMPLIANT[FALSE_NEGATIVE] #endif -#ifdef __has_attribute // NON_COMPLIANT +#ifdef __has_attribute // NON_COMPLIANT[FALSE_NEGATIVE] #endif -#ifdef __has_declspec_attribute // NON_COMPLIANT +#ifdef __has_declspec_attribute // NON_COMPLIANT[FALSE_NEGATIVE] #endif -#ifdef __is_identifier // NON_COMPLIANT +#ifdef __is_identifier // NON_COMPLIANT[FALSE_NEGATIVE] #endif -#ifdef __has_include // NON_COMPLIANT +#ifdef __has_include // NON_COMPLIANT[FALSE_NEGATIVE] #endif -#ifdef __has_include_next // NON_COMPLIANT +#ifdef __has_include_next // NON_COMPLIANT[FALSE_NEGATIVE] #endif -#ifdef __has_warning // NON_COMPLIANT +#ifdef __has_warning // NON_COMPLIANT[FALSE_NEGATIVE] #endif // Reference: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros @@ -51,18 +48,19 @@ // 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 +// 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 - +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 +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs void gf1() { ({ // NON_COMPLIANT int y = 1; - int z; + int z; if (y > 0) z = y; else @@ -73,36 +71,41 @@ void gf1() { // 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 + // __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 +// 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 +// 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 +// 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 +// 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] + //__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 @@ -115,7 +118,8 @@ void gf8() { typeof(int *); // NON_COMPLIANT[FALSE_NEGATIVE] } -// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128 +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128 void gf9() { __int128 a; // NON_COMPLIANT } @@ -132,8 +136,10 @@ void gf11() { 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 +// 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] @@ -144,8 +150,9 @@ void gf13() { // 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] + // 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 @@ -158,35 +165,42 @@ void gf16() { char contents[0]; // NON_COMPLIANT } -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html#Named-Address-Spaces +// 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 + // 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] + // long _Fract; // NON_COMPLIANT[FALSE_NEGATIVE] } struct gf19 {}; // NON_COMPLIANT -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length +// 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 + // 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 +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html#Variadic-Macros #define gf21(format, args...) \ - printf(format, args) // NON_COMPLIANT // NON_COMPLIANT[FALSE_NEGATIVE] -- note the issue here is explicitly - // naming the arguments. + 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 +// 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 +"b" // NON_COMPLIANT[FALSE_NEGATIVE] - additional spaces after a backslash -- + // stripped by extractor #define gf22a \ "a" \ "b" // COMPLIANT @@ -195,8 +209,10 @@ 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], const double in[N][M]); // NON_COMPLIANT[FALSE_NEGATIVE] +// 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]; @@ -205,20 +221,23 @@ void gf25() { // to the element type of the array and not the array itself } -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html#Compound-Literals +// 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 + 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. + // case: 0 ... 5: // NON_COMPLIANT[FALSE_NEGATIVE] - Not supported in + // clang. // ;; // break; // default: @@ -232,7 +251,8 @@ union gf29u { double j; }; -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Cast-to-Union.html#Cast-to-Union +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Cast-to-Union.html#Cast-to-Union void gf29() { int x; int y; @@ -241,10 +261,12 @@ void gf29() { 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. +// 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. @@ -266,7 +288,8 @@ enum gf34 { void gf35() { int x; - // __attribute__((assume(x == 42))); // NON_COMPLIANT[FALSE_NEGATIVE] - Not supported in clang + // __attribute__((assume(x == 42))); // NON_COMPLIANT[FALSE_NEGATIVE] - Not + // supported in clang switch (x) { case 1: @@ -282,7 +305,8 @@ void gf37() { int a$1; // NON_COMPLIANT[FALSE_NEGATIVE] } -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Character-Escapes.html#Character-Escapes +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Character-Escapes.html#Character-Escapes void gf38() { const char *c = "test\e"; // NON_COMPLIANT[FALSE_NEGATIVE] } @@ -297,21 +321,25 @@ void gf39() { __alignof__(gf39v.x); // NON_COMPLIANT } -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Incomplete-Enums.html#Incomplete-Enums +// 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 +// 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] + 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 +// 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 + __builtin_frob_return_addr(0); // NON_COMPLIANT + __builtin_frame_address(0); // NON_COMPLIANT } struct gf43s { @@ -328,7 +356,8 @@ struct gf44s { char y; } gf44v; -// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins +// 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 @@ -350,7 +379,8 @@ void gf44() { __sync_lock_release(&i, 0); } -// Reference: https://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html#Binary-constants +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html#Binary-constants void gf45() { int i = 0b101010; // NON_COMPLIANT[FALSE_NEGATIVE] } @@ -358,7 +388,8 @@ void gf45() { // 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 +// Reference: +// https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html#Unnamed-Fields void gf47() { // NON_COMPLIANT in versions < C11. struct { int a; @@ -370,7 +401,9 @@ void gf47() { // NON_COMPLIANT in versions < C11. } 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.) +// 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/rule_packages/c/Language3.json b/rule_packages/c/Language3.json index 1c537fa667..7c26ce920c 100644 --- a/rule_packages/c/Language3.json +++ b/rule_packages/c/Language3.json @@ -15,7 +15,10 @@ "tags": [ "maintainability", "readability" - ] + ], + "implementation_scope": { + "description": "This implementation attempts to cover a broad section of the compiler specific extensions documented in: https://clang.llvm.org/docs/LanguageExtensions.html and https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html but is not comprehensive. The following topics are addressed in this query: Builtin macros, Variable Attributes, Function Attributes, Statement Expressions, Non-Local Gotos, Conditionals, Extended Integer / Numeric Types, Zero Length Structures, Zero Length Arrays, Variable Length Arrays, Case Attributes, Alignment, __sync and __fetch builtins. Other topics listed in the extension references are not covered by this query." + } } ], "title": "Language extensions should not be used" From 192ff575411019f40a3e8b91ec6df61dba066d0f Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Wed, 22 Mar 2023 11:48:35 -0400 Subject: [PATCH 07/13] update --- .../RULE-1-2/LanguageExtensionsShouldNotBeUsed.qlref | 1 + .../src/codingstandards/cpp/exclusions/c/Language3.qll | 8 +++++--- .../src/codingstandards/cpp/exclusions/c/RuleMetadata.qll | 3 +++ 3 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.qlref diff --git a/c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.qlref b/c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.qlref new file mode 100644 index 0000000000..965c95be2c --- /dev/null +++ b/c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.qlref @@ -0,0 +1 @@ +rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Language3.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Language3.qll index fe057f3b00..836f8f7010 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Language3.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Language3.qll @@ -7,14 +7,15 @@ newtype Language3Query = TLanguageExtensionsShouldNotBeUsedQuery() or TOccurrenceOfUndefinedBehaviorQuery() -predicate isLanguage3QueryMetadata(Query query, string queryId, string ruleId) { +predicate isLanguage3QueryMetadata(Query query, string queryId, string ruleId, string category) { query = // `Query` instance for the `languageExtensionsShouldNotBeUsed` query Language3Package::languageExtensionsShouldNotBeUsedQuery() and queryId = // `@id` for the `languageExtensionsShouldNotBeUsed` query "c/misra/language-extensions-should-not-be-used" and - ruleId = "RULE-1-2" + ruleId = "RULE-1-2" and + category = "advisory" or query = // `Query` instance for the `occurrenceOfUndefinedBehavior` query @@ -22,7 +23,8 @@ predicate isLanguage3QueryMetadata(Query query, string queryId, string ruleId) { queryId = // `@id` for the `occurrenceOfUndefinedBehavior` query "c/misra/occurrence-of-undefined-behavior" and - ruleId = "RULE-1-3" + ruleId = "RULE-1-3" and + category = "required" } module Language3Package { diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll index 9dfb52fb84..4a25016843 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll @@ -33,6 +33,7 @@ import IO4 import InvalidMemory1 import Language1 import Language2 +import Language3 import Memory1 import Misc import Pointers1 @@ -84,6 +85,7 @@ newtype TCQuery = TInvalidMemory1PackageQuery(InvalidMemory1Query q) or TLanguage1PackageQuery(Language1Query q) or TLanguage2PackageQuery(Language2Query q) or + TLanguage3PackageQuery(Language3Query q) or TMemory1PackageQuery(Memory1Query q) or TMiscPackageQuery(MiscQuery q) or TPointers1PackageQuery(Pointers1Query q) or @@ -135,6 +137,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat isInvalidMemory1QueryMetadata(query, queryId, ruleId, category) or isLanguage1QueryMetadata(query, queryId, ruleId, category) or isLanguage2QueryMetadata(query, queryId, ruleId, category) or + isLanguage3QueryMetadata(query, queryId, ruleId, category) or isMemory1QueryMetadata(query, queryId, ruleId, category) or isMiscQueryMetadata(query, queryId, ruleId, category) or isPointers1QueryMetadata(query, queryId, ruleId, category) or From 73602b43338403718a1ae963f08866fbe5993e52 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Wed, 22 Mar 2023 11:55:40 -0400 Subject: [PATCH 08/13] Delete settings.json --- .vscode/settings.json | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index c6399d9b5e..0000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "files.associations": { - "atomic": "c" - } -} \ No newline at end of file From c5821907fe313ac7689072581bcc193f5d1508d5 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Wed, 22 Mar 2023 11:56:02 -0400 Subject: [PATCH 09/13] Delete MatrixTestReport-gcc-cpp-2023-02-13_18-12-16.csv --- MatrixTestReport-gcc-cpp-2023-02-13_18-12-16.csv | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 MatrixTestReport-gcc-cpp-2023-02-13_18-12-16.csv diff --git a/MatrixTestReport-gcc-cpp-2023-02-13_18-12-16.csv b/MatrixTestReport-gcc-cpp-2023-02-13_18-12-16.csv deleted file mode 100644 index 57c94fcdd3..0000000000 --- a/MatrixTestReport-gcc-cpp-2023-02-13_18-12-16.csv +++ /dev/null @@ -1,11 +0,0 @@ -"COMPILE_ERROR_OUTPUT","TEST_PASS","COMPILE_PASS","SUITE","TEST_DIFFERENCE","PACKAGE","RULE","QUERY" -"","True","True","AUTOSAR","","Toolchain","A1-1-2","CompilerWarningLevelNotInCompliance" -"","True","True","AUTOSAR","","Toolchain","A1-1-2","CompilerWarningLevelNotInCompliance" -"","True","True","AUTOSAR","","Toolchain","A1-1-2","CompilerWarningLevelNotInCompliance" -"","False","True","AUTOSAR","--- expected -+++ actual -@@ -1,1 +1,1 @@ --| test.cpp:0:0:0:0 | test.cpp | No warning-level options were used in the compilation of 'test.cpp'. | -+ -[1/1 eval 12.4s] FAILED(RESULT) /mnt/c/Projects/codeql-coding-standards/cpp/autosar/test/rules/A1-1-2.3/CompilerWarningLevelNotInCompliance.qlref -","Toolchain","A1-1-2","CompilerWarningLevelNotInCompliance" From 4148a57dd419347d05dd6b46868b85087811e4e3 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Wed, 22 Mar 2023 11:56:12 -0400 Subject: [PATCH 10/13] Delete MatrixTestReport-gcc-cpp-2023-02-13_18-18-12.csv --- MatrixTestReport-gcc-cpp-2023-02-13_18-18-12.csv | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 MatrixTestReport-gcc-cpp-2023-02-13_18-18-12.csv diff --git a/MatrixTestReport-gcc-cpp-2023-02-13_18-18-12.csv b/MatrixTestReport-gcc-cpp-2023-02-13_18-18-12.csv deleted file mode 100644 index 3c4f1fc8a8..0000000000 --- a/MatrixTestReport-gcc-cpp-2023-02-13_18-18-12.csv +++ /dev/null @@ -1,11 +0,0 @@ -"TEST_DIFFERENCE","TEST_PASS","PACKAGE","SUITE","QUERY","RULE","COMPILE_ERROR_OUTPUT","COMPILE_PASS" -"","True","Toolchain","AUTOSAR","CompilerWarningLevelNotInCompliance","A1-1-2","","True" -"","True","Toolchain","AUTOSAR","CompilerWarningLevelNotInCompliance","A1-1-2","","True" -"","True","Toolchain","AUTOSAR","CompilerWarningLevelNotInCompliance","A1-1-2","","True" -"--- expected -+++ actual -@@ -1,1 +1,1 @@ --| test.cpp:0:0:0:0 | test.cpp | No warning-level options were used in the compilation of 'test.cpp'. | -+ -[1/1 eval 13.1s] FAILED(RESULT) /mnt/c/Projects/codeql-coding-standards/cpp/autosar/test/rules/A1-1-2.3/CompilerWarningLevelNotInCompliance.qlref -","False","Toolchain","AUTOSAR","CompilerWarningLevelNotInCompliance","A1-1-2","","True" From f2aeea5405877e99e7ed766fd166a2c69d5d760f Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Wed, 22 Mar 2023 17:06:42 -0400 Subject: [PATCH 11/13] 1-3 --- .../codingstandards/c/UndefinedBehavior.qll | 28 +++++++++++++++++++ .../RULE-1-3/OccurrenceOfUndefinedBehavior.ql | 8 +++--- .../OccurrenceOfUndefinedBehavior.expected | 6 +++- c/misra/test/rules/RULE-1-3/test.c | 25 +++++++++++++++++ .../codingstandards/cpp/UndefinedBehavior.qll | 6 ++++ rule_packages/c/Language3.json | 5 +++- 6 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 c/common/src/codingstandards/c/UndefinedBehavior.qll create mode 100644 c/misra/test/rules/RULE-1-3/test.c create mode 100644 cpp/common/src/codingstandards/cpp/UndefinedBehavior.qll diff --git a/c/common/src/codingstandards/c/UndefinedBehavior.qll b/c/common/src/codingstandards/c/UndefinedBehavior.qll new file mode 100644 index 0000000000..49b1ee3e5e --- /dev/null +++ b/c/common/src/codingstandards/c/UndefinedBehavior.qll @@ -0,0 +1,28 @@ +import cpp +import codingstandards.cpp.UndefinedBehavior + +/** + * Library for modeling undefined behavior. + */ +abstract class CUndefinedBehavior extends UndefinedBehavior { } + +class C99MainFunction extends Function { + C99MainFunction() { + this.getNumberOfParameters() = 2 and + this.getType() instanceof IntType and + this.getParameter(0).getType() instanceof IntType and + this.getParameter(1).getType().(PointerType).getBaseType().(PointerType).getBaseType() + instanceof CharType + or + this.getNumberOfParameters() = 0 and + this.getType() instanceof VoidType + } +} + +class CUndefinedMainDefinition extends CUndefinedBehavior, Function { + CUndefinedMainDefinition() { + // for testing purposes, we use the prefix ____codeql_coding_standards` + (this.getName() = "main" or this.getName().indexOf("____codeql_coding_standards") = 0) and + not this instanceof C99MainFunction + } +} diff --git a/c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql b/c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql index a00d207d65..f6b295bd32 100644 --- a/c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql +++ b/c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql @@ -13,8 +13,8 @@ import cpp import codingstandards.c.misra +import codingstandards.c.UndefinedBehavior -from -where - not isExcluded(x, Language3Package::occurrenceOfUndefinedBehaviorQuery()) and -select +from CUndefinedBehavior c +where not isExcluded(c, Language3Package::occurrenceOfUndefinedBehaviorQuery()) +select c, "May result in undefined behavior." diff --git a/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.expected b/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.expected index 2ec1a0ac6c..68216d500f 100644 --- a/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.expected +++ b/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.expected @@ -1 +1,5 @@ -No expected results have yet been specified \ No newline at end of file +| test.c:8:6:8:35 | ____codeql_coding_standards_m2 | May result in undefined behavior. | +| test.c:11:5:11:34 | ____codeql_coding_standards_m3 | May result in undefined behavior. | +| test.c:15:5:15:34 | ____codeql_coding_standards_m4 | May result in undefined behavior. | +| test.c:19:5:19:34 | ____codeql_coding_standards_m5 | May result in undefined behavior. | +| test.c:23:5:23:34 | ____codeql_coding_standards_m6 | May result in undefined behavior. | diff --git a/c/misra/test/rules/RULE-1-3/test.c b/c/misra/test/rules/RULE-1-3/test.c new file mode 100644 index 0000000000..190cff4000 --- /dev/null +++ b/c/misra/test/rules/RULE-1-3/test.c @@ -0,0 +1,25 @@ +void main(void) { // COMPLIANT +} + +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; +} diff --git a/cpp/common/src/codingstandards/cpp/UndefinedBehavior.qll b/cpp/common/src/codingstandards/cpp/UndefinedBehavior.qll new file mode 100644 index 0000000000..425ab32aec --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/UndefinedBehavior.qll @@ -0,0 +1,6 @@ +import cpp +/** + * Library for modeling undefined behavior. + */ +abstract class UndefinedBehavior extends Locatable {} +abstract class CPPUndefinedBehavior extends UndefinedBehavior {} diff --git a/rule_packages/c/Language3.json b/rule_packages/c/Language3.json index 7c26ce920c..e659debf1b 100644 --- a/rule_packages/c/Language3.json +++ b/rule_packages/c/Language3.json @@ -38,7 +38,10 @@ "tags": [ "maintainability", "readability" - ] + ], + "implementation_scope": { + "description": "This implementation only considers alternate forms of `main` and the undefined behavior that results. Additional cases from Appendix J of the C99 standard are not currently considered." + } } ], "title": "There shall be no occurrence of undefined or critical unspecified behavior" From 4b6a01d79d98dbde87399d085d4500a112545e52 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 23 Mar 2023 13:42:03 -0400 Subject: [PATCH 12/13] format fix --- cpp/common/src/codingstandards/cpp/UndefinedBehavior.qll | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/UndefinedBehavior.qll b/cpp/common/src/codingstandards/cpp/UndefinedBehavior.qll index 425ab32aec..85e2f64612 100644 --- a/cpp/common/src/codingstandards/cpp/UndefinedBehavior.qll +++ b/cpp/common/src/codingstandards/cpp/UndefinedBehavior.qll @@ -1,6 +1,8 @@ -import cpp +import cpp + /** * Library for modeling undefined behavior. */ -abstract class UndefinedBehavior extends Locatable {} -abstract class CPPUndefinedBehavior extends UndefinedBehavior {} +abstract class UndefinedBehavior extends Locatable { } + +abstract class CPPUndefinedBehavior extends UndefinedBehavior { } From a293557c7c89f000a6ffc26d72a6b5108e559438 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 23 Mar 2023 16:32:34 -0400 Subject: [PATCH 13/13] note --- rule_packages/c/Language3.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rule_packages/c/Language3.json b/rule_packages/c/Language3.json index e659debf1b..d48444a4ab 100644 --- a/rule_packages/c/Language3.json +++ b/rule_packages/c/Language3.json @@ -40,7 +40,7 @@ "readability" ], "implementation_scope": { - "description": "This implementation only considers alternate forms of `main` and the undefined behavior that results. Additional cases from Appendix J of the C99 standard are not currently considered." + "description": "This implementation only considers alternate forms of `main` and the undefined behavior that results. Note that the current version of CodeQL is not able to detect this issue if a function is named `main` since it will assume the return type and formal parameters. Additional cases from Appendix J of the C99 standard are not currently considered." } } ],