• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nickg / nvc / 15094290326

18 May 2025 08:51AM UTC coverage: 92.332% (-0.02%) from 92.354%
15094290326

push

github

nickg
Fix non-accelerated SHA1 writing to input buffer

Spotted by @Blebowski in #1184

69299 of 75054 relevant lines covered (92.33%)

387241.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.4
/src/eval.c
1
//
2
//  Copyright (C) 2013-2023  Nick Gasson
3
//
4
//  This program is free software: you can redistribute it and/or modify
5
//  it under the terms of the GNU General Public License as published by
6
//  the Free Software Foundation, either version 3 of the License, or
7
//  (at your option) any later version.
8
//
9
//  This program is distributed in the hope that it will be useful,
10
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
//  GNU General Public License for more details.
13
//
14
//  You should have received a copy of the GNU General Public License
15
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

18
#include "util.h"
19
#include "common.h"
20
#include "diag.h"
21
#include "eval.h"
22
#include "hash.h"
23
#include "ident.h"
24
#include "jit/jit-ffi.h"
25
#include "jit/jit.h"
26
#include "lib.h"
27
#include "lower.h"
28
#include "mir/mir-unit.h"
29
#include "option.h"
30
#include "phase.h"
31
#include "rt/assert.h"
32
#include "tree.h"
33
#include "type.h"
34
#include "vcode.h"
35

36
#include <assert.h>
37
#include <stdint.h>
38
#include <stdlib.h>
39
#include <stdarg.h>
40
#include <inttypes.h>
41
#include <string.h>
42

43
static const char *eval_expr_name(tree_t expr)
×
44
{
45
   const tree_kind_t kind = tree_kind(expr);
×
46
   if (kind == T_FCALL)
×
47
      return istr(tree_ident(expr));
×
48
   else
49
      return tree_kind_str(kind);
×
50
}
51

52
static tree_t eval_value_to_tree(jit_scalar_t value, type_t type,
11,474✔
53
                                 const loc_t *loc)
54
{
55
   tree_t tree = NULL;
11,474✔
56

57
   if (type_is_enum(type)) {
11,474✔
58
      type_t base = type_base_recur(type);
2,878✔
59
      if ((unsigned)value.integer >= type_enum_literals(base))
2,878✔
60
         fatal_at(loc, "enum position %"PRIi64" out of range for type %s",
×
61
                  value.integer, type_pp(base));
62

63
      tree_t lit = type_enum_literal(base, value.integer);
2,878✔
64

65
      tree = tree_new(T_REF);
2,878✔
66
      tree_set_ref(tree, lit);
2,878✔
67
      tree_set_ident(tree, tree_ident(lit));
2,878✔
68
   }
69
   else if (type_is_integer(type)) {
8,596✔
70
      tree = tree_new(T_LITERAL);
2,354✔
71
      tree_set_subkind(tree, L_INT);
2,354✔
72
      tree_set_ival(tree, value.integer);
2,354✔
73
   }
74
   else if (type_is_real(type)) {
6,242✔
75
      tree = tree_new(T_LITERAL);
6,123✔
76
      tree_set_subkind(tree, L_REAL);
6,123✔
77
      tree_set_dval(tree, value.real);
6,123✔
78
   }
79
   else if (type_is_physical(type)) {
119✔
80
      tree = tree_new(T_LITERAL);
119✔
81
      tree_set_subkind(tree, L_PHYSICAL);
119✔
82
      tree_set_ival(tree, value.integer);
119✔
83
   }
84
   else
85
      fatal_trace("cannot convert 0x%"PRIx64" to %s", value.integer,
86
                  type_pp(type));
87

88
   tree_set_type(tree, type);
11,474✔
89
   tree_set_loc(tree, loc);
11,474✔
90
   return tree;
11,474✔
91
}
92

93
static void *thunk_result_cb(jit_scalar_t *args, void *user)
11,660✔
94
{
95
   tree_t expr = user;
11,660✔
96
   type_t type = tree_type(expr);
11,660✔
97
   const loc_t *loc = tree_loc(expr);
11,660✔
98

99
   if (type_is_array(type)) {
11,660✔
100
      assert(dimension_of(type) == 1);
198✔
101

102
      type_t elem = type_elem(type);
198✔
103
      assert(type_is_scalar(elem));
198✔
104

105
      type_t base = type_base_recur(elem);
198✔
106

107
      bool all_chars = true;
198✔
108
      tree_t *lits LOCAL = NULL;
396✔
109
      if (type_is_enum(elem)) {
198✔
110
         const int nlits = type_enum_literals(base);
193✔
111
         lits = xcalloc_array(nlits, sizeof(tree_t));
193✔
112
      }
113
      else
114
         all_chars = false;
115

116
      range_kind_t dir;
198✔
117
      int64_t length, ileft, iright;
198✔
118
      if (!type_const_bounds(type)) {
198✔
119
         length = ffi_array_length(args[2].integer);
197✔
120
         dir = ffi_array_dir(args[2].integer);
197✔
121
         ileft = args[1].integer;
197✔
122
         iright = ffi_array_right(args[1].integer, args[2].integer);
296✔
123
      }
124
      else {
125
         tree_t r = range_of(type, 0);
1✔
126
         if (!folded_length(r, &length))
1✔
127
            fatal_at(loc, "cannot determine static length of array");
×
128

129
         dir = tree_subkind(r);
1✔
130
         ileft = assume_int(tree_left(r));
1✔
131
         iright = assume_int(tree_right(r));
1✔
132
      }
133

134
      const int bytes = (type_bit_width(elem) + 7) / 8;
198✔
135
      tree_t *elts LOCAL = xmalloc_array(length, sizeof(tree_t));
396✔
136
      for (int i = 0; i < length; i++) {
2,384✔
137
#define UNPACK_VALUE(type) do {                                    \
138
            value.integer = ((type *)args[0].pointer)[i];          \
139
         } while (0);
140

141
         jit_scalar_t value = { .integer = 0 };
2,186✔
142
         FOR_ALL_SIZES(bytes, UNPACK_VALUE);
2,186✔
143

144
         if (lits != NULL) {
2,186✔
145
            assert(value.integer >= 0);
2,174✔
146

147
            if (lits[value.integer] == NULL) {
2,174✔
148
               tree_t li = type_enum_literal(base, value.integer);
365✔
149
               lits[value.integer] = make_ref(li);
365✔
150
               all_chars &= ident_char(tree_ident(li), 0) == '\'';
365✔
151
            }
152

153
            elts[i] = lits[value.integer];
2,174✔
154
         }
155
         else
156
            elts[i] = eval_value_to_tree(value, elem, loc);
12✔
157
      }
158

159
      type_t sub = type_new(T_SUBTYPE);
198✔
160
      type_set_base(sub, type);
198✔
161

162
      type_t index_type = index_type_of(type, 0);
198✔
163

164
      tree_t left = NULL, right = NULL;
198✔
165
      if (type_is_enum(index_type)) {
198✔
166
         left = get_enum_lit(expr, index_type, ileft);
×
167
         right = get_enum_lit(expr, index_type, iright);
×
168
      }
169
      else {
170
         left = get_int_lit(expr, index_type, ileft);
198✔
171
         right = get_int_lit(expr, index_type, iright);
198✔
172
      }
173

174
      tree_t r = tree_new(T_RANGE);
198✔
175
      tree_set_subkind(r, dir);
198✔
176
      tree_set_left(r, left);
198✔
177
      tree_set_right(r, right);
198✔
178
      tree_set_loc(r, loc);
198✔
179
      tree_set_type(r, index_type);
198✔
180

181
      tree_t c = tree_new(T_CONSTRAINT);
198✔
182
      tree_set_subkind(c, C_INDEX);
198✔
183
      tree_add_range(c, r);
198✔
184
      tree_set_loc(c, loc);
198✔
185

186
      type_set_constraint(sub, c);
198✔
187

188
      if (all_chars) {
198✔
189
         tree_t tree = tree_new(T_STRING);
192✔
190

191
         for (int i = 0; i < length; i++)
2,364✔
192
            tree_add_char(tree, elts[i]);
2,172✔
193

194
         tree_set_loc(tree, loc);
192✔
195
         tree_set_type(tree, sub);
192✔
196
         return tree;
192✔
197
      }
198
      else {
199
         tree_t tree = tree_new(T_AGGREGATE);
6✔
200
         tree_set_type(tree, sub);
6✔
201
         tree_set_loc(tree, loc);
6✔
202

203
         for (int i = 0; i < length; i++) {
20✔
204
            tree_t a = tree_new(T_ASSOC);
14✔
205
            tree_set_loc(a, loc);
14✔
206
            tree_set_subkind(a, A_POS);
14✔
207
            tree_set_pos(a, i);
14✔
208
            tree_set_value(a, elts[i]);
14✔
209

210
            tree_add_assoc(tree, a);
14✔
211
         }
212

213
         return tree;
214
      }
215
   }
216
   else
217
      return eval_value_to_tree(args[0], tree_type(expr), tree_loc(expr));
11,462✔
218
}
219

220
static tree_t eval_do_fold(jit_t *jit, tree_t expr, lower_unit_t *parent,
12,389✔
221
                           unit_registry_t *registry, void *context)
222
{
223
   vcode_unit_t thunk;
12,389✔
224
   if (parent != NULL)
12,389✔
225
      thunk = lower_thunk_in_context(registry, expr, parent);
908✔
226
   else
227
      thunk = lower_global_thunk(registry, expr);
11,481✔
228

229
   if (thunk == NULL)
12,389✔
230
      return expr;
231

232
   const bool verbose = opt_get_verbose(OPT_EVAL_VERBOSE, NULL);
12,087✔
233

234
   tree_t result = jit_call_thunk(jit, thunk, context, thunk_result_cb, expr);
12,087✔
235

236
   vcode_unit_unref(thunk);
12,083✔
237
   thunk = NULL;
12,083✔
238

239
   if (result != NULL) {
12,083✔
240
      if (verbose) {
11,660✔
241
         LOCAL_TEXT_BUF tb = tb_new();
×
242
         capture_syntax(tb);
×
243
         dump(result);
×
244
         capture_syntax(NULL);
×
245
         tb_strip(tb);
×
246

247
         debugf("evaluating %s returned %s", eval_expr_name(expr), tb_get(tb));
×
248
      }
249

250
      return result;
11,660✔
251
   }
252
   else if (verbose) {
423✔
253
      diag_t *d = diag_new(DIAG_DEBUG, tree_loc(expr));
×
254
      diag_printf(d, "failed to evaluate %s", eval_expr_name(expr));
×
255
      diag_emit(d);
×
256
   }
257

258
   return expr;
259
}
260

261
tree_t eval_try_fold(jit_t *jit, tree_t expr, unit_registry_t *registry,
12,264✔
262
                     lower_unit_t *parent, void *context)
263
{
264
   const bool verbose = opt_get_verbose(OPT_EVAL_VERBOSE, NULL);
12,264✔
265
   jit_set_silent(jit, !verbose);
12,264✔
266

267
   tree_t result = eval_do_fold(jit, expr, parent, registry, context);
12,264✔
268

269
   jit_set_silent(jit, false);
12,260✔
270
   jit_reset_exit_status(jit);
12,260✔
271

272
   clear_vhdl_assert();
12,260✔
273

274
   return result;
12,260✔
275
}
276

277
tree_t eval_must_fold(jit_t *jit, tree_t expr, unit_registry_t *registry,
125✔
278
                      lower_unit_t *parent, void *context)
279
{
280
   return eval_do_fold(jit, expr, parent, registry, context);
125✔
281
}
282

283
static bool eval_not_possible(tree_t t, const char *why)
10,659✔
284
{
285
   if (opt_get_verbose(OPT_EVAL_VERBOSE, NULL))
10,659✔
286
      warn_at(tree_loc(t), "%s prevents constant folding", why);
×
287

288
   return false;
10,659✔
289
}
290

291
bool eval_possible(tree_t t, unit_registry_t *ur, mir_context_t *mc)
64,343✔
292
{
293
   switch (tree_kind(t)) {
73,678✔
294
   case T_FCALL:
23,656✔
295
      {
296
         const tree_flags_t flags = tree_flags(t);
23,656✔
297
         if (!(flags & (TREE_F_LOCALLY_STATIC | TREE_F_GLOBALLY_STATIC)))
23,656✔
298
            return eval_not_possible(t, "non-static expression");
64✔
299

300
         tree_t decl = tree_ref(t);
23,592✔
301
         const subprogram_kind_t kind = tree_subkind(decl);
23,592✔
302
         if (tree_flags(decl) & TREE_F_IMPURE)
23,592✔
303
            return eval_not_possible(t, "call to impure function");
×
304
         else if (kind != S_USER && !is_open_coded_builtin(kind)
23,592✔
305
                  && unit_registry_get(ur, tree_ident2(decl)) == NULL
4,158✔
306
                  && mir_get_unit(mc, tree_ident2(decl)) == NULL)
207✔
307
            return eval_not_possible(t, "not yet lowered predef");
162✔
308
         else if (kind == S_USER && !is_package(tree_container(decl)))
23,430✔
309
            return eval_not_possible(t, "subprogram not in package");
835✔
310

311
         const int nparams = tree_params(t);
22,595✔
312
         for (int i = 0; i < nparams; i++) {
38,349✔
313
            tree_t p = tree_value(tree_param(t, i));
27,732✔
314
            if (!eval_possible(p, ur, mc))
27,732✔
315
               return false;
316
            else if (tree_kind(p) == T_FCALL && type_is_scalar(tree_type(p)))
15,890✔
317
               return false;  // Would have been folded already if possible
318
         }
319

320
         return true;
321
      }
322

323
   case T_LITERAL:
324
   case T_STRING:
325
   case T_OPEN:
326
      return true;
327

328
   case T_TYPE_CONV:
7,066✔
329
   case T_QUALIFIED:
330
      {
331
         tree_t value = tree_value(t);
7,066✔
332
         if (tree_kind(value) == T_FCALL)
7,066✔
333
            return false;   // Would have been folded already if possible
334

335
         return eval_possible(value, ur, mc);
336
      }
337

338
   case T_REF:
19,331✔
339
      {
340
         tree_t decl = tree_ref(t);
19,331✔
341
         switch (tree_kind(decl)) {
19,331✔
342
         case T_UNIT_DECL:
343
         case T_ENUM_LIT:
344
            return true;
345

346
         case T_CONST_DECL:
2,008✔
347
            if (tree_has_value(decl))
2,008✔
348
               return eval_possible(tree_value(decl), ur, mc);
1,987✔
349
            else
350
               return false;
351

352
         default:
9,376✔
353
            return eval_not_possible(t, "reference");
9,376✔
354
         }
355
      }
356

357
   case T_RECORD_REF:
397✔
358
      return eval_possible(tree_value(t), ur, mc);
397✔
359

360
   case T_ARRAY_REF:
969✔
361
      {
362
         const int nparams = tree_params(t);
969✔
363
         for (int i = 0; i < nparams; i++) {
1,898✔
364
            if (!eval_possible(tree_value(tree_param(t, i)), ur, mc))
1,004✔
365
               return false;
366
         }
367

368
         return eval_possible(tree_value(t), ur, mc);
894✔
369
      }
370

371
   case T_AGGREGATE:
1,694✔
372
      {
373
         const int nassocs = tree_assocs(t);
1,694✔
374
         for (int i = 0; i < nassocs; i++) {
10,601✔
375
            if (!eval_possible(tree_value(tree_assoc(t, i)), ur, mc))
8,940✔
376
               return false;
377
         }
378

379
         // Check for missing choices in constrained array aggregates
380
         type_t composite_type = tree_type(t);
1,661✔
381
         if (type_is_array(composite_type)
1,661✔
382
             && !type_is_unconstrained(composite_type)) {
1,563✔
383
            int64_t count = 0, elem_count = 0;
1,541✔
384
            bool known_elem_count = false;
1,541✔
385
            bool has_others = false;
1,541✔
386
            bool has_range = false;
1,541✔
387
            for (int i = 0; i < nassocs; i++) {
10,128✔
388
               tree_t a = tree_assoc(t, i);
8,587✔
389
               const assoc_kind_t akind = tree_subkind(a);
8,587✔
390

391
               switch (akind) {
8,587✔
392

393
               case A_NAMED:
8,486✔
394
               case A_POS:
395
                  known_elem_count = true;
8,486✔
396
                  elem_count = 1;
8,486✔
397
                  break;
8,486✔
398

399
               case A_RANGE:
53✔
400
                  known_elem_count = false;
53✔
401
                  has_range = true;
53✔
402
                  break;
53✔
403

404
               case A_OTHERS:
42✔
405
                  known_elem_count = false;
42✔
406
                  has_others = true;
42✔
407
                  break;
42✔
408

409
               case A_SLICE:
6✔
410
               case A_CONCAT:
411
                  {
412
                     type_t v_type = tree_type(tree_value(a));
6✔
413
                     known_elem_count = true;
6✔
414
                     if (type_is_unconstrained(v_type))
6✔
415
                        known_elem_count = false;
416
                     else if (!folded_length(range_of(v_type, 0), &elem_count))
6✔
417
                        known_elem_count = false;
×
418
                     break;
419
                  }
420
               }
421

422
               if (known_elem_count)
8,587✔
423
                  count += elem_count;
8,492✔
424
            }
425

426
            if (has_range)
1,541✔
427
               // Range could overlap, defer to bounds check
428
               return eval_not_possible(t, "range as choice");
54✔
429

430
            if (!has_others) {
1,488✔
431
               int64_t type_count;
1,446✔
432
               if (folded_length(range_of(composite_type, 0), &type_count))
1,446✔
433
                  if (count != type_count)
1,446✔
434
                     return eval_not_possible(t, "missing choice");
1✔
435
            }
436
         }
437

438
         return true;
439
      }
440

441
   case T_ATTR_REF:
3,364✔
442
      {
443
         if (tree_subkind(t) == ATTR_USER)
3,364✔
444
            return eval_not_possible(t, "user defined attribute");
×
445

446
         if (!eval_possible(tree_name(t), ur, mc))
3,364✔
447
            return false;
448

449
         const int nparams = tree_params(t);
×
450
         for (int i = 0; i < nparams; i++) {
×
451
            if (!eval_possible(tree_value(tree_param(t, i)), ur, mc))
×
452
               return false;
453
         }
454

455
         return true;
456
      }
457

458
   default:
168✔
459
      return eval_not_possible(t, tree_kind_str(tree_kind(t)));
168✔
460
   }
461
}
462

463
static void *case_result_cb(jit_scalar_t *args, void *user)
9✔
464
{
465
   jit_scalar_t *result = user;
9✔
466
   result->integer = args[0].integer;
9✔
467
   return result;
9✔
468
}
469

470
tree_t eval_case(jit_t *jit, tree_t stmt, lower_unit_t *parent, void *context)
9✔
471
{
472
   assert(tree_kind(stmt) == T_CASE_GENERATE);
9✔
473

474
   vcode_unit_t thunk = lower_case_generate_thunk(parent, stmt);
9✔
475

476
   jit_scalar_t result = { .integer = -1 };
9✔
477
   if (jit_call_thunk(jit, thunk, context, case_result_cb, &result) == NULL)
9✔
478
      error_at(tree_loc(tree_value(stmt)), "generate expression is not static");
×
479

480
   vcode_unit_unref(thunk);
9✔
481

482
   if (result.integer == -1)
9✔
483
      return NULL;
484
   else
485
      return tree_stmt(stmt, result.integer);
9✔
486
}
487

488
void *eval_instance(jit_t *jit, ident_t name, void *context)
×
489
{
490
   jit_handle_t h = jit_lazy_compile(jit, name);
×
491
   if (h == JIT_HANDLE_INVALID)
×
492
      fatal_trace("failed to compile instance %s", istr(name));
493

494
   jit_scalar_t result;
×
495
   if (!jit_try_call(jit, h, &result, context, context))
×
496
      return NULL;
497

498
   return result.pointer;
×
499
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc