https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120929
--- Comment #20 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to qinzhao from comment #16) > (In reply to Siddhesh Poyarekar from comment #12) > > This is interesting here's the IR dump right after objsz: > > > > The key bit is: > > > > map2_4 = __builtin_malloc (8); > > pin_pointer (&buf); > > _1 = &map2_4->magic; > > _9 = __builtin_malloc (9); > > *_1 = _9; > > goto <bb 4>; [100.00%] > > > > <bb 3> [local count: 1073741824]: > > b = ""; > > ptr_10 = *_1; > > _11 = 8; > > __builtin___memcpy_chk (ptr_10, &b, 9, _11); > > > > where *_1 gets updated to _9, but when one follows the *_1 through ptr_10, > > it doesn't end up with _9, the def statement is: > > > > _1 = &map2_4->magic; > > > > which leads to the incorrect value for the object size. This is because the > > pass doesn't know that a MEM_REF could be the LHS (for the zero byte offset > > case like it is here) for an assignment, i.e. this: > > > > *_1 = _9; > > There are two possible solutions to the above issue: > > A. Add handling for *_1 = _9 to enable the object size propagate through the > correct data flow path. > Or > B. in my latest change that triggered this issue: > > /* Handle the following stmt #2 to propagate the size from the > stmt #1 to #3: > 1 _1 = .ACCESS_WITH_SIZE (_3, _4, 1, 0, -1, 0B); > 2 _5 = *_1; > 3 _6 = __builtin_dynamic_object_size (_5, 1); > */ > else if (TREE_CODE (rhs) == MEM_REF > && POINTER_TYPE_P (TREE_TYPE (rhs)) > && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME > && integer_zerop (TREE_OPERAND (rhs, 1))) > reexamine = merge_object_sizes (osi, var, TREE_OPERAND (rhs, > 0)); > > > I feel that propagating the size through _5 = *_1 might not be correct in > general, we should only limit it to the case when the RHS is a pointer > defined by .ACCESS_WITH_SIZE? > > what do you think? I'm confused as to what this does for the case in question. The IL is _1 = &map2_4->magic; _9 = __builtin_malloc (9); *_1 = _9; ptr_10 = *_1; _11 = __builtin_dynamic_object_size (ptr_10, 0); ptr_10 is equal to _9, but the objsize dump suggests we are instead looking at the size of what _1 points to, instead of the size of what *_1 points to?! That would be completely incorrect of course! Also if that's not the case but we still look at *_1 but with _1 from the earlier def that cannot be done either because you skipped an intermediate definition of *_1. I think the code is obviously bogus. Quoting more in full: else if (gimple_assign_single_p (stmt) || gimple_assign_unary_nop_p (stmt)) { if (TREE_CODE (rhs) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (rhs))) reexamine = merge_object_sizes (osi, var, rhs); /* Handle the following stmt #2 to propagate the size from the stmt #1 to #3: 1 _1 = .ACCESS_WITH_SIZE (_3, _4, 1, 0, -1, 0B); 2 _5 = *_1; 3 _6 = __builtin_dynamic_object_size (_5, 1); */ else if (TREE_CODE (rhs) == MEM_REF && POINTER_TYPE_P (TREE_TYPE (rhs)) && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME && integer_zerop (TREE_OPERAND (rhs, 1))) reexamine = merge_object_sizes (osi, var, TREE_OPERAND (rhs, 0)); so for _1 = _2; we merge from _2. For _1 = *_2; we _also_ merge from _2. But those are semantically not the same! IMO this change was bogus and should be reverted.