Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/harfbuzz/src/./../../../../gfx/harfbuzz/src/graph/../OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
Warning:line 172, column 5
Value stored to 'count' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_gfx_harfbuzz_src0.cpp -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 -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/harfbuzz/src -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/harfbuzz/src -resource-dir /usr/lib/llvm-23/lib/clang/23 -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/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D PACKAGE_VERSION="moz" -D PACKAGE_BUGREPORT="http://bugzilla.mozilla.org/" -D HAVE_OT=1 -D HAVE_ROUND=1 -D HB_NO_BUFFER_VERIFY -D HB_NO_FALLBACK_SHAPE -D HB_NO_PAINT -D HB_NO_UCD -D HB_NO_UNICODE_FUNCS -D HB_NO_VAR_COMPOSITES -D HAVE_MMAP=1 -D HAVE_SYS_MMAN_H=1 -D HAVE_UNISTD_H=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/gfx/harfbuzz/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/harfbuzz/src -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 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -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-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 -Wno-character-conversion -std=gnu++20 -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 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c++ Unified_cpp_gfx_harfbuzz_src0.cpp
1#ifndef OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBSTFORMAT1_HH
2#define OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBSTFORMAT1_HH
3
4#include "Common.hh"
5
6namespace OT {
7namespace Layout {
8namespace GSUB_impl {
9
10struct ReverseChainSingleSubstFormat1
11{
12 protected:
13 HBUINT16 format; /* Format identifier--format = 1 */
14 Offset16To<Coverage>
15 coverage; /* Offset to Coverage table--from
16 * beginning of table */
17 Array16OfOffset16To<Coverage>
18 backtrack; /* Array of coverage tables
19 * in backtracking sequence, in glyph
20 * sequence order */
21 Array16OfOffset16To<Coverage>
22 lookaheadX; /* Array of coverage tables
23 * in lookahead sequence, in glyph
24 * sequence order */
25 Array16Of<HBGlyphID16>
26 substituteX; /* Array of substitute
27 * GlyphIDs--ordered by Coverage Index */
28 public:
29 DEFINE_SIZE_MIN (10)void _instance_assertion_on_line_29 () const { static_assert (
(sizeof (*this) >= (10)), ""); } static constexpr unsigned
null_size = (10); static constexpr unsigned min_size = (10)
;
30
31 bool sanitize (hb_sanitize_context_t *c) const
32 {
33 TRACE_SANITIZE (this)hb_no_trace_t<bool> trace;
34 if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
35 return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 35);
36 hb_barrier ();
37 const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
38 if (!lookahead.sanitize (c, this))
39 return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 39);
40 hb_barrier ();
41 const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
42 return_trace (substitute.sanitize (c))return trace.ret (substitute.sanitize (c), __PRETTY_FUNCTION__
, 42)
;
43 }
44
45 bool intersects (const hb_set_t *glyphs) const
46 {
47 if (!(this+coverage).intersects (glyphs))
48 return false;
49
50 const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
51
52 unsigned int count;
53
54 count = backtrack.len;
55 for (unsigned int i = 0; i < count; i++)
56 if (!(this+backtrack[i]).intersects (glyphs))
57 return false;
58
59 count = lookahead.len;
60 for (unsigned int i = 0; i < count; i++)
61 if (!(this+lookahead[i]).intersects (glyphs))
62 return false;
63
64 return true;
65 }
66
67 bool may_have_non_1to1 () const
68 { return false; }
69
70 void depend (hb_depend_context_t *c) const {
71 // Filter by intersects and parent_active_glyphs like closure does
72 if (!intersects (c->glyphs)) return;
73
74 const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
75 const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
76
77 /* Build context set from backtrack and lookahead coverages.
78 * ReverseChainSingleSubst has contextual requirements - the substitution
79 * only fires when backtrack and lookahead glyphs are present. */
80 hb_set_t context_glyphs;
81
82 /* Add glyphs from backtrack coverages */
83 unsigned int count = backtrack.len;
84 for (unsigned int i = 0; i < count; i++)
85 {
86 hb_set_t back_glyphs;
87 (this+backtrack[i]).intersect_set (*c->glyphs, back_glyphs);
88 if (back_glyphs.get_population () == 1)
89 context_glyphs.add (back_glyphs.get_min ());
90 else if (back_glyphs.get_population () > 1)
91 {
92 hb_codepoint_t set_idx = c->depend_data->find_or_create_context_set (back_glyphs);
93 if (unlikely (set_idx == HB_CODEPOINT_INVALID)__builtin_expect (bool(set_idx == ((hb_codepoint_t) -1)), 0))
94 return;
95 context_glyphs.add (HB_DEPEND_CONTEXT_SET_FLAG0x80000000u | set_idx);
96 }
97 }
98
99 /* Add glyphs from lookahead coverages */
100 count = lookahead.len;
101 for (unsigned int i = 0; i < count; i++)
102 {
103 hb_set_t look_glyphs;
104 (this+lookahead[i]).intersect_set (*c->glyphs, look_glyphs);
105 if (look_glyphs.get_population () == 1)
106 context_glyphs.add (look_glyphs.get_min ());
107 else if (look_glyphs.get_population () > 1)
108 {
109 hb_codepoint_t set_idx = c->depend_data->find_or_create_context_set (look_glyphs);
110 if (unlikely (set_idx == HB_CODEPOINT_INVALID)__builtin_expect (bool(set_idx == ((hb_codepoint_t) -1)), 0))
111 return;
112 context_glyphs.add (HB_DEPEND_CONTEXT_SET_FLAG0x80000000u | set_idx);
113 }
114 }
115
116 /* Allocate context set and save/restore around edge creation */
117 if (unlikely (context_glyphs.in_error ())__builtin_expect (bool(context_glyphs.in_error ()), 0))
118 {
119 c->depend_data->fail ();
120 return;
121 }
122 hb_codepoint_t context_set_idx = context_glyphs.is_empty ()
123 ? HB_CODEPOINT_INVALID((hb_codepoint_t) -1)
124 : c->depend_data->find_or_create_context_set (context_glyphs);
125 if (unlikely (!context_glyphs.is_empty () &&__builtin_expect (bool(!context_glyphs.is_empty () &&
context_set_idx == ((hb_codepoint_t) -1)), 0)
126 context_set_idx == HB_CODEPOINT_INVALID)__builtin_expect (bool(!context_glyphs.is_empty () &&
context_set_idx == ((hb_codepoint_t) -1)), 0)
)
127 return;
128
129 hb_codepoint_t saved_context = c->depend_data->current_context_set_index;
130 c->depend_data->current_context_set_index = context_set_idx;
131
132 + hb_zip (this+coverage, substitute)
133 | hb_filter (c->parent_active_glyphs (), hb_first)
134 | hb_apply ([&] (const hb_codepoint_pair_t &_) { c->depend_data->add_gsub_lookup (_.first, c->lookup_index, _.second); })
135 ;
136
137 c->depend_data->current_context_set_index = saved_context;
138 }
139
140 void closure (hb_closure_context_t *c) const
141 {
142 if (!intersects (c->glyphs)) return;
143
144 const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
145 const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
146
147 + hb_zip (this+coverage, substitute)
148 | hb_filter (c->parent_active_glyphs (), hb_first)
149 | hb_map (hb_second)
150 | hb_sink (c->output)
151 ;
152 }
153
154 void closure_lookups (hb_closure_lookups_context_t *c) const {}
155
156 void collect_glyphs (hb_collect_glyphs_context_t *c) const
157 {
158 if (unlikely (!(this+coverage).collect_coverage (c->input))__builtin_expect (bool(!(this+coverage).collect_coverage (c->
input)), 0)
) return;
159
160 unsigned int count;
161
162 count = backtrack.len;
163 for (unsigned int i = 0; i < count; i++)
164 if (unlikely (!(this+backtrack[i]).collect_coverage (c->before))__builtin_expect (bool(!(this+backtrack[i]).collect_coverage (
c->before)), 0)
) return;
165
166 const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
167 count = lookahead.len;
168 for (unsigned int i = 0; i < count; i++)
169 if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))__builtin_expect (bool(!(this+lookahead[i]).collect_coverage (
c->after)), 0)
) return;
170
171 const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
172 count = substitute.len;
Value stored to 'count' is never read
173 c->output->add_array (substitute.arrayZ, substitute.len);
174 }
175
176 const Coverage &get_coverage () const { return this+coverage; }
177
178 bool would_apply (hb_would_apply_context_t *c) const
179 { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED((unsigned int) -1); }
180
181 bool apply (hb_ot_apply_context_t *c) const
182 {
183 TRACE_APPLY (this)hb_no_trace_t<bool> trace;
184 unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
185 if (index == NOT_COVERED((unsigned int) -1)) return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 185);
186
187 if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL)__builtin_expect (bool(c->nesting_level_left != 64), 0))
188 return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 188); /* No chaining to this type */
189
190 const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
191 const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
192
193 if (unlikely (index >= substitute.len)__builtin_expect (bool(index >= substitute.len), 0)) return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 193);
194
195 unsigned int start_index = 0, end_index = 0;
196 if (match_backtrack (c,
197 backtrack.len, (HBUINT16 *) backtrack.arrayZ,
198 match_coverage, this,
199 &start_index) &&
200 match_lookahead (c,
201 lookahead.len, (HBUINT16 *) lookahead.arrayZ,
202 match_coverage, this,
203 c->buffer->idx + 1, &end_index))
204 {
205 c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
206
207 if (HB_BUFFER_MESSAGE_MORE(0 +0) && c->buffer->messaging ())
208 {
209 c->buffer->message (c->font,
210 "replacing glyph at %u (reverse chaining substitution)",
211 c->buffer->idx);
212 }
213
214 c->replace_glyph_inplace (substitute[index]);
215
216 if (HB_BUFFER_MESSAGE_MORE(0 +0) && c->buffer->messaging ())
217 {
218 c->buffer->message (c->font,
219 "replaced glyph at %u (reverse chaining substitution)",
220 c->buffer->idx);
221 }
222
223 /* Note: We DON'T decrease buffer->idx. The main loop does it
224 * for us. This is useful for preventing surprises if someone
225 * calls us through a Context lookup. */
226 return_trace (true)return trace.ret (true, __PRETTY_FUNCTION__, 226);
227 }
228 else
229 {
230 c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
231 return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 231);
232 }
233 }
234
235 template<typename Iterator,
236 hb_requires (hb_is_iterator (Iterator))typename hb_enable_if<((hb_is_iterator_of<Iterator, typename
Iterator::item_t>::value))>::type* = nullptr
>
237 bool serialize_coverage_offset_array (hb_subset_context_t *c, Iterator it) const
238 {
239 TRACE_SERIALIZE (this)hb_no_trace_t<bool> trace;
240 auto *out = c->serializer->start_embed<Array16OfOffset16To<Coverage>> ();
241
242 if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size))__builtin_expect (bool(!c->serializer->allocate_size<
HBUINT16> (HBUINT16::static_size)), 0)
)
243 return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 243);
244
245 for (auto& offset : it) {
246 auto *o = out->serialize_append (c->serializer);
247 if (unlikely (!o)__builtin_expect (bool(!o), 0) || !o->serialize_subset (c, offset, this))
248 return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 248);
249 }
250
251 return_trace (true)return trace.ret (true, __PRETTY_FUNCTION__, 251);
252 }
253
254 template<typename Iterator, typename BacktrackIterator, typename LookaheadIterator,
255 hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_pair_t))typename hb_enable_if<(((hb_is_source_of<Iterator, hb_codepoint_pair_t
>::value && Iterator::is_sorted_iterator)))>::type
* = nullptr
,
256 hb_requires (hb_is_iterator (BacktrackIterator))typename hb_enable_if<((hb_is_iterator_of<BacktrackIterator
, typename BacktrackIterator::item_t>::value))>::type* =
nullptr
,
257 hb_requires (hb_is_iterator (LookaheadIterator))typename hb_enable_if<((hb_is_iterator_of<LookaheadIterator
, typename LookaheadIterator::item_t>::value))>::type* =
nullptr
>
258 bool serialize (hb_subset_context_t *c,
259 Iterator coverage_subst_iter,
260 BacktrackIterator backtrack_iter,
261 LookaheadIterator lookahead_iter) const
262 {
263 TRACE_SERIALIZE (this)hb_no_trace_t<bool> trace;
264
265 auto *out = c->serializer->start_embed (this);
266 if (unlikely (!c->serializer->embed (this->format))__builtin_expect (bool(!c->serializer->embed (this->
format)), 0)
) return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 266);
267 if (unlikely (!c->serializer->embed (this->coverage))__builtin_expect (bool(!c->serializer->embed (this->
coverage)), 0)
) return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 267);
268
269 if (!serialize_coverage_offset_array (c, backtrack_iter)) return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 269);
270 if (!serialize_coverage_offset_array (c, lookahead_iter)) return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 270);
271
272 auto *substitute_out = c->serializer->start_embed<Array16Of<HBGlyphID16>> ();
273 auto substitutes =
274 + coverage_subst_iter
275 | hb_map (hb_second)
276 ;
277
278 auto glyphs =
279 + coverage_subst_iter
280 | hb_map_retains_sorting (hb_first)
281 ;
282 if (unlikely (! c->serializer->check_success (substitute_out->serialize (c->serializer, substitutes)))__builtin_expect (bool(! c->serializer->check_success (
substitute_out->serialize (c->serializer, substitutes))
), 0)
)
283 return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 283);
284
285 if (unlikely (!out->coverage.serialize_serialize (c->serializer, glyphs))__builtin_expect (bool(!out->coverage.serialize_serialize (
c->serializer, glyphs)), 0)
)
286 return_trace (false)return trace.ret (false, __PRETTY_FUNCTION__, 286);
287 return_trace (true)return trace.ret (true, __PRETTY_FUNCTION__, 287);
288 }
289
290 bool subset (hb_subset_context_t *c) const
291 {
292 TRACE_SUBSET (this)hb_no_trace_t<bool> trace;
293 const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
294 const hb_map_t &glyph_map = *c->plan->glyph_map;
295
296 const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
297 const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
298
299 auto it =
300 + hb_zip (this+coverage, substitute)
301 | hb_filter (glyphset, hb_first)
302 | hb_filter (glyphset, hb_second)
303 | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> p) -> hb_codepoint_pair_t
304 { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
305 ;
306
307 return_trace (bool (it) && serialize (c, it, backtrack.iter (), lookahead.iter ()))return trace.ret (bool (it) && serialize (c, it, backtrack
.iter (), lookahead.iter ()), __PRETTY_FUNCTION__, 307)
;
308 }
309};
310
311}
312}
313}
314
315#endif /* HB_OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBSTFORMAT1_HH */