git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] sequencer: clarify intention to break out of loop

From
MÅMartin Ågren <martin.agren@gmail.com>
Date
Oct 28, 2018, 15:31 UTC
Message-ID
<20181028153145.25734-1-martin.agren@gmail.com>

When we find a space, we set `len = i`, which gives us the answer we are looking for, but which also breaks out of the loop through these steps:

  1. `len = i`
  2. `i = i + 1`
  3. Is `i < len`? No, so break out.

Since `i` is signed, step 2 is undefined if `i` has the value `INT_MAX`. It can't actually have that value, but that doesn't stop my copy of gcc 7.3.0 from throwing the following:

> sequencer.c:2853:3: error: assuming signed overflow does not occur when
> assuming that (X + c) < X is always false [-Werror=strict-overflow]
>    for (i = 0; i < len; i++)
>    ^~~

That is, the compiler has realized that the code is essentially evaluating "(len + 1) < len" and that for `len = INT_MAX`, this is undefined behavior. What it hasn't figured out is that if `i` and `len` are both `INT_MAX` after step 1, then `len` must have had a value larger than `INT_MAX` before that step, which it can't have had.

Let's be explicit about breaking out of the loop. This helps the compiler grok our intention. As a bonus, it might make it (even) more obvious to human readers that the loop stops at the first space.

While at it, reduce the scope of `i`.
Signed-off-by: Martin Ågren <martin.agren@gmail.com>
---
 sequencer.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 0c164d5f98..a351638ad9 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2829,7 +2829,7 @@ static int do_reset(const char *name, int len, struct replay_opts *opts)
 	struct tree_desc desc;
 	struct tree *tree;
 	struct unpack_trees_options unpack_tree_opts;
-	int ret = 0, i;
+	int ret = 0;
 
 	if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0)
 		return -1;
@@ -2849,10 +2849,14 @@ static int do_reset(const char *name, int len, struct replay_opts *opts)
 		}
 		oidcpy(&oid, &opts->squash_onto);
 	} else {
+		int i;
 		/* Determine the length of the label */
-		for (i = 0; i < len; i++)
-			if (isspace(name[i]))
+		for (i = 0; i < len; i++) {
+			if (isspace(name[i])) {
 				len = i;
+				break;
+			}
+		}
 
 		strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name);
 		if (get_oid(ref_name.buf, &oid) &&
-- 
2.19.1.593.gc670b1f876.dirty
Next: Eric Sunshine
Message 1 of 8 in “sequencer: clarify intention to break out of loop”
  1. sequencer: clarify intention to break out of loopMartin Ågren, Oct 28, 2018
  2. Eric SunshineOct 28, 2018
  3. Martin ÅgrenOct 28, 2018
  4. Junio C HamanoOct 29, 2018
  5. sequencer: break out of loop explicitlyMartin Ågren, Oct 30, 2018
  6. Johannes SchindelinOct 31, 2018
  7. Eric SunshineOct 31, 2018
  8. Martin ÅgrenOct 31, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.