@@ -2498,9 +2498,9 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
24982498
24992499 /* The number of bytes to add to or subtract from the size of the provided
25002500 buffer based on an offset into an array or an array element reference.
2501- Although intermediate results may be negative (as in a[3] - 2) the final
2502- result cannot be. */
2503- HOST_WIDE_INT adjust = 0 ;
2501+ Although intermediate results may be negative (as in a[3] - 2) a valid
2502+ final result cannot be. */
2503+ offset_int adjust = 0 ;
25042504 /* True when the size of the entire destination object should be used
25052505 to compute the possibly optimistic estimate of the available space. */
25062506 bool use_obj_size = false;
@@ -2524,15 +2524,15 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
25242524 is a constant. */
25252525 if (TREE_CODE (oper ) == POINTER_PLUS_EXPR )
25262526 {
2527- /* If the offset is comple -time constant, use it to compute a more
2527+ /* If the offset is compile -time constant, use it to compute a more
25282528 accurate estimate of the size of the buffer. Since the operand
25292529 of POINTER_PLUS_EXPR is represented as an unsigned type, convert
25302530 it to signed first.
25312531 Otherwise, use the size of the entire array as an optimistic
25322532 estimate (this may lead to false negatives). */
25332533 tree adj = TREE_OPERAND (oper , 1 );
25342534 if (CONSTANT_CLASS_P (adj ))
2535- adjust += tree_to_shwi (convert (ssizetype , adj ));
2535+ adjust += wi :: to_offset (convert (ssizetype , adj ));
25362536 else
25372537 use_obj_size = true;
25382538
@@ -2559,9 +2559,9 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
25592559 not a compile-time constant, use the index to determine the
25602560 size of the buffer. Otherwise, use the entire array as
25612561 an optimistic estimate of the size. */
2562- const_tree adj = TREE_OPERAND (oper , 1 );
2562+ const_tree adj = fold_non_dependent_expr ( TREE_OPERAND (oper , 1 ) );
25632563 if (!use_obj_size && CONSTANT_CLASS_P (adj ))
2564- adjust += tree_to_shwi (adj );
2564+ adjust += wi :: to_offset (adj );
25652565 else
25662566 {
25672567 use_obj_size = true;
@@ -2580,25 +2580,34 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
25802580 members from arrays of unspecified size. */
25812581 bool compref = TREE_CODE (oper ) == COMPONENT_REF ;
25822582
2583+ /* For COMPONENT_REF (i.e., a struct member) the size of the entire
2584+ enclosing struct. Used to validate the adjustment (offset) into
2585+ an array at the end of a struct. */
2586+ offset_int compsize = 0 ;
2587+
25832588 /* Descend into a struct or union to find the member whose address
25842589 is being used as the argument. */
25852590 if (TREE_CODE (oper ) == COMPONENT_REF )
25862591 {
2592+ tree comptype = TREE_TYPE (TREE_OPERAND (oper , 0 ));
2593+ compsize = wi ::to_offset (TYPE_SIZE_UNIT (comptype ));
2594+
25872595 tree op0 = oper ;
25882596 while (TREE_CODE (op0 = TREE_OPERAND (op0 , 0 )) == COMPONENT_REF );
25892597 if (VAR_P (op0 ))
25902598 var_decl = op0 ;
25912599 oper = TREE_OPERAND (oper , 1 );
25922600 }
25932601
2594- if ((addr_expr || !POINTER_TYPE_P (TREE_TYPE (oper )))
2602+ tree opertype = TREE_TYPE (oper );
2603+ if ((addr_expr || !POINTER_TYPE_P (opertype ))
25952604 && (VAR_P (oper )
25962605 || TREE_CODE (oper ) == FIELD_DECL
25972606 || TREE_CODE (oper ) == PARM_DECL ))
25982607 {
25992608 /* A possibly optimistic estimate of the number of bytes available
26002609 in the destination buffer. */
2601- unsigned HOST_WIDE_INT bytes_avail = 0 ;
2610+ offset_int bytes_avail = 0 ;
26022611 /* True when the estimate above is in fact the exact size
26032612 of the destination buffer rather than an estimate. */
26042613 bool exact_size = true;
@@ -2613,47 +2622,42 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
26132622 /* Use the size of the entire array object when the expression
26142623 refers to a variable or its size depends on an expression
26152624 that's not a compile-time constant. */
2616- bytes_avail = tree_to_uhwi (DECL_SIZE_UNIT (oper ));
2625+ bytes_avail = wi :: to_offset (DECL_SIZE_UNIT (oper ));
26172626 exact_size = !use_obj_size ;
26182627 }
2619- else if (TYPE_SIZE_UNIT (TREE_TYPE (oper ))
2620- && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (oper ))))
2628+ else if (tree opersize = TYPE_SIZE_UNIT (opertype ))
26212629 {
26222630 /* Use the size of the type of the destination buffer object
2623- as the optimistic estimate of the available space in it. */
2624- bytes_avail = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (oper )));
2631+ as the optimistic estimate of the available space in it.
2632+ Use the maximum possible size for zero-size arrays and
2633+ flexible array members (except of initialized objects
2634+ thereof). */
2635+ if (TREE_CODE (opersize ) == INTEGER_CST )
2636+ bytes_avail = wi ::to_offset (opersize );
26252637 }
2626- else if (var_decl )
2627- {
2628- /* Constructing into a buffer provided by the flexible array
2629- member of a declared object (which is permitted as a G++
2630- extension). If the array member has been initialized,
2631- determine its size from the initializer. Otherwise,
2632- the array size is zero. */
2633- bytes_avail = 0 ;
2634-
2635- if (tree init = find_field_init (oper , DECL_INITIAL (var_decl )))
2636- bytes_avail = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (init )));
2637- }
2638- else
2638+
2639+ if (bytes_avail == 0 )
26392640 {
2640- /* Bail if neither the size of the object nor its type is known. */
2641- return ;
2641+ if (var_decl )
2642+ {
2643+ /* Constructing into a buffer provided by the flexible array
2644+ member of a declared object (which is permitted as a G++
2645+ extension). If the array member has been initialized,
2646+ determine its size from the initializer. Otherwise,
2647+ the array size is zero. */
2648+ if (tree init = find_field_init (oper , DECL_INITIAL (var_decl )))
2649+ bytes_avail = wi ::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (init )));
2650+ }
2651+ else
2652+ bytes_avail = (wi ::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node ))
2653+ - compsize );
26422654 }
26432655
2644- tree_code oper_code = TREE_CODE (TREE_TYPE ( oper ) );
2656+ tree_code oper_code = TREE_CODE (opertype );
26452657
26462658 if (compref && oper_code == ARRAY_TYPE )
26472659 {
2648- /* Avoid diagnosing flexible array members (which are accepted
2649- as an extension and diagnosed with -Wpedantic) and zero-length
2650- arrays (also an extension).
2651- Overflowing construction in one-element arrays is diagnosed
2652- only at level 2. */
2653- if (bytes_avail == 0 && !var_decl )
2654- return ;
2655-
2656- tree nelts = array_type_nelts_top (TREE_TYPE (oper ));
2660+ tree nelts = array_type_nelts_top (opertype );
26572661 tree nelts_cst = maybe_constant_value (nelts );
26582662 if (TREE_CODE (nelts_cst ) == INTEGER_CST
26592663 && integer_onep (nelts_cst )
@@ -2662,29 +2666,35 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
26622666 return ;
26632667 }
26642668
2665- /* The size of the buffer can only be adjusted down but not up. */
2666- gcc_checking_assert (0 <= adjust );
2667-
26682669 /* Reduce the size of the buffer by the adjustment computed above
26692670 from the offset and/or the index into the array. */
2670- if (bytes_avail < static_cast < unsigned HOST_WIDE_INT > ( adjust ) )
2671+ if (bytes_avail < adjust || adjust < 0 )
26712672 bytes_avail = 0 ;
26722673 else
2673- bytes_avail -= adjust ;
2674+ {
2675+ tree elttype = (TREE_CODE (opertype ) == ARRAY_TYPE
2676+ ? TREE_TYPE (opertype ) : opertype );
2677+ if (tree eltsize = TYPE_SIZE_UNIT (elttype ))
2678+ {
2679+ bytes_avail -= adjust * wi ::to_offset (eltsize );
2680+ if (bytes_avail < 0 )
2681+ bytes_avail = 0 ;
2682+ }
2683+ }
26742684
26752685 /* The minimum amount of space needed for the allocation. This
26762686 is an optimistic estimate that makes it possible to detect
26772687 placement new invocation for some undersize buffers but not
26782688 others. */
2679- unsigned HOST_WIDE_INT bytes_need ;
2689+ offset_int bytes_need ;
26802690
26812691 if (CONSTANT_CLASS_P (size ))
2682- bytes_need = tree_to_uhwi (size );
2692+ bytes_need = wi :: to_offset (size );
26832693 else if (nelts && CONSTANT_CLASS_P (nelts ))
2684- bytes_need = tree_to_uhwi (nelts )
2685- * tree_to_uhwi (TYPE_SIZE_UNIT (type ));
2694+ bytes_need = ( wi :: to_offset (nelts )
2695+ * wi :: to_offset (TYPE_SIZE_UNIT (type ) ));
26862696 else if (tree_fits_uhwi_p (TYPE_SIZE_UNIT (type )))
2687- bytes_need = tree_to_uhwi (TYPE_SIZE_UNIT (type ));
2697+ bytes_need = wi :: to_offset (TYPE_SIZE_UNIT (type ));
26882698 else
26892699 {
26902700 /* The type is a VLA. */
@@ -2703,9 +2713,8 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
27032713 : "placement new constructing an object of type "
27042714 "%<%T [%wu]%> and size %qwu in a region of type %qT "
27052715 "and size at most %qwu" ,
2706- type , tree_to_uhwi (nelts ), bytes_need ,
2707- TREE_TYPE (oper ),
2708- bytes_avail );
2716+ type , tree_to_uhwi (nelts ), bytes_need .to_uhwi (),
2717+ opertype , bytes_avail .to_uhwi ());
27092718 else
27102719 warning_at (loc , OPT_Wplacement_new_ ,
27112720 exact_size ?
@@ -2715,8 +2724,8 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
27152724 : "placement new constructing an array of objects "
27162725 "of type %qT and size %qwu in a region of type %qT "
27172726 "and size at most %qwu" ,
2718- type , bytes_need , TREE_TYPE ( oper ) ,
2719- bytes_avail );
2727+ type , bytes_need . to_uhwi (), opertype ,
2728+ bytes_avail . to_uhwi () );
27202729 else
27212730 warning_at (loc , OPT_Wplacement_new_ ,
27222731 exact_size ?
@@ -2725,8 +2734,8 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
27252734 : "placement new constructing an object of type %qT "
27262735 "and size %qwu in a region of type %qT and size "
27272736 "at most %qwu" ,
2728- type , bytes_need , TREE_TYPE ( oper ) ,
2729- bytes_avail );
2737+ type , bytes_need . to_uhwi (), opertype ,
2738+ bytes_avail . to_uhwi () );
27302739 }
27312740 }
27322741}
0 commit comments