Merge pull request #16149 from codeqlhelper/main

C++: Improvements to reduce false alarms
This commit is contained in:
Mathias Vorreiter Pedersen
2024-04-16 15:03:31 +01:00
committed by GitHub
6 changed files with 57 additions and 2 deletions

View File

@@ -31,7 +31,9 @@ predicate useFunc(GlobalVariable v, Function f) {
}
predicate uninitialisedBefore(GlobalVariable v, Function f) {
f.hasGlobalName("main")
f.hasGlobalName("main") and
not initialisedAtDeclaration(v) and
not isStdlibVariable(v)
or
exists(Call call, Function g |
uninitialisedBefore(v, g) and
@@ -98,10 +100,16 @@ predicate callReaches(Call call, ControlFlowNode successor) {
)
}
/** Holds if `v` has an initializer. */
predicate initialisedAtDeclaration(GlobalVariable v) { exists(v.getInitializer()) }
/** Holds if `v` is a global variable that does not need to be initialized. */
predicate isStdlibVariable(GlobalVariable v) { v.hasGlobalName(["stdin", "stdout", "stderr"]) }
from GlobalVariable v, Function f
where
uninitialisedBefore(v, f) and
useFunc(v, f)
select f,
"The variable '" + v.getName() +
"The variable '" + v.getName() + "'" +
" is used in this function but may not be initialized when it is called."

View File

@@ -15,6 +15,8 @@ import cpp
from StackVariable v, ControlFlowNode def, VariableAccess checked, VariableAccess unchecked
where
checked = v.getAnAccess() and
// The check can often be in a macro for handling exception
not checked.isInMacroExpansion() and
dereferenced(checked) and
unchecked = v.getAnAccess() and
dereferenced(unchecked) and

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* The "Global variable may be used before initialization" query (`cpp/global-use-before-init`) no longer raises an alert on global variables that are initialized when they are declared.
* The "Inconsistent null check of pointer" query (`cpp/inconsistent-nullness-testing`) query no longer raises an alert when the guarded check is in a macro expansion.

View File

@@ -0,0 +1 @@
| test.cpp:27:5:27:6 | f1 | The variable 'b' is used in this function but may not be initialized when it is called. |

View File

@@ -0,0 +1 @@
Critical/GlobalUseBeforeInit.ql

View File

@@ -0,0 +1,38 @@
typedef __builtin_va_list va_list;
typedef struct {} FILE;
extern FILE * stdin;
extern FILE * stdout;
extern FILE * stderr;
#define va_start(args, fmt) __builtin_va_start(args,fmt)
#define va_end(args) __builtin_va_end(args);
int vfprintf (FILE *, const char *, va_list);
int a = 1;
int b;
int my_printf(const char * fmt, ...)
{
va_list vl;
int ret;
va_start(vl, fmt);
ret = vfprintf(stdout, fmt, vl);
ret = vfprintf(stderr, fmt, vl);
va_end(vl);
return ret;
}
int f1()
{
my_printf("%d\n", a + 2);
my_printf("%d\n", b + 2); // BAD
return 0;
}
int main()
{
int b = f1();
return 0;
}