Dereference of NULL error according to GCC's -fanalyzer
Nostress767 opened this issue · 0 comments
Nostress767 commented
OS and version: Linux archlinux 6.8.1-arch1-1 #1 SMP PREEMPT_DYNAMIC Sat, 16 Mar 2024 17:15:35 +0000 x86_64 GNU/Linux
Compiler version: gcc (GCC) 13.2.1 20230801
Release or commit: bf945f1
I run a small project using the flags "-fanalyzer -Werror -Wall -Wpedantic". When I tried adding GLFW to it, GCC's static analyzer flared up and gave me some errors. I'm not sure what they affect or how they interact with other things, but I tried replicating the issue from the latest commit with a minimal code example just to make sure and they still popped up.
I created the Makefile and main.c in the root directory of this project and ran make
Makefile:
# Disable built-in rules and variables
MAKEFLAGS += --no-builtin-rules
MAKEFLAGS += --no-builtin-variables
CC := gcc
CPPFLAGS := -Iinclude -D_GLFW_X11
CFLAGS := -fanalyzer -c
LDFLAGS := -lm
EXE := Example
OBJS := main.o
OBJS += src/context.o src/init.o src/input.o src/monitor.o src/platform.o src/window.o
OBJS += src/posix_module.o src/posix_thread.o src/posix_time.o src/posix_poll.o
OBJS += src/egl_context.o src/glx_context.o src/osmesa_context.o
OBJS += src/linux_joystick.o src/xkb_unicode.o
OBJS += src/vulkan.o
OBJS += src/x11_window.o src/x11_init.o src/x11_monitor.o
OBJS += src/null_init.o src/null_joystick.o src/null_monitor.o src/null_window.o
all: clean $(EXE)
$(OBJS) : %.o : %.c
$(CC) $(CPPFLAGS) $(CFLAGS) $< -o $@
$(EXE): $(OBJS)
$(CC) -o $@ $(OBJS) $(LDFLAGS)
clean:
rm -f src/*.o $(EXE)
main.c:
#include "GLFW/glfw3.h"
#include <stdbool.h>
int main(int argc, char* argv[])
{
glfwInit();
GLFWwindow *window = glfwCreateWindow(800, 600, "Test", NULL, NULL);
glfwMakeContextCurrent(window);
while(!glfwWindowShouldClose(window)){
glfwPollEvents();
if(glfwGetKey(window, GLFW_KEY_P) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
glfwSwapBuffers(window);
}
glfwTerminate();
}
Build log:
rm -f src/*.o Example
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/context.c -o src/context.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/init.c -o src/init.o
src/init.c: In function ‘_glfwInputError’:
src/init.c:366:25: warning: dereference of NULL ‘error’ [CWE-476] [-Wanalyzer-null-dereference]
366 | error->next = _glfw.errorListHead;
| ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
‘_glfwInputError’: events 1-6
|
| 309 | void _glfwInputError(int code, const char* format, ...)
| | ^~~~~~~~~~~~~~~
| | |
| | (1) entry to ‘_glfwInputError’
|......
| 358 | if (_glfw.initialized)
| | ~
| | |
| | (2) following ‘true’ branch...
| 359 | {
| 360 | error = _glfwPlatformGetTls(&_glfw.errorSlot);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
| 361 | if (!error)
| | ~
| | |
| | (4) following ‘true’ branch (when ‘error’ is NULL)...
| 362 | {
| 363 | error = _glfw_calloc(1, sizeof(_GLFWerror));
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (5) ...to here
| | (6) calling ‘_glfw_calloc’ from ‘_glfwInputError’
|
+--> ‘_glfw_calloc’: events 7-12
|
| 249 | void* _glfw_calloc(size_t count, size_t size)
| | ^~~~~~~~~~~~
| | |
| | (7) entry to ‘_glfw_calloc’
| 250 | {
| 251 | if (count && size)
| | ~
| | |
| | (8) following ‘true’ branch...
|......
| 255 | if (count > SIZE_MAX / size)
| | ~~~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (9) ...to here
| | (10) following ‘true’ branch...
| 256 | {
| 257 | _glfwInputError(GLFW_INVALID_VALUE, "Allocation size overflow");
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (11) ...to here
| | (12) calling ‘_glfwInputError’ from ‘_glfw_calloc’
|
+--> ‘_glfwInputError’: events 13-19
|
| 309 | void _glfwInputError(int code, const char* format, ...)
| | ^~~~~~~~~~~~~~~
| | |
| | (13) entry to ‘_glfwInputError’
|......
| 314 | if (format)
| | ~
| | |
| | (14) following ‘true’ branch (when ‘format’ is non-NULL)...
|......
| 318 | va_start(vl, format);
| | ~~~~~~~~
| | |
| | (15) ...to here
|......
| 358 | if (_glfw.initialized)
| | ~
| | |
| | (16) following ‘false’ branch...
|......
| 372 | error = &_glfwMainThreadError;
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (17) ...to here
|......
| 377 | if (_glfwErrorCallback)
| | ~
| | |
| | (18) following ‘false’ branch...
| 378 | _glfwErrorCallback(code, description);
| 379 | }
| | ~
| | |
| | (19) ...to here
|
<------+
|
‘_glfw_calloc’: event 20
|
| 257 | _glfwInputError(GLFW_INVALID_VALUE, "Allocation size overflow");
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (20) returning to ‘_glfw_calloc’ from ‘_glfwInputError’
|
‘_glfw_calloc’: event 21
|
| 258 | return NULL;
| | ^~~~
| | |
| | (21) ‘0’ is NULL
|
<------+
|
‘_glfwInputError’: events 22-24
|
| 363 | error = _glfw_calloc(1, sizeof(_GLFWerror));
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (22) returning to ‘_glfwInputError’ from ‘_glfw_calloc’
|......
| 366 | error->next = _glfw.errorListHead;
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (24) dereference of NULL ‘error’
| 367 | _glfw.errorListHead = error;
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (23) ‘error’ is NULL
|
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/input.c -o src/input.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/monitor.c -o src/monitor.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/platform.c -o src/platform.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/window.c -o src/window.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/posix_module.c -o src/posix_module.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/posix_thread.c -o src/posix_thread.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/posix_time.c -o src/posix_time.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/posix_poll.c -o src/posix_poll.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/egl_context.c -o src/egl_context.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/glx_context.c -o src/glx_context.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/osmesa_context.c -o src/osmesa_context.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/linux_joystick.c -o src/linux_joystick.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/xkb_unicode.c -o src/xkb_unicode.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/vulkan.c -o src/vulkan.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/x11_window.c -o src/x11_window.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/x11_init.c -o src/x11_init.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/x11_monitor.c -o src/x11_monitor.o
src/x11_monitor.c: In function ‘modeIsGood’:
src/x11_monitor.c:42:15: warning: dereference of NULL ‘mi’ [CWE-476] [-Wanalyzer-null-dereference]
42 | return (mi->modeFlags & RR_Interlace) == 0;
| ~~^~~~~~~~~~~
‘_glfwGetVideoModesX11’: events 1-2
|
| 442 | GLFWvidmode* _glfwGetVideoModesX11(_GLFWmonitor* monitor, int* count)
| | ^~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) entry to ‘_glfwGetVideoModesX11’
|......
| 448 | if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
| | ~
| | |
| | (2) following ‘true’ branch...
|
‘_glfwGetVideoModesX11’: event 3
|
|src/x11_platform.h:329:53:
| 329 | #define XRRGetScreenResourcesCurrent _glfw.x11.randr.GetScreenResourcesCurrent
| | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
src/x11_monitor.c:451:13: note: in expansion of macro ‘XRRGetScreenResourcesCurrent’
| 451 | XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
‘_glfwGetVideoModesX11’: events 4-6
|
| 457 | for (int i = 0; i < oi->nmode; i++)
| | ~~^~~~~~~~~~~
| | |
| | (4) following ‘true’ branch...
| 458 | {
| 459 | const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (5) ...to here
| | (6) calling ‘getModeInfo’ from ‘_glfwGetVideoModesX11’
|
+--> ‘getModeInfo’: event 7
|
| 57 | static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id)
| | ^~~~~~~~~~~
| | |
| | (7) entry to ‘getModeInfo’
|
‘getModeInfo’: event 8
|
| 65 | return NULL;
| | ^~~~
| | |
| | (8) ‘0’ is NULL
|
<------+
|
‘_glfwGetVideoModesX11’: events 9-10
|
| 459 | const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (9) return of NULL to ‘_glfwGetVideoModesX11’ from ‘getModeInfo’
| 460 | if (!modeIsGood(mi))
| | ~~~~~~~~~~~~~~
| | |
| | (10) calling ‘modeIsGood’ from ‘_glfwGetVideoModesX11’
|
+--> ‘modeIsGood’: events 11-12
|
| 40 | static GLFWbool modeIsGood(const XRRModeInfo* mi)
| | ^~~~~~~~~~
| | |
| | (11) entry to ‘modeIsGood’
| 41 | {
| 42 | return (mi->modeFlags & RR_Interlace) == 0;
| | ~~~~~~~~~~~~~
| | |
| | (12) dereference of NULL ‘mi’
|
src/x11_monitor.c: In function ‘_glfwPollMonitorsX11’:
src/x11_monitor.c:180:31: warning: dereference of NULL ‘screens’ [CWE-476] [-Wanalyzer-null-dereference]
180 | if (screens[j].x_org == ci->x &&
| ~~~~~~~~~~^~~~~~
‘_glfwPollMonitorsX11’: events 1-8
|
| 103 | if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
| | ^
| | |
| | (1) following ‘true’ branch...
| 104 | {
| 105 | int disconnectedCount, screenCount = 0;
| | ~~~~~~~~~~~
| | |
| | (2) ...to here
| 106 | _GLFWmonitor** disconnected = NULL;
| 107 | XineramaScreenInfo* screens = NULL;
| | ~~~~~~~
| | |
| | (3) ‘screens’ is NULL
|......
| 113 | if (_glfw.x11.xinerama.available)
| | ~
| | |
| | (4) following ‘false’ branch...
|......
| 116 | disconnectedCount = _glfw.monitorCount;
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (5) ...to here
| 117 | if (disconnectedCount)
| | ~
| | |
| | (6) following ‘false’ branch (when ‘disconnectedCount == 0’)...
|......
| 125 | for (int i = 0; i < sr->noutput; i++)
| | ~ ~~~~~~~~~~~~~~~
| | | |
| | | (8) following ‘true’ branch...
| | (7) ...to here
|
‘_glfwPollMonitorsX11’: event 9
|
|src/x11_platform.h:327:41:
| 327 | #define XRRGetOutputInfo _glfw.x11.randr.GetOutputInfo
| | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
| | |
| | (9) ...to here
src/x11_monitor.c:129:33: note: in expansion of macro ‘XRRGetOutputInfo’
| 129 | XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
| | ^~~~~~~~~~~~~~~~
|
‘_glfwPollMonitorsX11’: events 10-14
|
| 130 | if (oi->connection != RR_Connected || oi->crtc == None)
| | ^
| | |
| | (10) following ‘false’ branch...
|......
| 136 | for (j = 0; j < disconnectedCount; j++)
| | ~~~~~ ~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (12) following ‘false’ branch (when ‘j >= disconnectedCount’)...
| | (11) ...to here
|......
| 146 | if (j < disconnectedCount)
| | ~
| | |
| | (13) ...to here
| | (14) following ‘false’ branch (when ‘j >= disconnectedCount’)...
|
‘_glfwPollMonitorsX11’: event 15
|
|src/x11_platform.h:326:39:
| 326 | #define XRRGetCrtcInfo _glfw.x11.randr.GetCrtcInfo
| | ~~~~~~~~~~~~~~~^~~~~~~~~~~~
| | |
| | (15) ...to here
src/x11_monitor.c:152:31: note: in expansion of macro ‘XRRGetCrtcInfo’
| 152 | XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
| | ^~~~~~~~~~~~~~
|
‘_glfwPollMonitorsX11’: events 16-19
|
| 178 | for (j = 0; j < screenCount; j++)
| | ~~^~~~~~~~~~~~~
| | |
| | (16) following ‘true’ branch...
| 179 | {
| 180 | if (screens[j].x_org == ci->x &&
| | ~~~~~~~~~~~~~~~~
| | | |
| | | (19) dereference of NULL ‘screens + (long unsigned int)j * 12’
| | (17) ...to here
| | (18) ‘screens’ is NULL
|
src/x11_monitor.c: In function ‘_glfwGetMonitorWorkareaX11’:
src/x11_monitor.c:367:28: warning: dereference of NULL ‘mi’ [CWE-476] [-Wanalyzer-null-dereference]
367 | areaWidth = mi->height;
| ~~^~~~~~~~
‘_glfwGetMonitorWorkareaX11’: events 1-2
|
| 348 | void _glfwGetMonitorWorkareaX11(_GLFWmonitor* monitor,
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) entry to ‘_glfwGetMonitorWorkareaX11’
|......
| 354 | if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
| | ~
| | |
| | (2) following ‘true’ branch...
|
‘_glfwGetMonitorWorkareaX11’: event 3
|
|src/x11_platform.h:329:53:
| 329 | #define XRRGetScreenResourcesCurrent _glfw.x11.randr.GetScreenResourcesCurrent
| | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
src/x11_monitor.c:357:13: note: in expansion of macro ‘XRRGetScreenResourcesCurrent’
| 357 | XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
‘_glfwGetMonitorWorkareaX11’: event 4
|
| 363 | const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (4) calling ‘getModeInfo’ from ‘_glfwGetMonitorWorkareaX11’
|
+--> ‘getModeInfo’: event 5
|
| 57 | static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id)
| | ^~~~~~~~~~~
| | |
| | (5) entry to ‘getModeInfo’
|
‘getModeInfo’: event 6
|
| 65 | return NULL;
| | ^~~~
| | |
| | (6) ‘0’ is NULL
|
<------+
|
‘_glfwGetMonitorWorkareaX11’: events 7-8
|
| 363 | const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (7) return of NULL to ‘_glfwGetMonitorWorkareaX11’ from ‘getModeInfo’
|......
| 367 | areaWidth = mi->height;
| | ~~~~~~~~~~
| | |
| | (8) dereference of NULL ‘mi’
|
src/x11_monitor.c:372:28: warning: dereference of NULL ‘mi’ [CWE-476] [-Wanalyzer-null-dereference]
372 | areaWidth = mi->width;
| ~~^~~~~~~
‘_glfwGetMonitorWorkareaX11’: events 1-2
|
| 348 | void _glfwGetMonitorWorkareaX11(_GLFWmonitor* monitor,
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) entry to ‘_glfwGetMonitorWorkareaX11’
|......
| 354 | if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
| | ~
| | |
| | (2) following ‘true’ branch...
|
‘_glfwGetMonitorWorkareaX11’: event 3
|
|src/x11_platform.h:329:53:
| 329 | #define XRRGetScreenResourcesCurrent _glfw.x11.randr.GetScreenResourcesCurrent
| | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (3) ...to here
src/x11_monitor.c:357:13: note: in expansion of macro ‘XRRGetScreenResourcesCurrent’
| 357 | XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
‘_glfwGetMonitorWorkareaX11’: event 4
|
| 363 | const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (4) calling ‘getModeInfo’ from ‘_glfwGetMonitorWorkareaX11’
|
+--> ‘getModeInfo’: event 5
|
| 57 | static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id)
| | ^~~~~~~~~~~
| | |
| | (5) entry to ‘getModeInfo’
|
‘getModeInfo’: event 6
|
| 65 | return NULL;
| | ^~~~
| | |
| | (6) ‘0’ is NULL
|
<------+
|
‘_glfwGetMonitorWorkareaX11’: events 7-10
|
| 363 | const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (7) return of NULL to ‘_glfwGetMonitorWorkareaX11’ from ‘getModeInfo’
| 364 |
| 365 | if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
| | ~
| | |
| | (8) following ‘false’ branch...
|......
| 372 | areaWidth = mi->width;
| | ~~~~~~~~~
| | |
| | (9) ...to here
| | (10) dereference of NULL ‘mi’
|
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/null_init.c -o src/null_init.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/null_joystick.c -o src/null_joystick.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/null_monitor.c -o src/null_monitor.o
gcc -Iinclude -D_GLFW_X11 -fanalyzer -c src/null_window.c -o src/null_window.o
gcc -o Example main.o src/context.o src/init.o src/input.o src/monitor.o src/platform.o src/window.o src/posix_module.o src/posix_thread.o src/posix_time.o src/posix_poll.o src/egl_context.o src/glx_context.o src/osmesa_context.o src/linux_joystick.o src/xkb_unicode.o src/vulkan.o src/x11_window.o src/x11_init.o src/x11_monitor.o src/null_init.o src/null_joystick.o src/null_monitor.o src/null_window.o -lm