Bug Summary

File:Profiler.cpp
Warning:line 185, column 10
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Profiler.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 -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/tmp/build/cg3/cg3-1.4.17+g2285~f7d45cea/src -resource-dir /usr/lib/llvm-16/lib/clang/16 -D BOOST_NO_CXX98_FUNCTION_BASE=1 -D HAS_FS -D UNISTR_FROM_CHAR_EXPLICIT=explicit -D UNISTR_FROM_STRING_EXPLICIT=explicit -D _POSIX_C_SOURCE=200112 -D cg3_EXPORTS -I /tmp/build/cg3/cg3-1.4.17+g2285~f7d45cea/include/posix -I /tmp/build/cg3/cg3-1.4.17+g2285~f7d45cea/include -I /tmp/build/cg3/cg3-1.4.17+g2285~f7d45cea/src -I /usr/local/include -D NDEBUG -internal-isystem /usr/lib/llvm-16/bin/../include/c++/v1 -internal-isystem /usr/lib/llvm-16/lib/clang/16/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 -O3 -Wno-missing-field-initializers -Wno-deprecated -Wno-unused-parameter -Wno-unused-result -std=c++2b -fdebug-compilation-dir=/tmp/build/cg3/cg3-1.4.17+g2285~f7d45cea/src -ferror-limit 19 -fvisibility-inlines-hidden -fgnuc-version=4.2.1 -fno-implicit-modules -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/build/cg3/scan-build/2024-09-11-161008-13503-1 -x c++ /tmp/build/cg3/cg3-1.4.17+g2285~f7d45cea/src/Profiler.cpp
1/*
2* Copyright (C) 2007-2024, GrammarSoft ApS
3* Developed by Tino Didriksen <mail@tinodidriksen.com>
4*
5* This program is free software: you can redistribute it and/or modify
6* it under the terms of the GNU General Public License as published by
7* the Free Software Foundation, either version 3 of the License, or
8* (at your option) any later version.
9*
10* This program is distributed in the hope that it will be useful,
11* but WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this progam. If not, see <https://www.gnu.org/licenses/>.
17*/
18
19#include "Profiler.hpp"
20#include "stdafx.hpp"
21#include <sqlite3.h>
22
23namespace CG3 {
24
25inline auto sqlite3_exec(sqlite3* db, const char* sql) {
26 return ::sqlite3_exec(db, sql, nullptr, nullptr, nullptr);
27}
28
29void Profiler::write(const char* fname) {
30 if (sqlite3_initialize() != SQLITE_OK0) {
31 throw std::runtime_error("sqlite3_initialize() errored");
32 }
33
34 remove(fname);
35
36 sqlite3* db = nullptr;
37 sqlite3_stmt* s = nullptr;
38 if (sqlite3_open_v2(fname, &db, SQLITE_OPEN_READWRITE0x00000002 | SQLITE_OPEN_CREATE0x00000004, nullptr) != SQLITE_OK0) {
39 throw std::runtime_error(concat("sqlite3_open_v2() error: ", sqlite3_errmsg(db)));
40 }
41
42 auto inits = {
43 "PRAGMA journal_mode = MEMORY",
44 "PRAGMA locking_mode = EXCLUSIVE",
45 "PRAGMA synchronous = OFF",
46 "CREATE TABLE strings (key INTEGER PRIMARY KEY NOT NULL, value TEXT NOT NULL)",
47 "CREATE TABLE grammars (fname INTEGER PRIMARY KEY NOT NULL, grammar INTEGER NOT NULL)",
48 "CREATE TABLE entries (type INTEGER NOT NULL, id INTEGER NOT NULL, grammar INTEGER NOT NULL, b INTEGER NOT NULL, e INTEGER NOT NULL, num_match INTEGER NOT NULL, num_fail INTEGER NOT NULL, example_window INTEGER NOT NULL, PRIMARY KEY (type, id))",
49 "CREATE TABLE rule_contexts (rule INTEGER NOT NULL, context INTEGER NOT NULL, num_match INTEGER NOT NULL, PRIMARY KEY (rule, context))",
50 "BEGIN",
51 };
52 for (auto q : inits) {
53 if (sqlite3_exec(db, q) != SQLITE_OK0) {
54 throw std::runtime_error(concat("sqlite3 error while initializing database: ", sqlite3_errmsg(db)));
55 }
56 }
57
58 // Strings
59 if (sqlite3_prepare_v2(db, "INSERT INTO strings (key, value) VALUES (:key, :value)", -1, &s, nullptr) != SQLITE_OK0) {
60 throw std::runtime_error(concat("sqlite3 error preparing insert into strings table: ", sqlite3_errmsg(db)));
61 }
62 for (auto& it : strings) {
63 sqlite3_reset(s);
64 auto sz = it.second;
65 if (sz == grammar_ast) {
66 sz = 0;
67 }
68 if (sqlite3_bind_int64(s, 1, sz) != SQLITE_OK0) {
69 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for key: ", sqlite3_errmsg(db)));
70 }
71 if (sqlite3_bind_text(s, 2, it.first.c_str(), SI32(it.first.size()), SQLITE_STATIC((sqlite3_destructor_type)0)) != SQLITE_OK0) {
72 throw std::runtime_error(concat("sqlite3 error trying to bind text for value: ", sqlite3_errmsg(db)));
73 }
74 if (sqlite3_step(s) != SQLITE_DONE101) {
75 throw std::runtime_error(concat("sqlite3 error inserting into strings table: ", sqlite3_errmsg(db)));
76 }
77 }
78 sqlite3_finalize(s);
79
80 // Grammars
81 if (sqlite3_prepare_v2(db, "INSERT INTO grammars (fname, grammar) VALUES (:fname, :grammar)", -1, &s, nullptr) != SQLITE_OK0) {
82 throw std::runtime_error(concat("sqlite3 error preparing insert into grammars table: ", sqlite3_errmsg(db)));
83 }
84 for (auto& it : grammars) {
85 sqlite3_reset(s);
86 if (sqlite3_bind_int64(s, 1, it.first) != SQLITE_OK0) {
87 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for fname: ", sqlite3_errmsg(db)));
88 }
89 if (sqlite3_bind_int64(s, 2, it.second) != SQLITE_OK0) {
90 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for grammar: ", sqlite3_errmsg(db)));
91 }
92 if (sqlite3_step(s) != SQLITE_DONE101) {
93 throw std::runtime_error(concat("sqlite3 error inserting into grammars table: ", sqlite3_errmsg(db)));
94 }
95 }
96 sqlite3_finalize(s);
97
98 // Entries
99 if (sqlite3_prepare_v2(db, "INSERT INTO entries (type, id, grammar, b, e, num_match, num_fail, example_window) VALUES(:type, :id, :grammar, :b, :e, :num_match, :num_fail, :example_window)", -1, &s, nullptr) != SQLITE_OK0) {
100 throw std::runtime_error(concat("sqlite3 error preparing insert into entries table: ", sqlite3_errmsg(db)));
101 }
102 for (auto& it : entries) {
103 sqlite3_reset(s);
104 if (sqlite3_bind_int64(s, 1, it.first.type) != SQLITE_OK0) {
105 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for type: ", sqlite3_errmsg(db)));
106 }
107 if (sqlite3_bind_int64(s, 2, it.first.id) != SQLITE_OK0) {
108 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for id: ", sqlite3_errmsg(db)));
109 }
110 if (sqlite3_bind_int64(s, 3, it.second.grammar) != SQLITE_OK0) {
111 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for grammar: ", sqlite3_errmsg(db)));
112 }
113 if (sqlite3_bind_int64(s, 4, it.second.b) != SQLITE_OK0) {
114 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for b: ", sqlite3_errmsg(db)));
115 }
116 if (sqlite3_bind_int64(s, 5, it.second.e) != SQLITE_OK0) {
117 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for e: ", sqlite3_errmsg(db)));
118 }
119 if (sqlite3_bind_int64(s, 6, it.second.num_match) != SQLITE_OK0) {
120 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for num_match: ", sqlite3_errmsg(db)));
121 }
122 if (sqlite3_bind_int64(s, 7, it.second.num_fail) != SQLITE_OK0) {
123 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for num_fail: ", sqlite3_errmsg(db)));
124 }
125 if (sqlite3_bind_int64(s, 8, it.second.example_window) != SQLITE_OK0) {
126 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for example_window: ", sqlite3_errmsg(db)));
127 }
128 if (sqlite3_step(s) != SQLITE_DONE101) {
129 throw std::runtime_error(concat("sqlite3 error inserting into entries table: ", sqlite3_errmsg(db)));
130 }
131 }
132 sqlite3_finalize(s);
133
134 // Rule->Context hits
135 if (sqlite3_prepare_v2(db, "INSERT INTO rule_contexts (rule, context, num_match) VALUES (:rule, :context, :num_match)", -1, &s, nullptr) != SQLITE_OK0) {
136 throw std::runtime_error(concat("sqlite3 error preparing insert into rule_contexts table: ", sqlite3_errmsg(db)));
137 }
138 for (auto& it : rule_contexts) {
139 sqlite3_reset(s);
140 if (sqlite3_bind_int64(s, 1, it.first.first) != SQLITE_OK0) {
141 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for rule: ", sqlite3_errmsg(db)));
142 }
143 if (sqlite3_bind_int64(s, 2, it.first.second) != SQLITE_OK0) {
144 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for context: ", sqlite3_errmsg(db)));
145 }
146 if (sqlite3_bind_int64(s, 3, it.second) != SQLITE_OK0) {
147 throw std::runtime_error(concat("sqlite3 error trying to bind int64 for num_match: ", sqlite3_errmsg(db)));
148 }
149 if (sqlite3_step(s) != SQLITE_DONE101) {
150 throw std::runtime_error(concat("sqlite3 error inserting into rule_contexts table: ", sqlite3_errmsg(db)));
151 }
152 }
153 sqlite3_finalize(s);
154
155 // Erase contexts that only exist as linked part of a larger context
156 // Such contexts are currently irrelevant and just get in the way
157 for (int i = 0; i < 10; ++i) {
158 if (sqlite3_exec(db, "DELETE FROM entries WHERE type = 1 AND id IN (SELECT id FROM entries as et INNER JOIN (SELECT max(b) as b, e FROM entries WHERE type = 1 GROUP BY e HAVING count(b) > 1) as jt ON (et.b = jt.b AND et.e = jt.e))") != SQLITE_OK0) {
159 throw std::runtime_error(concat("sqlite3 error while deleting overlapping contexts: ", sqlite3_errmsg(db)));
160 }
161 }
162
163 if (sqlite3_exec(db, "COMMIT") != SQLITE_OK0) {
164 throw std::runtime_error(concat("sqlite3 error while committing: ", sqlite3_errmsg(db)));
165 }
166}
167
168void Profiler::read(const char* fname) {
169 if (sqlite3_initialize() != SQLITE_OK0) {
170 throw std::runtime_error("sqlite3_initialize() errored");
171 }
172
173 sqlite3* db = nullptr;
174 sqlite3_stmt* s = nullptr;
175 int r = 0;
176 std::string tmp;
177 if (sqlite3_open_v2(fname, &db, SQLITE_OPEN_READONLY0x00000001, nullptr) != SQLITE_OK0) {
178 throw std::runtime_error(concat("sqlite3_open_v2() error: ", sqlite3_errmsg(db)));
179 }
180
181 // Strings
182 if (sqlite3_prepare_v2(db, "SELECT * FROM strings", -1, &s, nullptr) != SQLITE_OK0) {
183 throw std::runtime_error(concat("sqlite3 error preparing select from strings table: ", sqlite3_errmsg(db)));
184 }
185 while ((r = sqlite3_step(s)) == SQLITE_ROW100) {
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r'
186 auto sz = UIZ(sqlite3_column_int64(s, 0));
187 tmp.assign(reinterpret_cast<const char*>(sqlite3_column_text(s, 1)));
188 strings[std::move(tmp)] = sz;
189 }
190 sqlite3_finalize(s);
191
192 // Grammars
193 if (sqlite3_prepare_v2(db, "SELECT * FROM grammars", -1, &s, nullptr) != SQLITE_OK0) {
194 throw std::runtime_error(concat("sqlite3 error preparing select from grammars table: ", sqlite3_errmsg(db)));
195 }
196 while ((r = sqlite3_step(s)) == SQLITE_ROW100) {
197 auto f = UIZ(sqlite3_column_int64(s, 0));
198 auto g = UIZ(sqlite3_column_int64(s, 1));
199 grammars[f] = g;
200 }
201 sqlite3_finalize(s);
202
203 // Entries
204 if (sqlite3_prepare_v2(db, "SELECT * FROM entries", -1, &s, nullptr) != SQLITE_OK0) {
205 throw std::runtime_error(concat("sqlite3 error preparing select from entries table: ", sqlite3_errmsg(db)));
206 }
207 while ((r = sqlite3_step(s)) == SQLITE_ROW100) {
208 auto type = UI8(sqlite3_column_int64(s, 0));
209 auto id = UI32(sqlite3_column_int64(s, 1));
210 Profiler::Key k{type, id};
211 auto& e = entries[k];
212 e.type = type;
213 e.grammar = UI32(sqlite3_column_int64(s, 2));
214 e.b = UIZ(sqlite3_column_int64(s, 3));
215 e.e = UIZ(sqlite3_column_int64(s, 4));
216 e.num_match = UIZ(sqlite3_column_int64(s, 5));
217 e.num_fail = UIZ(sqlite3_column_int64(s, 6));
218 e.example_window = UIZ(sqlite3_column_int64(s, 7));
219 }
220 sqlite3_finalize(s);
221
222 // Rule->Context hits
223 if (sqlite3_prepare_v2(db, "SELECT * FROM rule_contexts", -1, &s, nullptr) != SQLITE_OK0) {
224 throw std::runtime_error(concat("sqlite3 error preparing select from rule_contexts table: ", sqlite3_errmsg(db)));
225 }
226 while ((r = sqlite3_step(s)) == SQLITE_ROW100) {
227 auto r = UI32(sqlite3_column_int64(s, 0));
228 auto c = UI32(sqlite3_column_int64(s, 1));
229 rule_contexts[std::pair(r,c)] = UIZ(sqlite3_column_int64(s, 2));
230 }
231 sqlite3_finalize(s);
232}
233
234}