]> granicus.if.org Git - graphviz/commit
cgraph: more uniform treatment of sequence IDs
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Wed, 6 Jul 2022 00:24:05 +0000 (17:24 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 9 Jul 2022 20:27:34 +0000 (13:27 -0700)
commitdc9492928702e6177639ae1a9cfc6c0974cdfbab
tree93e3807e104216cc27e301c25bb2f8132b349d05
parent94b0d63c995eacb54170b0ee2754d85ca1abfb21
cgraph: more uniform treatment of sequence IDs

Sequence IDs are calculated using 64-bit counters in `Agclos_s`. But then the
field used to store sequence IDs, `Agtag_s.seq`, is `sizeof(unsigned) * 8 - 4`
bits wide, 28-bit on x86 and x86-64. As a result, the compiler believes IDs that
exceed 2²⁸ - 1 can occur and overflow `Agtag_s.seq`:

  edge.c:213:30: warning: conversion from 'int' to 'unsigned int:28' may change
    value [-Wconversion]
  213 |     AGSEQ(in) = AGSEQ(out) = seq;
      |                              ^~~
  ...
  graph.c: In function 'agopen1':
  graph.c:77:20: warning: conversion from 'uint64_t' {aka 'long unsigned int'}
    to 'unsigned int:28' may change value [-Wconversion]
   77 |         AGSEQ(g) = agnextseq(par, AGRAPH);
      |                    ^~~~~~~~~
  ...
  node.c: In function 'newnode':
  node.c:76:16: warning: conversion from 'uint64_t' {aka 'long unsigned int'} to
    'unsigned int:28' may change value [-Wconversion]
   76 |     AGSEQ(n) = seq;
      |                ^~~
  ...
  node.c: In function 'agnodebefore':
  node.c:359:22: warning: conversion from 'uint64_t' {aka 'long unsigned int'}
    to 'unsigned int:28' may change value [-Wconversion]
  359 |         AGSEQ(snd) = (g->clos->seq[AGNODE] + 2);
      |                      ^

In practice, ingesting a graph of this size is not achievable, so these
overflows cannot occur.

This change introduces assertions and casts in these cases to explain the
assumptions to the compiler. It squashes the above warnings. In future, perhaps
these fields should all be made to all consistently use the same type.
lib/cgraph/cghdr.h
lib/cgraph/edge.c
lib/cgraph/graph.c
lib/cgraph/node.c