https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106463

            Bug ID: 106463
           Summary: Incorrect value for loop terminating test. for loop
                    runs when it should not.
           Product: gcc
           Version: 11.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gordon.lack at dsl dot pipex.com
  Target Milestone: ---

Created attachment 53371
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53371&action=edit
Preprocessed .i file

For the simple loop:

    int maxnum = power10(n);
    for (int unum = 0; unum < maxnum; unum++) {
        some code...
    }

the loop will run (multiple times) even if maxnum is -ve (a result of an
overflow in powr10).

This happens for -O3 and -O2, but not -O1 or -O0 using gcc11.2.0 (on Kubuntu
22.04).
Also happens on gcc:
   10.2.1
    7.4.0

On 4.4.7 (Centos6) it only passes through the loop once (which is still wrong).

The raw test.c file to show the problem is short:
==========================================================
#include <stdlib.h>
#include <string.h>

static int power10(int exp) {
    int res = 1;
    while (exp-- > 0) res *= 10;
    return res;   
}

static char testname[32] = "test";
static int namelen = 4;
static char name[32];

void *bfind(char *fn, int cflag, int bflag) {
    snprintf(fn, 32, "%d %d", cflag, bflag);
    return fn;
}

int main(int argc, char *argv[]) {
    if (!argv[1]) return 2;
    int numlen = atoi(argv[1]);
    int maxnum = power10(numlen);
    printf("Loop max %d\n", maxnum);
    for (int unum = 0; unum < maxnum; unum++) {
        printf("Loop var %d (max %d)\n", unum, maxnum);
        printf("Loop end cond %d\n", (unum < maxnum));
        snprintf(testname + namelen, 28, "%d", unum);
        if (bfind(testname, 0, 0) == NULL) {
            strcpy(name, testname);
            return 0;
        }
    }
    return 1;
}

Reply via email to