Bug Summary

File:root/firefox-clang/gfx/wr/swgl/src/program.h
Warning:line 98, column 8
Excessive padding in 'struct glsl::FragmentShaderImpl' (32 padding bytes, where 0 is optimal). Optimal fields order: swgl_IsPixelDiscarded, gl_FragCoord, gl_FragColor, gl_SecondaryFragColor, init_span_func, run_func, skip_func, init_span_w_func, run_w_func, skip_w_func, draw_span_RGBA8_func, draw_span_R8_func, swgl_OutRGBA8, swgl_OutR8, flags, swgl_SpanLength, swgl_StepZW, consider reordering the fields or adding explicit padding members

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gl.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -fapprox-func -funsafe-math-optimizations -fno-signed-zeros -mreassociate -freciprocal-math -ffp-contract=fast -fno-rounding-math -mrecip=none -complex-range=basic -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/gfx/wr/swgl -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/root/firefox-clang/gfx/wr/swgl -resource-dir /usr/lib/llvm-21/lib/clang/21 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/gfx/wr/swgl/../webrender/res -I src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/x86_64-unknown-linux-gnu/debug/build/swgl-19ea748e17a3c52a/out -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -D MOZILLA_CONFIG_H -U MOZILLA_CONFIG_H -D _GLIBCXX_USE_CXX11_ABI=0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -std=c++17 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-06-27-100320-3286336-1 -x c++ src/gl.cc
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5struct VertexAttrib;
6
7namespace glsl {
8
9// Type holding group of scalars interpolated across rasterized rows and spans,
10// shuttling values between vertex shaders and fragment shaders.
11// GCC requires power-of-two vector sizes, so must use glsl type as workaround
12// to operate in Float-sized chunks.
13typedef vec3 Interpolants;
14
15// Clip distances, if enabled, are always stored in the first SIMD chunk of the
16// interpolants.
17static ALWAYS_INLINE__attribute__((always_inline)) inline Float get_clip_distances(const Interpolants& interp) {
18 return interp.x;
19}
20
21struct VertexShaderImpl;
22struct FragmentShaderImpl;
23
24struct ProgramImpl {
25 virtual ~ProgramImpl() {}
26 virtual int get_uniform(const char* name) const = 0;
27 virtual void bind_attrib(const char* name, int index) = 0;
28 virtual int get_attrib(const char* name) const = 0;
29 virtual size_t interpolants_size() const = 0;
30 virtual VertexShaderImpl* get_vertex_shader() = 0;
31 virtual FragmentShaderImpl* get_fragment_shader() = 0;
32 virtual const char* get_name() const = 0;
33};
34
35typedef ProgramImpl* (*ProgramLoader)();
36
37// The maximum size of the gl_ClipDistance array.
38constexpr int32_t gl_MaxClipDistances = 4;
39
40struct VertexShaderImpl {
41 typedef void (*SetUniform1iFunc)(VertexShaderImpl*, int index, int value);
42 typedef void (*SetUniform4fvFunc)(VertexShaderImpl*, int index,
43 const float* value);
44 typedef void (*SetUniformMatrix4fvFunc)(VertexShaderImpl*, int index,
45 const float* value);
46 typedef void (*InitBatchFunc)(VertexShaderImpl*);
47 typedef void (*LoadAttribsFunc)(VertexShaderImpl*, VertexAttrib* attribs,
48 uint32_t start, int instance, int count);
49 typedef void (*RunPrimitiveFunc)(VertexShaderImpl*, char* interps,
50 size_t interp_stride);
51
52 SetUniform1iFunc set_uniform_1i_func = nullptr;
53 SetUniform4fvFunc set_uniform_4fv_func = nullptr;
54 SetUniformMatrix4fvFunc set_uniform_matrix4fv_func = nullptr;
55 InitBatchFunc init_batch_func = nullptr;
56 LoadAttribsFunc load_attribs_func = nullptr;
57 RunPrimitiveFunc run_primitive_func = nullptr;
58
59 enum FLAGS {
60 CLIP_DISTANCE = 1 << 0,
61 };
62 int flags = 0;
63 void enable_clip_distance() { flags |= CLIP_DISTANCE; }
64 ALWAYS_INLINE__attribute__((always_inline)) inline bool use_clip_distance() const {
65 return (flags & CLIP_DISTANCE) != 0;
66 }
67
68 vec4 gl_Position;
69 Float gl_ClipDistance[gl_MaxClipDistances];
70
71 void set_uniform_1i(int index, int value) {
72 (*set_uniform_1i_func)(this, index, value);
73 }
74
75 void set_uniform_4fv(int index, const float* value) {
76 (*set_uniform_4fv_func)(this, index, value);
77 }
78
79 void set_uniform_matrix4fv(int index, const float* value) {
80 (*set_uniform_matrix4fv_func)(this, index, value);
81 }
82
83 void init_batch() { (*init_batch_func)(this); }
84
85 ALWAYS_INLINE__attribute__((always_inline)) inline void load_attribs(VertexAttrib* attribs, uint32_t start,
86 int instance, int count) {
87 (*load_attribs_func)(this, attribs, start, instance, count);
88 }
89
90 ALWAYS_INLINE__attribute__((always_inline)) inline void run_primitive(char* interps, size_t interp_stride) {
91 (*run_primitive_func)(this, interps, interp_stride);
92 }
93};
94
95// The number of pixels in a step.
96constexpr int32_t swgl_StepSize = 4;
97
98struct FragmentShaderImpl {
Excessive padding in 'struct glsl::FragmentShaderImpl' (32 padding bytes, where 0 is optimal). Optimal fields order: swgl_IsPixelDiscarded, gl_FragCoord, gl_FragColor, gl_SecondaryFragColor, init_span_func, run_func, skip_func, init_span_w_func, run_w_func, skip_w_func, draw_span_RGBA8_func, draw_span_R8_func, swgl_OutRGBA8, swgl_OutR8, flags, swgl_SpanLength, swgl_StepZW, consider reordering the fields or adding explicit padding members
99 typedef void (*InitSpanFunc)(FragmentShaderImpl*, const void* interps,
100 const void* step);
101 typedef void (*RunFunc)(FragmentShaderImpl*);
102 typedef void (*SkipFunc)(FragmentShaderImpl*, int steps);
103 typedef void (*InitSpanWFunc)(FragmentShaderImpl*, const void* interps,
104 const void* step);
105 typedef void (*RunWFunc)(FragmentShaderImpl*);
106 typedef void (*SkipWFunc)(FragmentShaderImpl*, int steps);
107 typedef int (*DrawSpanRGBA8Func)(FragmentShaderImpl*);
108 typedef int (*DrawSpanR8Func)(FragmentShaderImpl*);
109
110 InitSpanFunc init_span_func = nullptr;
111 RunFunc run_func = nullptr;
112 SkipFunc skip_func = nullptr;
113 InitSpanWFunc init_span_w_func = nullptr;
114 RunWFunc run_w_func = nullptr;
115 SkipWFunc skip_w_func = nullptr;
116 DrawSpanRGBA8Func draw_span_RGBA8_func = nullptr;
117 DrawSpanR8Func draw_span_R8_func = nullptr;
118
119 enum FLAGS {
120 DISCARD = 1 << 0,
121 PERSPECTIVE = 1 << 1,
122 };
123 int flags = 0;
124 void enable_discard() { flags |= DISCARD; }
125 void enable_perspective() { flags |= PERSPECTIVE; }
126 ALWAYS_INLINE__attribute__((always_inline)) inline bool use_discard() const { return (flags & DISCARD) != 0; }
127 ALWAYS_INLINE__attribute__((always_inline)) inline bool use_perspective() const {
128 return (flags & PERSPECTIVE) != 0;
129 }
130
131 vec4 gl_FragCoord;
132 vec4 gl_FragColor;
133 vec4 gl_SecondaryFragColor;
134
135 vec2_scalar swgl_StepZW;
136 Bool swgl_IsPixelDiscarded = false;
137 // The current buffer position for committing span output.
138 uint32_t* swgl_OutRGBA8 = nullptr;
139 uint8_t* swgl_OutR8 = nullptr;
140 // The remaining number of pixels in the span.
141 int32_t swgl_SpanLength = 0;
142
143 ALWAYS_INLINE__attribute__((always_inline)) inline void step_fragcoord(int steps = 4) { gl_FragCoord.x += steps; }
144
145 ALWAYS_INLINE__attribute__((always_inline)) inline void step_perspective(int steps = 4) {
146 gl_FragCoord.z += swgl_StepZW.x * steps;
147 gl_FragCoord.w += swgl_StepZW.y * steps;
148 }
149
150 template <bool W = false>
151 ALWAYS_INLINE__attribute__((always_inline)) inline void init_span(const void* interps, const void* step) {
152 (*(W ? init_span_w_func : init_span_func))(this, interps, step);
153 }
154
155 template <bool W = false>
156 ALWAYS_INLINE__attribute__((always_inline)) inline void run() {
157 (*(W ? run_w_func : run_func))(this);
158 }
159
160 template <bool W = false>
161 ALWAYS_INLINE__attribute__((always_inline)) inline void skip(int steps = 4) {
162 (*(W ? skip_w_func : skip_func))(this, steps);
163 }
164
165 ALWAYS_INLINE__attribute__((always_inline)) inline int draw_span(uint32_t* buf, int len) {
166 swgl_OutRGBA8 = buf;
167 swgl_SpanLength = len;
168 return (*draw_span_RGBA8_func)(this);
169 }
170
171 ALWAYS_INLINE__attribute__((always_inline)) inline bool has_draw_span(uint32_t*) {
172 return draw_span_RGBA8_func != nullptr;
173 }
174
175 ALWAYS_INLINE__attribute__((always_inline)) inline int draw_span(uint8_t* buf, int len) {
176 swgl_OutR8 = buf;
177 swgl_SpanLength = len;
178 return (*draw_span_R8_func)(this);
179 }
180
181 ALWAYS_INLINE__attribute__((always_inline)) inline bool has_draw_span(uint8_t*) {
182 return draw_span_R8_func != nullptr;
183 }
184};
185
186} // namespace glsl