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

--- Comment #13 from Martin Sebor <msebor at gcc dot gnu.org> ---
Here's a reduced test case that reproduces the problem with an x86_64-linux GCC
in ILP32 mode:

$ cat pr103121.C && gcc -O2 -S -Wall -m32 pr103121.C
typedef typeof (sizeof 0) size_t;

struct tree_node {
  const char *str;
  unsigned len;
};

typedef tree_node *tree;
extern tree get_identifier_with_length (const char *, size_t);
extern tree get_identifier (const char *);
tree decl_assembler_name (tree);

tree cdtor_comdat_group (tree complete, tree base)
{
  tree complete_name = decl_assembler_name (complete);
  tree base_name = decl_assembler_name (base);

  char *grp_name = (char *) __builtin_alloca (complete_name->len + 1);

  const char *p = complete_name->str;
  const char *q = base_name->str;

  size_t i;
  bool diff_seen = false;

  for (i = 0; i < complete_name->len; i++)
    if (p[i] == q[i])
      grp_name[i] = p[i];
    else
      diff_seen = true;

  grp_name[i] = '\0';

  if (!diff_seen)
    __builtin_abort ();

  return get_identifier (grp_name);
}
pr103121.C: In function ‘tree_node* cdtor_comdat_group(tree, tree)’:
pr103121.C:32:15: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
   32 |   grp_name[i] = '\0';
      |   ~~~~~~~~~~~~^~~~~~
pr103121.C:18:46: note: at offset 1 into destination object of size 1 allocated
by ‘__builtin_alloca’
   18 |   char *grp_name = (char *) __builtin_alloca (complete_name->len + 1);
      |                             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~


An annotated ranger dump is below:

;; Function cdtor_comdat_group

=========== BB 2 ============
Imports: _1  
Exports: _1  
Relational : (_2 != _1)
    <bb 2> [local count: 118111600]:
    _20 = decl_assembler_name (complete_18(D));
    _23 = decl_assembler_name (base_21(D));
    _1 = _20->len;
    _2 = _1 + 1;
    grp_name_25 = __builtin_alloca (_2);
    p_26 = _20->str;
    q_27 = _23->str;
    if (_1 != 0)
      goto <bb 10>; [89.00%]
    else
      goto <bb 6>; [11.00%]

grp_name_25 : char * [1B, +INF]
2->10  (T) _1 :         unsigned int [1, +INF]
2->10  (T) _2 :         unsigned int [0, 0][2, +INF]
2->6  (F) _1 :  unsigned int [0, 0]
2->6  (F) _2 :  unsigned int [1, 1]

=========== BB 10 ============
    <bb 10> [local count: 105119324]:


=========== BB 3 ============
Imports: _4  _6  
Exports: _4  _6  
Equivalence set : [_6]
Equivalence set : [_4]
    <bb 3> [local count: 955630225]:
    # i_35 = PHI <i_33(11), 0(10)>
    # diff_seen_38 = PHI <diff_seen_13(11), 0(10)>
    _4 = MEM[(const char *)p_26 + i_35 * 1];
    _6 = MEM[(const char *)q_27 + i_35 * 1];
    if (_4 == _6)
      goto <bb 4>; [34.00%]
    else
      goto <bb 5>; [66.00%]

i_35 : size_t [0, 4294967294]

=========== BB 4 ============
i_35    size_t [0, 4294967294]
Equivalence set : [_4, _6]
    <bb 4> [local count: 324914280]:
    MEM[(char *)grp_name_25 + i_35 * 1] = _4;


=========== BB 5 ============
Imports: _10  i_35  
Exports: _10  i_33  i_35  
         i_33 : i_35(I)  
i_35    size_t [0, 4294967294]
Relational : (i_33 > i_35)
    <bb 5> [local count: 955630225]:
    # diff_seen_13 = PHI <diff_seen_38(4), 1(3)>
    i_33 = i_35 + 1;
    _10 = _20->len;
    if (_10 > i_33)
      goto <bb 11>; [89.00%]
    else
      goto <bb 7>; [11.00%]

i_33 : size_t [1, +INF]
5->11  (T) _10 :        unsigned int [2, +INF]
5->11  (T) i_33 :       size_t [1, 4294967294]
5->11  (T) i_35 :       size_t [0, 4294967293]
5->7  (F) i_33 :        size_t [1, +INF]
5->7  (F) i_35 :        size_t [0, 4294967294]

=========== BB 11 ============
diff_seen_13    bool VARYING
i_33    size_t [1, 4294967294]
Relational : (_10 > i_35)
Relational : (_10 > i_33)
    <bb 11> [local count: 850510901]:
    goto <bb 3>; [100.00%]


=========== BB 6 ============
    <bb 6> [local count: 12992276]:
    *grp_name_25 = 0;
    goto <bb 8>; [100.00%]


=========== BB 7 ============
Imports: diff_seen_13  
Exports: diff_seen_13  
diff_seen_13    bool VARYING
i_33    size_t [1, +INF]
Relational : (_10 <= i_33)
    <bb 7> [local count: 105119324]:
    _11 = grp_name_25 + i_33;  <<< grp_name_25 points to a block of size 1
    *_11 = 0;                  <<< -Wstringop-overflow
    if (diff_seen_13 != 0)
      goto <bb 9>; [100.00%]
    else
      goto <bb 8>; [0.00%]

_11 : char * [1B, +INF]
7->8  (F) diff_seen_13 :        bool [0, 0]
7->9  (T) diff_seen_13 :        bool [1, 1]

=========== BB 8 ============
    <bb 8> [count: 0]:
    __builtin_abort ();


=========== BB 9 ============
    <bb 9> [local count: 118111600]:
    _30 = get_identifier (grp_name_25);
    return _30;

Non-varying global ranges:
=========================:
_11  : char * [1B, +INF]
grp_name_25  : char * [1B, +INF]
i_33  : size_t [1, +INF]
i_35  : size_t [0, 4294967294]

Reply via email to