aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog62
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog402
-rw-r--r--gcc/ada/exp_ch6.adb5
-rw-r--r--gcc/c-family/ChangeLog22
-rw-r--r--gcc/c-family/c-attribs.cc44
-rw-r--r--gcc/c-family/c-gimplify.cc28
-rw-r--r--gcc/c-family/c-ubsan.cc316
-rw-r--r--gcc/c/ChangeLog14
-rw-r--r--gcc/c/c-decl.cc91
-rw-r--r--gcc/c/c-typeck.cc60
-rw-r--r--gcc/cobol/ChangeLog8
-rw-r--r--gcc/cobol/Make-lang.in2
-rw-r--r--gcc/cobol/parse.y2
-rw-r--r--gcc/config/aarch64/aarch64-simd.md30
-rw-r--r--gcc/config/i386/driver-i386.cc2
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/typeck.cc62
-rw-r--r--gcc/doc/extend.texi41
-rw-r--r--gcc/fortran/ChangeLog22
-rw-r--r--gcc/fortran/coarray.cc11
-rw-r--r--gcc/fortran/trans-intrinsic.cc2
-rw-r--r--gcc/m2/ChangeLog6
-rw-r--r--gcc/m2/gm2-libs-iso/IOChanUtils.def8
-rw-r--r--gcc/m2/gm2-libs-iso/IOChanUtils.mod12
-rw-r--r--gcc/testsuite/ChangeLog125
-rw-r--r--gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob4
-rw-r--r--gcc/testsuite/g++.dg/parse/pr120471.C42
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr120471.C21
-rw-r--r--gcc/testsuite/gcc.dg/flex-array-counted-by.c2
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-1.c34
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-2.c10
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-3.c127
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c6
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c6
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c10
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c10
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4.c77
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-5.c56
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-6.c56
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-7.c32
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by.c111
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c51
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c42
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c42
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c40
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c46
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c36
-rw-r--r--gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c40
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c2
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c2
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c2
-rw-r--r--gcc/testsuite/gfortran.dg/coarray/coindexed_7.f9024
-rw-r--r--gcc/testsuite/gnat.dg/specs/finalizable2.ads21
-rw-r--r--gcc/tree-object-size.cc19
-rw-r--r--gcc/tree-vect-loop.cc1
-rw-r--r--gcc/tree.cc62
-rw-r--r--gcc/tree.h4
58 files changed, 2265 insertions, 162 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 78239f0..9004d1c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,65 @@
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * tree-object-size.cc (access_with_size_object_size): Update comments
+ for pointers with .ACCESS_WITH_SIZE.
+ (collect_object_sizes_for): Propagate size info through GIMPLE_ASSIGN
+ for pointers with .ACCESS_WITH_SIZE.
+
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * doc/extend.texi: Extend counted_by attribute to pointer fields in
+ structures. Add one more requirement to pointers with counted_by
+ attribute.
+
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/120471
+ * tree.h (address_invariant_p): New function.
+ * tree.cc (address_invariant_p): New function.
+ (tree_invariant_p_1): Use it for ADDR_EXPR handling. Formatting
+ tweak.
+
+2025-07-01 Remi Machet <rmachet@nvidia.com>
+
+ * config/aarch64/aarch64-simd.md (*shrn_to_subhn_<mode>): Add pattern
+ converting mvn+shrn into mvni+subhn.
+
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/120608
+ * passes.def (pass_musttail): Move before pass_sanopt.
+ * tree-tailcall.cc (empty_eh_cleanup): Handle GIMPLE_RESX
+ which doesn't throw externally through recursion on single
+ eh edge (if any and cnt still allows that).
+ (find_tail_calls): Add ESUCC, IGNORED_EDGES and MUST_SEE_BBS
+ arguments. Handle GIMPLE_CONDs for non-simplified cleanups with
+ finally_tmp temporaries both on backward and forward walks, adjust
+ recursive call.
+ (tree_optimize_tail_calls_1): Adjust find_tail_calls callers.
+
+2025-07-01 Ezra Sitorus <ezra.sitorus@arm.com>
+
+ * config/aarch64/aarch64-sys-regs.def: Copy from Binutils.
+
+2025-07-01 H.J. Lu <hjl.tools@gmail.com>
+
+ PR debug/120902
+ * print-tree.cc (debug with const tree_node *): Call debug_tree
+ instead of debug.
+
+2025-07-01 Yuao Ma <c8ef@outlook.com>
+
+ * fold-const-call.cc (fold_const_call_ss): Constant fold for
+ single arg pi-based trigonometric builtins.
+ (fold_const_call_sss): Constant fold for double arg pi-based
+ trigonometric builtins.
+ * fold-const.cc (negate_mathfn_p): asinpi/atanpi is odd func.
+ (tree_call_nonnegative_warnv_p): acospi always non-neg,
+ asinpi/atanpi non-neg iff arg non-neg.
+ * tree-call-cdce.cc (can_test_argument_range): Add acospi/asinpi.
+ (edom_only_function): Add acospi/asinpi/cospi/sinpi.
+ (get_no_error_domain): Add acospi/asinpi.
+
2025-06-30 Jeff Law <jlaw@ventanamicro.com>
PR rtl-optimization/120242
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index ac92899..46e9463 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250701
+20250702
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 88b27a8..8aaa006 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,405 @@
+2025-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/120705
+ * exp_ch6.adb (Needs_BIP_Collection): Always return False if the
+ type has relaxed finalization.
+
+2025-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/s-valuef.adb (Integer_to_Fixed): Restore rounding of the
+ first scaled divide operation.
+
+2025-07-01 Piotr Trojanek <trojanek@adacore.com>
+
+ * gnat1drv.adb (Gnat1drv): Do minimal decoration of the spec and body
+ of an ignored ghost compilation unit.
+
+2025-07-01 Piotr Trojanek <trojanek@adacore.com>
+
+ * ali.ads (Unit_Record): Fix grammar in comment.
+ * bindgen.adb (Num_Elab_Calls, Num_Primary_Stacks): Remove counters
+ that were only incremented and never actually used.
+
+2025-07-01 Tonu Naks <naks@adacore.com>
+
+ * libgnat/s-valuer.adb (Scan_Decimal_Digits,
+ Scan_Integral_Digits): fix condition for rejecting
+ underscore.
+
+2025-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/s-valued.adb (Integer_To_Decimal): Deal specifically with
+ Val = 2**(Int'Size - 1) if Minus is not set. Exit the loops when V
+ saturates to 0 in the case of (huge) negative exponents. Use Base
+ instead of B consistently in unsigned computations.
+ * libgnat/s-valuef.adb (Integer_To_Fixed): Use Base instead of B
+ consistently in unsigned computations.
+
+2025-07-01 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_ch4.adb (Fixup_Universal_Fixed_Operation): Move to spec.
+ * exp_ch4.ads (Fixup_Universal_Fixed_Operation): Move from body.
+ * exp_spark.adb (Expand_SPARK): Call a fixup expansion routine.
+
+2025-07-01 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_ch3.adb (Build_Heap_Or_Pool_Allocator): Test not Has_Relaxed_Finalization
+ as a guard against retrieving BIP_Collection formal (and related code).
+
+2025-07-01 Javier Miranda <miranda@adacore.com>
+
+ * exp_ch3.adb (Build_Untagged_Record_Equality): Report the
+ warning when no component of an untagged record type U is a
+ record type, and the type C of some of its components has
+ defined its user-defined equality operator "=".
+ * exp_ch4.adb (Expand_Composite_Equality): Report the warning
+ calling Warn_On_Ignored_Equality_Operator.
+ * sem_warn.ads (Warn_On_Ignored_Equality_Operator): New subprogram.
+ * sem_warn.adb (Warn_On_Ignored_Equality_Operator): Factorize code
+ reporting the warning.
+
+2025-07-01 Tonu Naks <naks@adacore.com>
+
+ * libgnat/a-ngelfu.adb: conditional computation of X^2
+
+2025-07-01 Steve Baird <baird@adacore.com>
+
+ * Makefile.rtl: Add entry for new unit's object file.
+ * libgnat/s-casuti.adb: Remove bodies of subprograms that were moved
+ to the new unit.
+ * libgnat/s-casuti.ads: Replace (with renamings) declarations for
+ subprograms that moved to the new unit.
+ * libgnat/s-cautns.adb: Body for new unit (a new source file).
+ * libgnat/s-cautns.ads: Spec for new unit (a new source file).
+ * libgnat/s-valuti.adb: Use the new unit instead of the old one.
+ * gcc-interface/Make-lang.in: Add entries for new unit's object file.
+ * gcc-interface/Makefile.in: Likewise.
+
+2025-07-01 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_ch3.adb (Constrain_Corresponding_Record): Inherit Class_Wide_Type on the
+ created constrained subtype.
+
+2025-07-01 Artur Pietrek <pietrek@adacore.com>
+
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst: add
+ GNAT LLVM explicit selection in GPR file
+ * gnat_ugn.texi: Regenerate.
+
+2025-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch7.adb (Shift_Address_For_Descriptor): Add dummy variable
+ to make sure that System_Storage_Elements is loaded.
+
+2025-07-01 Ronan Desplanques <desplanques@adacore.com>
+
+ * doc/gnat_rm/gnat_language_extensions.rst: Document new extension.
+ * gen_il-fields.ads (Opt_Field_Enum): Add new fields.
+ * gen_il-types.ads (N_Loop_Flow_Statement, N_Continue_Statement): New
+ node kinds.
+ * gen_il-gen-gen_nodes.adb (N_Loop_Flow_Statement): New abstract node
+ kind.
+ (N_Continue_Statement): New node kind.
+ (N_Exit_Statement): Reparent below N_Loop_Flow_Statement.
+ * sinfo.ads (N_Continue_Statement): Add description.
+ * sinfo-utils.ads (Loop_Flow_Keyword): New function.
+ * sinfo-utils.adb (Loop_Flow_Keyword): New function.
+ * gen_il-gen-gen_entities.adb (E_Loop): Add new field.
+ * einfo.ads (Continue_Mark): Document new field.
+ * sprint.adb (Sprint_Node_Actual): Update for new node kind.
+ * snames.ads-tmpl: Add new keyword.
+ * par-ch5.adb (P_Continue_Statement, Parse_Loop_Flow_Statement): New
+ functions.
+ (P_Sequence_Of_Statements): Handle continue statements.
+ (P_Exit_Statement): Use Parse_Loop_Flow_Statement.
+ * sem.adb (Analyze): Handle new node kind.
+ * sem_ch5.adb (Analyze_Loop_Flow_Statement): New function.
+ (Analyze_Continue_Statement): New procedure.
+ (Analyze_Exit_Statement): Use new Analyze_Loop_Flow_Statement function.
+ * sem_ch5.ads (Analyze_Continue_Statement): New procedure.
+ * expander.adb (Expand): Handle new node kind.
+ * exp_ch5.ads (Expand_N_Continue_Statement): New procedure.
+ * exp_ch5.adb (Expand_Loop_Flow_Statement): New procedure.
+ (Expand_N_Continue_Statement): New procedure.
+ (Expand_N_Exit_Statement): Use new Expand_Loop_Flow_Statement
+ procedure.
+ (Build_Formal_Container_Iteration): Always reuse original loop entity.
+ * gnat_rm.texi: Regenerate.
+
+2025-07-01 Bob Duff <duff@adacore.com>
+
+ * repinfo.adb (List_Entities):
+ Disable output in case of object renamings.
+
+2025-07-01 Aleksandra Pasek <pasek@adacore.com>
+
+ * libgnat/s-valuen.ads: Correct comment.
+
+2025-07-01 Alexandre Oliva <oliva@adacore.com>
+
+ * init.c: Include string.h.
+
+2025-07-01 Tonu Naks <naks@adacore.com>
+
+ * doc/gnat_rm.rst: remove ref to 2012 chapter
+ * doc/gnat_rm/about_this_guide.rst: remove ref to 2012 chapter
+ * doc/gnat_rm/compatibility_and_porting_guide.rst: update list of
+ supported versions
+ * doc/gnat_rm/implementation_of_ada_2012_features.rst: delete
+ * doc/gnat_rm/specialized_needs_annexes.rst: update list of
+ supported versions
+ * gnat_rm.texi: Regenerate.
+
+2025-07-01 Tonu Naks <naks@adacore.com>
+
+ * doc/gnat_rm/implementation_advice.rst: remove GLADE
+ * doc/gnat_rm/implementation_defined_characteristics.rst: remove GLADE
+ * doc/gnat_rm/specialized_needs_annexes.rst: remove GLADE
+ * doc/gnat_rm/the_gnat_library.rst: remove GLADE
+ * gnat_rm.texi: Regenerate.
+
+2025-07-01 Alexandre Oliva <oliva@adacore.com>
+
+ * adaint.c [__vxworks] (alloca): Redirect to builtin.
+
+2025-07-01 Ghjuvan Lacambre <lacambre@adacore.com>
+
+ * freeze.adb (Freeze_Record_Type): Check for CodePeer_Mode.
+
+2025-07-01 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch12.adb (Analyze_Subprogram_Instantiation): Move aspects when
+ instantiating subprogram as a library unit.
+
+2025-07-01 Ronan Desplanques <desplanques@adacore.com>
+
+ * exp_ch5.adb (Expand_N_Loop_Statement): Remove useless subexpressions.
+
+2025-07-01 Jose Ruiz <ruiz@adacore.com>
+
+ * doc/gnat_ugn/gnat_and_program_execution.rst: Add the
+ documentation about benefits of using sanitizers in
+ mixed-language applications.
+ * gnat_ugn.texi: Regenerate.
+
+2025-07-01 Viljar Indus <indus@adacore.com>
+
+ * atree.ads (Compile_Time_Pragma_Warnings): Removed.
+ * errout.adb (Initialize): Remove initialization for
+ Compile_Time_Pragma_Warnings.
+ (Error_Msg_Internal): Use Warning_As_Error_Kind in the
+ Error_Msg_Object. Set its value based on the reason the
+ warning was changed to an error.
+ (Write_JSON_Span): Adjust the code for Warn_Err.
+ (Output_Messages): Update the calculation for actual warnings
+ and errors by just using Warnings_Treated_As_Errors.
+ (Set_Msg_Text): Simply mark that we are dealing with a
+ run time message here. Move the code for the Warning_Mode to
+ Error_Msg_Internal.
+ * erroutc-pretty_emitter.adb (Write_Error_Msg_Line): Adjust the code
+ for Warn_Err. Use the Warn_As_Err_Tag token.
+ * erroutc.adb (Compilation_Errors): Simplify the implementation so
+ that it only checks for errors and warnings treated as errors.
+ (Decrease_Error_Msg_Count): Remove the count for
+ Compile_Time_Pragma_Warnings.
+ (dmsg): Adjust the code for changes to Warn_Err.
+ (Increase_Error_Msg_Count): Likewise and remove the count for
+ Compile_Time_Pragma_Warnings.
+ (Output_Msg_Text): Warnings converted to error by the
+ Warning_As_Error pragma and -gnatwE now use the error prefix
+ in their messages but only warnings changed by the pragma get
+ the [warning-as-error] tag.
+ (Output_Text_Within): Adjust the variable name for
+ Is_Runtime_Raise_Msg.
+ (Write_Error_Summary): Adjust printing of warnings so that it
+ just uses the counts for Warnings_Detected and
+ Warnings_Treated_As_Errors.
+ * erroutc.ads (Is_Runtime_Raise): renamed to Is_Runtime_Raise_Msg.
+ (Warning_As_Error_Kind): New type for marking the warning message
+ is treated as an error which also captures the reason for the
+ change. Historically each of the reasons will have a different way
+ of displaying the warning message.
+ (Error_Msg_Object.Warn_Err): Change type to Warning_As_Error_Kind.
+ (Kind_To_String): Warnings treated as errors originating from
+ the pragma or -gnatwE will return error where as warnings
+ originating from -gnatwe will return warning.
+ (Compilation_Errors): Update the documentation.
+ (Warn_As_Err_Tag): Constant string to be used when printing warnings
+ as errors.
+ * errutil.adb (Error_Msg): Adjust the code for Warn_Err.
+
+2025-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch7.adb (Shift_Address_For_Descriptor): New function.
+ (Make_Address_For_Finalize): Call above function.
+ (Make_Finalize_Address_Stmts): Likewise.
+ * exp_util.ads (Is_Constr_Array_Subt_Of_Unc_With_Controlled): New
+ predicate.
+ * exp_util.adb (Is_Constr_Array_Subt_Of_Unc_With_Controlled): Ditto.
+ (Remove_Side_Effects): Call above predicate.
+ * sem_ch3.adb (Analyze_Object_Declaration): Likewise.
+ * sem_ch4.adb (Analyze_Allocator): Allocate the bounds by setting
+ Is_Constr_Array_Subt_With_Bounds when appropriate.
+
+2025-07-01 Javier Miranda <miranda@adacore.com>
+
+ * sem_ch4.adb (Try_Object_Operation): Handle mutably tagged
+ class-wide type prefix.
+
+2025-07-01 Viljar Indus <indus@adacore.com>
+
+ * errout.adb (Error_Msg_Internal): Use the new
+ Warning_Treated_As_Error function.
+ * erroutc.adb (Get_Warning_Option): Add new version of this
+ function that operates on the Error_Msg_Object directly instead
+ of the Error_Id. Update the existing function to call the new
+ version interanlly.
+ (Get_Warning_Tag): Likewise.
+ (Warning_Treated_As_Error): Add a new method that combines the
+ checks for the error message itself and its tag.
+ * erroutc.ads (Get_Warning_Option): Add new spec.
+ (Get_Warning_Option): Likewise.
+ (Get_Warning_Option): Likewise.
+
+2025-07-01 Viljar Indus <indus@adacore.com>
+
+ * atree.ads: Add Compile_Time_Pragma_Warnings for counting
+ compile time warnings.
+ * errout.adb (Initialize): Initialize Compile_Time_Pragma_Warnings.
+ (Output_Messages): Use Compile_Time_Pragma_Warnings instead of
+ Count_Compile_Time_Pragma_Warnings.
+ * erroutc.adb (Compilation_Errors): Likewise.
+ (Count_Compile_Time_Pragma_Warnings): Removed.
+ (Decrease_Error_Msg_Count): Update Compile_Time_Pragma_Warnings.
+ (Increase_Error_Msg_Count): Likewise.
+ (Write_Error_Summary): Use Compile_Time_Pragma_Warnings instead of
+ Count_Compile_Time_Pragma_Warnings.
+ * erroutc.ads (Count_Compile_Time_Pragma_Warnings): Removed.
+
+2025-07-01 Viljar Indus <indus@adacore.com>
+
+ * errout.adb (Delete_Warning_And_Continuations): Use
+ Decrease_Error_Msg_Count to update the message counts.
+ (Delete_Warning): Likewise.
+ (To_Be_Removed): Likewise.
+
+2025-07-01 Viljar Indus <indus@adacore.com>
+
+ * errout.adb (Remove_Warning_Messages): Mark removed messages as
+ deleted.
+ * erroutc.adb (Purge_Messages): Likewise.
+
+2025-07-01 Martin Clochard <clochard@adacore.com>
+
+ * frontend.adb (Frontend): do not override GNATprove's setting for
+ Warn_On_Non_Local_Exception
+
+2025-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch4.adb (Analyze_Allocator): Do not set Etype to itself.
+
+2025-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_util.adb (Finalize_Address): Do not go to the root type for
+ array types.
+
+2025-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/s-valuer.ads (System.Value_R): Remove Round parameter.
+ (Scan_Raw_Real): Replace Extra with Extra2 and adjust the comment.
+ (Value_Raw_Real): Likewise.
+ * libgnat/s-valuer.adb (Round_Extra): Delete.
+ (Scan_Decimal_Digits): Replace Extra with Extra2 and adjust the
+ implementation.
+ (Scan_Integral_Digits): Replace Extra with Extra2 and Extra_Rounded
+ with Extra2_Filled and adjust the implementation.
+ (Scan_Raw_Real): Replace Extra with Extra2 and adjust the
+ implementation.
+ (Value_Raw_Real): Likewise.
+ * libgnat/s-valrea.adb (Impl): Remove actual for Round formal.
+ * libgnat/s-valued.adb (Impl): Likewise.
+ (Integer_to_Decimal): Replace Extra with Extra2 and adjust the
+ implementation. Rename Unsigned_To_Signed to To_Signed.
+ (Scan_Decimal): Replace Extra with Extra2 and adjust the
+ implementation.
+ (Value_Decimal): Likewise.
+ * libgnat/s-valuef.adb (Impl): Remove actual for Round formal.
+ (Integer_to_Fixed): Replace Extra with Extra2 and adjust the
+ implementation. Rename Unsigned_To_Signed to To_Signed. Only
+ round the last scaled divide operation.
+ (Scan_Fixed): Replace Extra with Extra2 and adjust the
+ implementation.
+ (Value_Fixed): Likewise.
+
+2025-07-01 Ronan Desplanques <desplanques@adacore.com>
+
+ * libgnat/s-valuer.adb (Scan_Decimal_Digits, Scan_Integral_Digits):
+ Minor rephrasing.
+
+2025-07-01 Ronan Desplanques <desplanques@adacore.com>
+
+ * sem_ch5.adb (Analyze_Loop_Parameter_Specification): Set ekind
+ earlier.
+
+2025-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_util.ads (Is_Finalizable_Access): New predicate.
+ (Is_Non_BIP_Func_Call): Delete.
+ (Is_Secondary_Stack_BIP_Func_Call): Likewise.
+ * exp_util.adb (Is_Finalizable_Access): New predicate.
+ (Initialized_By_Aliased_BIP_Func_Call): Delete.
+ (Initialized_By_Reference): Likewise.
+ (Is_Aliased): Only consider the nontransient object serviced by
+ the transient scope.
+ (Is_Part_Of_BIP_Return_Statement): Minor tweak.
+ (Is_Finalizable_Transient): Remove calls to Initialized_By_Reference
+ and Initialized_By_Aliased_BIP_Func_Call.
+ Call Is_Finalizable_Access for access objects.
+ (Is_Non_BIP_Func_Call): Delete.
+ (Is_Secondary_Stack_BIP_Func_Call): Likewise.
+ (Requires_Cleanup_Actions): Call Is_Finalizable_Access for access
+ objects.
+ (Side_Effect_Free): Return True for N_Reference.
+ * exp_ch7.adb (Build_Finalizer.Process_Declarations): Call
+ Is_Finalizable_Access for access objects.
+
+2025-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_util.adb (Is_Expression_Of_Func_Return): New predicate.
+ (Is_Related_To_Func_Return): Call Is_Expression_Of_Func_Return.
+ (Remove_Side_Effects): Generate a temporary for a function call
+ that returns a constrained array type with controlled component
+ and an unconstrained first subtype.
+
+2025-07-01 Piotr Trojanek <trojanek@adacore.com>
+
+ * inline.adb (Rewrite_Procedure_Call): Replace with a simple rewriting
+ of procedure call into a single block node, i.e. remove broken
+ optimization.
+ * sem_util.adb (Next_Actual): Adapt GNATprove-specific code that peeks
+ into inlined calls.
+
+2025-07-01 Martin Clochard <clochard@adacore.com>
+
+ * exp_util.adb (Is_Controlling_Formal_Ref): test scope against
+ derived subprogram as well.
+
+2025-07-01 Viljar Indus <indus@adacore.com>
+
+ * errout.adb (Error_Msg_Internal): Relocate Warn_As_Err propagation
+ to Increase_Error_Msg_Counti.
+ (Delete_Warning_And_Continuations): Update
+ Warnings_Treated_As_Errors count.
+ (Delete_Warning): Likewise.
+ (To_Be_Removed): Likewise.
+ * erroutc.adb (Increase_Error_Msg_Count): Count warnings treated
+ as errors here and perform the propagation of this property to
+ the parent message.
+ (Output_Msg_Text): Remove counting of warnings as errors from
+ here.
+ (Decrease_Error_Msg_Count): Update Warnings_Treated_As_Errors
+ count.
+
2025-06-30 Eric Botcazou <ebotcazou@adacore.com>
PR ada/120106
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 26302ba..6216192 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -9575,9 +9575,8 @@ package body Exp_Ch6 is
-- such build-in-place functions, primitive or not.
return not Restriction_Active (No_Finalization)
- and then ((Needs_Finalization (Typ)
- and then not Has_Relaxed_Finalization (Typ))
- or else Is_Tagged_Type (Typ))
+ and then (Needs_Finalization (Typ) or else Is_Tagged_Type (Typ))
+ and then not Has_Relaxed_Finalization (Typ)
and then not Has_Foreign_Convention (Typ);
end Needs_BIP_Collection;
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 2cd02b0..dd2ae5c 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,25 @@
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-gimplify.cc (is_address_with_access_with_size): New function.
+ (ubsan_walk_array_refs_r): Instrument an INDIRECT_REF whose base
+ address is .ACCESS_WITH_SIZE or an address computation whose base
+ address is .ACCESS_WITH_SIZE.
+ * c-ubsan.cc (ubsan_instrument_bounds_pointer_address): New function.
+ (struct factor_t): New structure.
+ (get_factors_from_mul_expr): New function.
+ (get_index_from_offset): New function.
+ (get_index_from_pointer_addr_expr): New function.
+ (is_instrumentable_pointer_array_address): New function.
+ (ubsan_array_ref_instrumented_p): Change prototype.
+ Handle MEM_REF in addtional to ARRAY_REF.
+ (ubsan_maybe_instrument_array_ref): Handle MEM_REF in addtional
+ to ARRAY_REF.
+
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-attribs.cc (handle_counted_by_attribute): Accept counted_by
+ attribute for pointer fields.
+
2025-06-30 Jakub Jelinek <jakub@redhat.com>
PR c/120520
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 5d7a31f..ea04ed7 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -2906,22 +2906,53 @@ handle_counted_by_attribute (tree *node, tree name,
" declaration %q+D", name, decl);
*no_add_attrs = true;
}
- /* This attribute only applies to field with array type. */
- else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
+ /* This attribute only applies to a field with array type or pointer type. */
+ else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE
+ && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
{
error_at (DECL_SOURCE_LOCATION (decl),
- "%qE attribute is not allowed for a non-array field",
- name);
+ "%qE attribute is not allowed for a non-array"
+ " or non-pointer field", name);
*no_add_attrs = true;
}
/* This attribute only applies to a C99 flexible array member type. */
- else if (! c_flexible_array_member_type_p (TREE_TYPE (decl)))
+ else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
+ && !c_flexible_array_member_type_p (TREE_TYPE (decl)))
{
error_at (DECL_SOURCE_LOCATION (decl),
"%qE attribute is not allowed for a non-flexible"
" array member field", name);
*no_add_attrs = true;
}
+ /* This attribute cannot be applied to a pointer to void type. */
+ else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == VOID_TYPE)
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "%qE attribute is not allowed for a pointer to void",
+ name);
+ *no_add_attrs = true;
+ }
+ /* This attribute cannot be applied to a pointer to function type. */
+ else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "%qE attribute is not allowed for a pointer to"
+ " function", name);
+ *no_add_attrs = true;
+ }
+ /* This attribute cannot be applied to a pointer to structure or union
+ with flexible array member. */
+ else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
+ && RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
+ && TYPE_INCLUDES_FLEXARRAY (TREE_TYPE (TREE_TYPE (decl))))
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "%qE attribute is not allowed for a pointer to"
+ " structure or union with flexible array member", name);
+ *no_add_attrs = true;
+ }
/* The argument should be an identifier. */
else if (TREE_CODE (argval) != IDENTIFIER_NODE)
{
@@ -2930,7 +2961,8 @@ handle_counted_by_attribute (tree *node, tree name,
*no_add_attrs = true;
}
/* Issue error when there is a counted_by attribute with a different
- field as the argument for the same flexible array member field. */
+ field as the argument for the same flexible array member or
+ pointer field. */
else if (old_counted_by != NULL_TREE)
{
tree old_fieldname = TREE_VALUE (TREE_VALUE (old_counted_by));
diff --git a/gcc/c-family/c-gimplify.cc b/gcc/c-family/c-gimplify.cc
index c6fb764..e905059 100644
--- a/gcc/c-family/c-gimplify.cc
+++ b/gcc/c-family/c-gimplify.cc
@@ -66,6 +66,20 @@ along with GCC; see the file COPYING3. If not see
walk back up, we check that they fit our constraints, and copy them
into temporaries if not. */
+
+/* Check whether TP is an address computation whose base is a call to
+ .ACCESS_WITH_SIZE. */
+
+static bool
+is_address_with_access_with_size (tree tp)
+{
+ if (TREE_CODE (tp) == POINTER_PLUS_EXPR
+ && (TREE_CODE (TREE_OPERAND (tp, 0)) == INDIRECT_REF)
+ && (is_access_with_size_p (TREE_OPERAND (TREE_OPERAND (tp, 0), 0))))
+ return true;
+ return false;
+}
+
/* Callback for c_genericize. */
static tree
@@ -121,6 +135,20 @@ ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
walk_tree (&TREE_OPERAND (*tp, 1), ubsan_walk_array_refs_r, pset, pset);
walk_tree (&TREE_OPERAND (*tp, 0), ubsan_walk_array_refs_r, pset, pset);
}
+ else if (TREE_CODE (*tp) == INDIRECT_REF
+ && is_address_with_access_with_size (TREE_OPERAND (*tp, 0)))
+ {
+ ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), false);
+ /* Make sure ubsan_maybe_instrument_array_ref is not called again on
+ the POINTER_PLUS_EXPR, so ensure it is not walked again and walk
+ its subtrees manually. */
+ tree aref = TREE_OPERAND (*tp, 0);
+ pset->add (aref);
+ *walk_subtrees = 0;
+ walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
+ }
+ else if (is_address_with_access_with_size (*tp))
+ ubsan_maybe_instrument_array_ref (tp, true);
return NULL_TREE;
}
diff --git a/gcc/c-family/c-ubsan.cc b/gcc/c-family/c-ubsan.cc
index 78b7868..38514a4 100644
--- a/gcc/c-family/c-ubsan.cc
+++ b/gcc/c-family/c-ubsan.cc
@@ -554,38 +554,322 @@ ubsan_instrument_bounds (location_t loc, tree array, tree *index,
*index, bound);
}
-/* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS. */
+
+/* Instrument array bounds for the pointer array address which is
+ an INDIRECT_REF to the call to .ACCESS_WITH_SIZE. We create special
+ builtin, that gets expanded in the sanopt pass, and make an array
+ dimention of it. POINTER_ADDR is the pointer array's base address.
+ *INDEX is an index to the array.
+ IGNORE_OFF_BY_ONE is true if the POINTER_ADDR is not inside an
+ INDIRECT_REF.
+ Return NULL_TREE if no instrumentation is emitted. */
+
+tree
+ubsan_instrument_bounds_pointer_address (location_t loc, tree pointer_addr,
+ tree *index,
+ bool ignore_off_by_one)
+{
+ gcc_assert (TREE_CODE (pointer_addr) == INDIRECT_REF);
+ tree call = TREE_OPERAND (pointer_addr, 0);
+ if (!is_access_with_size_p (call))
+ return NULL_TREE;
+ tree bound = get_bound_from_access_with_size (call);
+
+ if (ignore_off_by_one)
+ bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound,
+ build_int_cst (TREE_TYPE (bound),
+ 1));
+
+ /* Don't emit instrumentation in the most common cases. */
+ tree idx = NULL_TREE;
+ if (TREE_CODE (*index) == INTEGER_CST)
+ idx = *index;
+ else if (TREE_CODE (*index) == BIT_AND_EXPR
+ && TREE_CODE (TREE_OPERAND (*index, 1)) == INTEGER_CST)
+ idx = TREE_OPERAND (*index, 1);
+ if (idx
+ && TREE_CODE (bound) == INTEGER_CST
+ && tree_int_cst_sgn (idx) >= 0
+ && tree_int_cst_lt (idx, bound))
+ return NULL_TREE;
+
+ *index = save_expr (*index);
+
+ /* Create an array_type for the corresponding pointer array. */
+ tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
+ /* The array's element type can be get from the return type of the call to
+ .ACCESS_WITH_SIZE. */
+ tree element_type = TREE_TYPE (TREE_TYPE (TREE_TYPE (call)));
+ tree array_type = build_array_type (element_type, itype);
+ /* Create a "(T *) 0" tree node to describe the array type. */
+ tree zero_with_type = build_int_cst (build_pointer_type (array_type), 0);
+ return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS,
+ void_type_node, 3, zero_with_type,
+ *index, bound);
+}
+
+/* This structure is to combine a factor with its parent and its position
+ * in its parent tree. */
+struct factor_t
+{
+ tree factor;
+ tree parent; /* the parent tree of this factor. */
+ int pos; /* the position of this factor in its parent tree. */
+};
+
+/* for a multiply expression like:
+ ((long unsigned int) m * (long unsigned int) SAVE_EXPR <n>) * 4
+
+ locate all the factors, the parents of the factor and the position of
+ the factor in its parent, and put them to VEC_FACTORS. */
+
+static void
+get_factors_from_mul_expr (tree mult_expr, tree parent,
+ int pos, auto_vec<factor_t> *vec_factors)
+{
+ struct factor_t mult_factor = {0, 0, -1};
+ mult_factor.factor = mult_expr;
+ mult_factor.parent = parent;
+ mult_factor.pos = pos;
+
+ while (CONVERT_EXPR_CODE_P (TREE_CODE (mult_expr)))
+ {
+ mult_factor.parent = mult_expr;
+ mult_factor.pos = 0;
+ mult_expr = TREE_OPERAND (mult_expr, 0);
+ mult_factor.factor = mult_expr;
+ }
+ if (TREE_CODE (mult_expr) != MULT_EXPR)
+ vec_factors->safe_push (mult_factor);
+ else
+ {
+ get_factors_from_mul_expr (TREE_OPERAND (mult_expr, 0), mult_expr,
+ 0, vec_factors);
+ get_factors_from_mul_expr (TREE_OPERAND (mult_expr, 1), mult_expr,
+ 1, vec_factors);
+ }
+}
+
+/* Given an OFFSET expression, and the ELEMENT_SIZE,
+ get the index expression from OFFSET and return it.
+ For example:
+ OFFSET:
+ ((long unsigned int) m * (long unsigned int) SAVE_EXPR <n>) * 4
+ ELEMENT_SIZE:
+ (sizetype) SAVE_EXPR <n> * 4
+ get the index as (long unsigned int) m, and return it.
+ The INDEX_P holds the pointer to the parent tree of the index,
+ INDEX_N holds the position of the index in its parent. */
+
+static tree
+get_index_from_offset (tree offset, tree *index_p,
+ int *index_n, tree element_size)
+{
+ if (TREE_CODE (offset) != MULT_EXPR)
+ return NULL_TREE;
+
+ auto_vec<factor_t> e_factors, o_factors;
+ get_factors_from_mul_expr (element_size, NULL, -1, &e_factors);
+ get_factors_from_mul_expr (offset, *index_p, *index_n, &o_factors);
+
+ if (e_factors.is_empty () || o_factors.is_empty ())
+ return NULL_TREE;
+
+ bool all_found = true;
+ for (unsigned i = 0; i < e_factors.length (); i++)
+ {
+ factor_t e_size_factor = e_factors[i];
+ bool found = false;
+ for (unsigned j = 0; j < o_factors.length ();)
+ {
+ factor_t o_exp_factor = o_factors[j];
+ if (operand_equal_p (e_size_factor.factor, o_exp_factor.factor))
+ {
+ o_factors.unordered_remove (j);
+ found = true;
+ break;
+ }
+ else
+ j++;
+ }
+ if (!found)
+ all_found = false;
+ }
+
+ if (!all_found)
+ return NULL_TREE;
+
+ if (o_factors.length () != 1)
+ return NULL_TREE;
+
+ *index_p = o_factors[0].parent;
+ *index_n = o_factors[0].pos;
+ return o_factors[0].factor;
+}
+
+/* For an pointer + offset computation expression, such as,
+ *.ACCESS_WITH_SIZE (p->c, &p->b, 1, 0, -1, 0B)
+ + (sizetype) ((long unsigned int) index * 4
+ Return the index of this pointer array reference,
+ set the parent tree of INDEX to *INDEX_P.
+ set the operand position of the INDEX in the parent tree to *INDEX_N.
+ If failed, return NULL_TREE. */
+
+static tree
+get_index_from_pointer_addr_expr (tree pointer, tree *index_p, int *index_n)
+{
+ *index_p = NULL_TREE;
+ *index_n = -1;
+ if (TREE_CODE (TREE_OPERAND (pointer, 0)) != INDIRECT_REF)
+ return NULL_TREE;
+ tree call = TREE_OPERAND (TREE_OPERAND (pointer, 0), 0);
+ if (!is_access_with_size_p (call))
+ return NULL_TREE;
+
+ /* Get the pointee type of the call to .ACCESS_WITH_SIZE.
+ This should be the element type of the pointer array. */
+ tree pointee_type = TREE_TYPE (TREE_TYPE (TREE_TYPE (call)));
+ tree pointee_size = TYPE_SIZE_UNIT (pointee_type);
+
+ tree index_exp = TREE_OPERAND (pointer, 1);
+ *index_p = pointer;
+ *index_n = 1;
+
+ if (!(TREE_CODE (index_exp) != MULT_EXPR
+ && tree_int_cst_equal (pointee_size, integer_one_node)))
+ {
+ while (CONVERT_EXPR_CODE_P (TREE_CODE (index_exp)))
+ {
+ *index_p = index_exp;
+ *index_n = 0;
+ index_exp = TREE_OPERAND (index_exp, 0);
+ }
+ index_exp = get_index_from_offset (index_exp, index_p,
+ index_n, pointee_size);
+
+ if (!index_exp)
+ return NULL_TREE;
+ }
+
+ while (CONVERT_EXPR_CODE_P (TREE_CODE (index_exp)))
+ {
+ *index_p = index_exp;
+ *index_n = 0;
+ index_exp = TREE_OPERAND (index_exp, 0);
+ }
+
+ return index_exp;
+}
+
+/* Return TRUE when the EXPR is a pointer array address that could be
+ instrumented.
+ We only instrument an address computation similar as the following:
+ *.ACCESS_WITH_SIZE (p->c, &p->b, 1, 0, -1, 0B)
+ + (sizetype) ((long unsigned int) index * 4)
+ if the EXPR is instrumentable, return TRUE and
+ set the index to *INDEX.
+ set the *.ACCESS_WITH_SIZE to *BASE.
+ set the parent tree of INDEX to *INDEX_P.
+ set the operand position of the INDEX in the parent tree to INDEX_N. */
+
+static bool
+is_instrumentable_pointer_array_address (tree expr, tree *base,
+ tree *index, tree *index_p,
+ int *index_n)
+{
+ /* For a poiner array address as:
+ (*.ACCESS_WITH_SIZE (p->c, &p->b, 1, 0, -1, 0B)
+ + (sizetype) ((long unsigned int) index * 4)
+ op0 is the call to *.ACCESS_WITH_SIZE;
+ op1 is the index. */
+ if (TREE_CODE (expr) != POINTER_PLUS_EXPR)
+ return false;
+
+ tree op0 = TREE_OPERAND (expr, 0);
+ if (TREE_CODE (op0) != INDIRECT_REF)
+ return false;
+ if (!is_access_with_size_p (TREE_OPERAND (op0, 0)))
+ return false;
+ tree op1 = get_index_from_pointer_addr_expr (expr, index_p, index_n);
+ if (op1 != NULL_TREE)
+ {
+ *base = op0;
+ *index = op1;
+ return true;
+ }
+ return false;
+}
+
+/* Return true iff T is an array or an indirect reference that was
+ instrumented by SANITIZE_BOUNDS. */
bool
-ubsan_array_ref_instrumented_p (const_tree t)
+ubsan_array_ref_instrumented_p (tree t)
{
- if (TREE_CODE (t) != ARRAY_REF)
+ if (TREE_CODE (t) != ARRAY_REF
+ && TREE_CODE (t) != MEM_REF)
return false;
- tree op1 = TREE_OPERAND (t, 1);
- return TREE_CODE (op1) == COMPOUND_EXPR
- && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
- && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
- && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
+ bool is_array = (TREE_CODE (t) == ARRAY_REF);
+ tree op0 = NULL_TREE;
+ tree op1 = NULL_TREE;
+ tree index_p = NULL_TREE;
+ int index_n = 0;
+ if (is_array)
+ {
+ op1 = TREE_OPERAND (t, 1);
+ return TREE_CODE (op1) == COMPOUND_EXPR
+ && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
+ && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
+ && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
+ }
+ else if (is_instrumentable_pointer_array_address (t, &op0, &op1,
+ &index_p, &index_n))
+ return TREE_CODE (op1) == COMPOUND_EXPR
+ && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
+ && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
+ && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
+
+ return false;
}
-/* Instrument an ARRAY_REF, if it hasn't already been instrumented.
- IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
+/* Instrument an ARRAY_REF or an address computation whose base address is
+ a call to .ACCESS_WITH_SIZE, if it hasn't already been instrumented.
+ IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR, or the
+ address computation is not inside a INDIRECT_REF. */
void
ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
{
+ tree e = NULL_TREE;
+ tree op0 = NULL_TREE;
+ tree op1 = NULL_TREE;
+ tree index_p = NULL_TREE; /* the parent tree of INDEX. */
+ int index_n = 0; /* the operand position of INDEX in the parent tree. */
+
if (!ubsan_array_ref_instrumented_p (*expr_p)
&& sanitize_flags_p (SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT)
&& current_function_decl != NULL_TREE)
{
- tree op0 = TREE_OPERAND (*expr_p, 0);
- tree op1 = TREE_OPERAND (*expr_p, 1);
- tree e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0, &op1,
- ignore_off_by_one);
+ if (TREE_CODE (*expr_p) == ARRAY_REF)
+ {
+ op0 = TREE_OPERAND (*expr_p, 0);
+ op1 = TREE_OPERAND (*expr_p, 1);
+ index_p = *expr_p;
+ index_n = 1;
+ e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0,
+ &op1, ignore_off_by_one);
+ }
+ else if (is_instrumentable_pointer_array_address (*expr_p, &op0, &op1,
+ &index_p, &index_n))
+ e = ubsan_instrument_bounds_pointer_address (EXPR_LOCATION (*expr_p),
+ op0, &op1,
+ ignore_off_by_one);
+
+ /* Replace the original INDEX with the instrumented INDEX. */
if (e != NULL_TREE)
- TREE_OPERAND (*expr_p, 1) = build2 (COMPOUND_EXPR, TREE_TYPE (op1),
- e, op1);
+ TREE_OPERAND (index_p, index_n)
+ = build2 (COMPOUND_EXPR, TREE_TYPE (op1), e, op1);
}
}
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 89a3210..cb69b8c 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,17 @@
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-decl.cc (verify_counted_by_attribute): Change the 2nd argument
+ to a vector of fields with counted_by attribute. Verify all fields
+ in this vector.
+ (finish_struct): Collect all the fields with counted_by attribute
+ to a vector and pass this vector to verify_counted_by_attribute.
+ * c-typeck.cc (build_counted_by_ref): Handle pointers with counted_by.
+ Add one more argument, issue error when the pointee type is a structure
+ or union including a flexible array member.
+ (build_access_with_size_for_counted_by): Handle pointers with counted_by.
+ (handle_counted_by_for_component_ref): Call build_counted_by_ref
+ with the new prototype.
+
2025-06-23 Tobias Burnus <tburnus@baylibre.com>
* c-parser.cc (OACC_WAIT_CLAUSE_MASK): Add if clause.
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 8bbd6eb..7e1c197 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -9432,56 +9432,62 @@ c_update_type_canonical (tree t)
}
}
-/* Verify the argument of the counted_by attribute of the flexible array
- member FIELD_DECL is a valid field of the containing structure,
- STRUCT_TYPE, Report error and remove this attribute when it's not. */
+/* Verify the argument of the counted_by attribute of each of the
+ FIELDS_WITH_COUNTED_BY is a valid field of the containing structure,
+ STRUCT_TYPE, Report error and remove the corresponding attribute
+ when it's not. */
static void
-verify_counted_by_attribute (tree struct_type, tree field_decl)
+verify_counted_by_attribute (tree struct_type,
+ auto_vec<tree> *fields_with_counted_by)
{
- tree attr_counted_by = lookup_attribute ("counted_by",
- DECL_ATTRIBUTES (field_decl));
-
- if (!attr_counted_by)
- return;
+ for (tree field_decl : *fields_with_counted_by)
+ {
+ tree attr_counted_by = lookup_attribute ("counted_by",
+ DECL_ATTRIBUTES (field_decl));
- /* If there is an counted_by attribute attached to the field,
- verify it. */
+ if (!attr_counted_by)
+ continue;
- tree fieldname = TREE_VALUE (TREE_VALUE (attr_counted_by));
+ /* If there is an counted_by attribute attached to the field,
+ verify it. */
- /* Verify the argument of the attrbute is a valid field of the
- containing structure. */
+ tree fieldname = TREE_VALUE (TREE_VALUE (attr_counted_by));
- tree counted_by_field = lookup_field (struct_type, fieldname);
+ /* Verify the argument of the attrbute is a valid field of the
+ containing structure. */
- /* Error when the field is not found in the containing structure and
- remove the corresponding counted_by attribute from the field_decl. */
- if (!counted_by_field)
- {
- error_at (DECL_SOURCE_LOCATION (field_decl),
- "argument %qE to the %<counted_by%> attribute"
- " is not a field declaration in the same structure"
- " as %qD", fieldname, field_decl);
- DECL_ATTRIBUTES (field_decl)
- = remove_attribute ("counted_by", DECL_ATTRIBUTES (field_decl));
- }
- else
- /* Error when the field is not with an integer type. */
- {
- while (TREE_CHAIN (counted_by_field))
- counted_by_field = TREE_CHAIN (counted_by_field);
- tree real_field = TREE_VALUE (counted_by_field);
+ tree counted_by_field = lookup_field (struct_type, fieldname);
- if (!INTEGRAL_TYPE_P (TREE_TYPE (real_field)))
+ /* Error when the field is not found in the containing structure and
+ remove the corresponding counted_by attribute from the field_decl. */
+ if (!counted_by_field)
{
error_at (DECL_SOURCE_LOCATION (field_decl),
"argument %qE to the %<counted_by%> attribute"
- " is not a field declaration with an integer type",
- fieldname);
+ " is not a field declaration in the same structure"
+ " as %qD", fieldname, field_decl);
DECL_ATTRIBUTES (field_decl)
= remove_attribute ("counted_by", DECL_ATTRIBUTES (field_decl));
}
+ else
+ /* Error when the field is not with an integer type. */
+ {
+ while (TREE_CHAIN (counted_by_field))
+ counted_by_field = TREE_CHAIN (counted_by_field);
+ tree real_field = TREE_VALUE (counted_by_field);
+
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (real_field)))
+ {
+ error_at (DECL_SOURCE_LOCATION (field_decl),
+ "argument %qE to the %<counted_by%> attribute"
+ " is not a field declaration with an integer type",
+ fieldname);
+ DECL_ATTRIBUTES (field_decl)
+ = remove_attribute ("counted_by",
+ DECL_ATTRIBUTES (field_decl));
+ }
+ }
}
}
@@ -9556,7 +9562,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
until now.) */
bool saw_named_field = false;
- tree counted_by_fam_field = NULL_TREE;
+ auto_vec<tree> fields_with_counted_by;
for (x = fieldlist; x; x = DECL_CHAIN (x))
{
/* Whether this field is the last field of the structure or union.
@@ -9637,9 +9643,16 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
record it here and do more verification later after the
whole structure is complete. */
if (lookup_attribute ("counted_by", DECL_ATTRIBUTES (x)))
- counted_by_fam_field = x;
+ fields_with_counted_by.safe_push (x);
}
+ if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE)
+ /* If there is a counted_by attribute attached to this field,
+ record it here and do more verification later after the
+ whole structure is complete. */
+ if (lookup_attribute ("counted_by", DECL_ATTRIBUTES (x)))
+ fields_with_counted_by.safe_push (x);
+
if (pedantic && TREE_CODE (t) == RECORD_TYPE
&& flexible_array_type_p (TREE_TYPE (x)))
pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
@@ -9938,8 +9951,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
struct_parse_info->struct_types.safe_push (t);
}
- if (counted_by_fam_field)
- verify_counted_by_attribute (t, counted_by_fam_field);
+ if (fields_with_counted_by.length () > 0)
+ verify_counted_by_attribute (t, &fields_with_counted_by);
return t;
}
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index e24629b..7948106 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -2922,8 +2922,8 @@ should_suggest_deref_p (tree datum_type)
/* For a SUBDATUM field of a structure or union DATUM, generate a REF to
the object that represents its counted_by per the attribute counted_by
- attached to this field if it's a flexible array member field, otherwise
- return NULL_TREE.
+ attached to this field if it's a flexible array member or a pointer
+ field, otherwise return NULL_TREE.
Set COUNTED_BY_TYPE to the TYPE of the counted_by field.
For example, if:
@@ -2941,18 +2941,34 @@ should_suggest_deref_p (tree datum_type)
*/
static tree
-build_counted_by_ref (tree datum, tree subdatum, tree *counted_by_type)
+build_counted_by_ref (location_t loc, tree datum, tree subdatum,
+ tree *counted_by_type)
{
tree type = TREE_TYPE (datum);
- if (!c_flexible_array_member_type_p (TREE_TYPE (subdatum)))
+ tree sub_type = TREE_TYPE (subdatum);
+ if (!c_flexible_array_member_type_p (sub_type)
+ && TREE_CODE (sub_type) != POINTER_TYPE)
return NULL_TREE;
+ tree element_type = TREE_TYPE (sub_type);
+
tree attr_counted_by = lookup_attribute ("counted_by",
DECL_ATTRIBUTES (subdatum));
tree counted_by_ref = NULL_TREE;
*counted_by_type = NULL_TREE;
if (attr_counted_by)
{
+ /* Issue error when the element_type is a structure or
+ union including a flexible array member. */
+ if (RECORD_OR_UNION_TYPE_P (element_type)
+ && TYPE_INCLUDES_FLEXARRAY (element_type))
+ {
+ error_at (loc,
+ "%<counted_by%> attribute is not allowed for a pointer to"
+ " structure or union with flexible array member");
+ return error_mark_node;
+ }
+
tree field_id = TREE_VALUE (TREE_VALUE (attr_counted_by));
counted_by_ref
= build_component_ref (UNKNOWN_LOCATION,
@@ -2975,8 +2991,11 @@ build_counted_by_ref (tree datum, tree subdatum, tree *counted_by_type)
}
/* Given a COMPONENT_REF REF with the location LOC, the corresponding
- COUNTED_BY_REF, and the COUNTED_BY_TYPE, generate an INDIRECT_REF
- to a call to the internal function .ACCESS_WITH_SIZE.
+ COUNTED_BY_REF, and the COUNTED_BY_TYPE, generate the corresponding
+ call to the internal function .ACCESS_WITH_SIZE.
+
+ Generate an INDIRECT_REF to a call to the internal function
+ .ACCESS_WITH_SIZE.
REF
@@ -2986,17 +3005,15 @@ build_counted_by_ref (tree datum, tree subdatum, tree *counted_by_type)
(TYPE_OF_ARRAY *)0))
NOTE: The return type of this function is the POINTER type pointing
- to the original flexible array type.
- Then the type of the INDIRECT_REF is the original flexible array type.
-
- The type of the first argument of this function is a POINTER type
- to the original flexible array type.
+ to the original flexible array type or the original pointer type.
+ Then the type of the INDIRECT_REF is the original flexible array type
+ or the original pointer type.
The 4th argument of the call is a constant 0 with the TYPE of the
object pointed by COUNTED_BY_REF.
- The 6th argument of the call is a constant 0 with the pointer TYPE
- to the original flexible array type.
+ The 6th argument of the call is a constant 0 of the same TYPE as
+ the return type of the call.
*/
static tree
@@ -3004,11 +3021,16 @@ build_access_with_size_for_counted_by (location_t loc, tree ref,
tree counted_by_ref,
tree counted_by_type)
{
- gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref)));
- /* The result type of the call is a pointer to the flexible array type. */
+ gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref))
+ || TREE_CODE (TREE_TYPE (ref)) == POINTER_TYPE);
+ bool is_fam = c_flexible_array_member_type_p (TREE_TYPE (ref));
+ tree first_param = is_fam ? array_to_pointer_conversion (loc, ref)
+ : build_unary_op (loc, ADDR_EXPR, ref, false);
+
+ /* The result type of the call is a pointer to the original type
+ of the ref. */
tree result_type = c_build_pointer_type (TREE_TYPE (ref));
- tree first_param
- = c_fully_fold (array_to_pointer_conversion (loc, ref), false, NULL);
+ first_param = c_fully_fold (first_param, false, NULL);
tree second_param
= c_fully_fold (counted_by_ref, false, NULL);
@@ -3021,7 +3043,7 @@ build_access_with_size_for_counted_by (location_t loc, tree ref,
build_int_cst (counted_by_type, 0),
build_int_cst (integer_type_node, -1),
build_int_cst (result_type, 0));
- /* Wrap the call with an INDIRECT_REF with the flexible array type. */
+ /* Wrap the call with an INDIRECT_REF with the original type of the ref. */
call = build1 (INDIRECT_REF, TREE_TYPE (ref), call);
SET_EXPR_LOCATION (call, loc);
return call;
@@ -3039,7 +3061,7 @@ handle_counted_by_for_component_ref (location_t loc, tree ref)
tree datum = TREE_OPERAND (ref, 0);
tree subdatum = TREE_OPERAND (ref, 1);
tree counted_by_type = NULL_TREE;
- tree counted_by_ref = build_counted_by_ref (datum, subdatum,
+ tree counted_by_ref = build_counted_by_ref (loc, datum, subdatum,
&counted_by_type);
if (counted_by_ref)
ref = build_access_with_size_for_counted_by (loc, ref,
diff --git a/gcc/cobol/ChangeLog b/gcc/cobol/ChangeLog
index 9b29af8..4b05399 100644
--- a/gcc/cobol/ChangeLog
+++ b/gcc/cobol/ChangeLog
@@ -1,3 +1,11 @@
+2025-07-01 James K. Lowden <jklowden@cobolworx.com>
+
+ * Make-lang.in: Use && instead of semicolon between commands.
+
+2025-07-01 Robert Dubner <rdubner@symas.com>
+
+ * parse.y: printf() of size_t is %zu, not %ld.
+
2025-06-30 James K. Lowden <jklowden@cobolworx.com>
PR cobol/120772
diff --git a/gcc/cobol/Make-lang.in b/gcc/cobol/Make-lang.in
index 18eb3b0..e884212 100644
--- a/gcc/cobol/Make-lang.in
+++ b/gcc/cobol/Make-lang.in
@@ -287,7 +287,7 @@ cobol.install-common: installdirs
rm -f $(DESTDIR)$(bindir)/$(GCOBOL_TARGET_INSTALL_NAME)$(exeext); \
rm -f $(DESTDIR)$(bindir)/$(GCOBC_TARGET_INSTALL_NAME)$(exeext); \
( cd $(DESTDIR)$(bindir) && \
- $(LN) $(GCOBOL_INSTALL_NAME)$(exeext) $(GCOBOL_TARGET_INSTALL_NAME)$(exeext) ); \
+ $(LN) $(GCOBOL_INSTALL_NAME)$(exeext) $(GCOBOL_TARGET_INSTALL_NAME)$(exeext) && \
$(LN) $(GCOBC_INSTALL_NAME)$(exeext) $(GCOBC_TARGET_INSTALL_NAME)$(exeext) ); \
fi; \
fi
diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
index 57a41bb..74637c9 100644
--- a/gcc/cobol/parse.y
+++ b/gcc/cobol/parse.y
@@ -12404,7 +12404,7 @@ numstr2i( const char input[], radix_t radix ) {
return output;
}
if( erc == -1 ) {
- yywarn("'%s' was accepted as %ld", input, integer);
+ yywarn("'%s' was accepted as %zu", input, integer);
}
return output;
}
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index e771def..af574d5 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -5046,6 +5046,36 @@
DONE;
})
+;; convert (truncate)(~x >> imm) into (truncate)(((u16)-1 - x) >> imm)
+;; because it will result in the 'not' being replaced with a constant load
+;; which allows for better loop optimization.
+;; We limit this to truncations that take the upper half and shift it to the
+;; lower half as we use subhn (patterns that would have generated an shrn
+;; otherwise).
+;; On some implementations the use of subhn also result in better throughput.
+(define_insn_and_split "*shrn_to_subhn_<mode>"
+ [(set (match_operand:<VNARROWQ> 0 "register_operand" "=&w")
+ (truncate:<VNARROWQ>
+ (lshiftrt:VQN
+ (not:VQN (match_operand:VQN 1 "register_operand" "w"))
+ (match_operand:VQN 2 "aarch64_simd_shift_imm_vec_exact_top"))))]
+ "TARGET_SIMD"
+ "#"
+ "&& true"
+ [(const_int 0)]
+{
+ rtx tmp;
+ if (can_create_pseudo_p ())
+ tmp = gen_reg_rtx (<MODE>mode);
+ else
+ tmp = gen_rtx_REG (<MODE>mode, REGNO (operands[0]));
+ emit_move_insn (tmp, CONSTM1_RTX (<MODE>mode));
+ emit_insn (gen_aarch64_subhn<mode>_insn (operands[0], tmp,
+ operands[1], operands[2]));
+ DONE;
+})
+
+
;; pmul.
(define_insn "aarch64_pmul<mode>"
diff --git a/gcc/config/i386/driver-i386.cc b/gcc/config/i386/driver-i386.cc
index 63c7d79..fe71f55 100644
--- a/gcc/config/i386/driver-i386.cc
+++ b/gcc/config/i386/driver-i386.cc
@@ -600,7 +600,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
if (has_feature (FEATURE_AVX512F))
{
/* Assume Diamond Rapids. */
- if (has_feature (FEATURE_AMX_TRANSPOSE))
+ if (has_feature (FEATURE_AMX_FP8))
cpu = "diamondrapids";
/* Assume Granite Rapids D. */
else if (has_feature (FEATURE_AMX_COMPLEX))
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 318d0cd..ff7582d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/120471
+ * typeck.cc (cp_build_array_ref) <case COND_EXPR>: If idx is not
+ INTEGER_CST, don't optimize the case (but cp_default_conversion on
+ array early if it has ARRAY_TYPE) or use
+ SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0> as new op0 depending
+ on flag_strong_eval_order and whether op1 and op2 are arrays with
+ invariant address or tree invariant pointers. Formatting fixes.
+
2025-06-28 Nathaniel Shead <nathanieloshead@gmail.com>
* module.cc (trees_out::walking_bit_field_unit): New flag.
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index f4b49b7..447fe81 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -4001,13 +4001,61 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
}
case COND_EXPR:
- ret = build_conditional_expr
- (loc, TREE_OPERAND (array, 0),
- cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
- complain),
- cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx,
- complain),
- complain);
+ tree op0, op1, op2;
+ op0 = TREE_OPERAND (array, 0);
+ op1 = TREE_OPERAND (array, 1);
+ op2 = TREE_OPERAND (array, 1);
+ if (TREE_SIDE_EFFECTS (idx) || !tree_invariant_p (idx))
+ {
+ /* If idx could possibly have some SAVE_EXPRs, turning
+ (op0 ? op1 : op2)[idx] into
+ op0 ? op1[idx] : op2[idx] can lead into temporaries
+ initialized in one conditional path and uninitialized
+ uses of them in the other path.
+ And if idx is a really large expression, evaluating it
+ twice is also not optimal.
+ On the other side, op0 must be sequenced before evaluation
+ of op1 and op2 and for C++17 op0, op1 and op2 must be
+ sequenced before idx.
+ If idx is INTEGER_CST, we can just do the optimization
+ without any SAVE_EXPRs, if op1 and op2 are both ARRAY_TYPE
+ VAR_DECLs or COMPONENT_REFs thereof (so their address
+ is constant or relative to frame), optimize into
+ (SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0>)
+ ? op1[SAVE_EXPR <idx>] : op2[SAVE_EXPR <idx>]
+ Otherwise avoid this optimization. */
+ if (flag_strong_eval_order == 2)
+ {
+ if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
+ {
+ if (!address_invariant_p (op1) || !address_invariant_p (op2))
+ {
+ /* Force default conversion on array if
+ we can't optimize this and array is ARRAY_TYPE
+ COND_EXPR, we can't leave COND_EXPRs with
+ ARRAY_TYPE in the IL. */
+ array = cp_default_conversion (array, complain);
+ if (error_operand_p (array))
+ return error_mark_node;
+ break;
+ }
+ }
+ else if (!POINTER_TYPE_P (TREE_TYPE (array))
+ || !tree_invariant_p (op1)
+ || !tree_invariant_p (op2))
+ break;
+ }
+ if (TREE_SIDE_EFFECTS (idx))
+ {
+ idx = save_expr (idx);
+ op0 = save_expr (op0);
+ tree tem = build_compound_expr (loc, op0, idx);
+ op0 = build_compound_expr (loc, tem, op0);
+ }
+ }
+ op1 = cp_build_array_ref (loc, op1, idx, complain);
+ op2 = cp_build_array_ref (loc, op2, idx, complain);
+ ret = build_conditional_expr (loc, op0, op1, op2, complain);
protected_set_expr_location (ret, loc);
return ret;
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 046de36..70adf2d 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -7138,9 +7138,11 @@ The @code{aligned} attribute can also be used for functions
@cindex @code{counted_by} variable attribute
@item counted_by (@var{count})
The @code{counted_by} attribute may be attached to the C99 flexible array
-member of a structure. It indicates that the number of the elements of the
-array is given by the field "@var{count}" in the same structure as the
-flexible array member.
+member, or a pointer field of a structure. It indicates that the number
+of the elements of the array that is held by the flexible array member
+field, or is pointed to by the pointer field, is given by the field
+"@var{count}" in the same structure as the flexible array member or the
+pointer field.
This attribute is available only in C for now.
In C++ this attribute is ignored.
@@ -7161,8 +7163,22 @@ struct P @{
@end smallexample
@noindent
-specifies that the @code{array} is a flexible array member whose number of
-elements is given by the field @code{count} in the same structure.
+specifies that the @code{array} is a flexible array member whose number
+of elements is given by the field @code{count} in the same structure.
+
+@smallexample
+struct PP @{
+ size_t count2;
+ char other1;
+ char *array2 __attribute__ ((counted_by (count2)));
+ int other2;
+@} *pp;
+@end smallexample
+
+@noindent
+specifies that the @code{array2} is an array that is pointed by the
+pointer field, and its number of elements is given by the field
+@code{count2} in the same structure.
The field that represents the number of the elements should have an
integer type. Otherwise, the compiler reports an error and ignores
@@ -7171,6 +7187,12 @@ the attribute.
When the field that represents the number of the elements is assigned a
negative integer value, the compiler treats the value as zero.
+The @code{counted_by} attribute is not allowed for a pointer to @code{void},
+a pointer to function, or a pointer to a structure or union that includes
+a flexible array member. However, it is allowed for a pointer to
+non-void incomplete structure or union types, as long as the type could
+be completed before the first reference to the pointer.
+
An explicit @code{counted_by} annotation defines a relationship between
two objects, @code{p->array} and @code{p->count}, and there are the
following requirements on the relationship between this pair:
@@ -7186,6 +7208,13 @@ available all the time. This relationship must hold even after any of
these related objects are updated during the program.
@end itemize
+In addition to the above requirements, there is one more requirement
+between this pair if and only if @code{p->array} is an array that is
+pointed by the pointer field:
+
+@code{p->array} and @code{p->count} can only be changed by changing the
+whole structure at the same time.
+
It's the programmer's responsibility to make sure the above requirements to
be kept all the time. Otherwise the compiler reports warnings and
the results of the array bound sanitizer and the
@@ -7207,6 +7236,8 @@ In the above, @code{ref1} uses @code{val1} as the number of the elements in
@code{p->array}, and @code{ref2} uses @code{val2} as the number of elements
in @code{p->array}.
+Note, however, the above feature is not valid for the pointer field.
+
@cindex @code{alloc_size} variable attribute
@item alloc_size (@var{position})
@itemx alloc_size (@var{position-1}, @var{position-2})
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 6b44a69..0ea9c39 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,25 @@
+2025-07-01 Harald Anlauf <anlauf@gmx.de>
+
+ * coarray.cc (check_add_new_component): Treat pure and elemental
+ intrinsic functions the same as non-intrinsic ones.
+ (create_caf_add_data_parameter_type): Fix front-end memleaks.
+ * trans-intrinsic.cc (conv_caf_func_index): Likewise.
+
+2025-07-01 Andre Vehreschild <vehre@gcc.gnu.org>
+
+ PR fortran/120847
+ * coarray.cc (check_add_new_comp_handle_array): Make the count
+ of components static to be able to create more than one. Create
+ an array component only for array expressions.
+
+2025-07-01 Andre Vehreschild <vehre@gcc.gnu.org>
+
+ PR fortran/120843
+ * resolve.cc (resolve_operator): Report inconsistent coranks
+ only when not referencing this_image.
+ (gfc_op_rank_conformable): Treat coranks as inconformable only
+ when a coindex other then implicit this_image is used.
+
2025-06-27 Harald Anlauf <anlauf@gmx.de>
PR fortran/120784
diff --git a/gcc/fortran/coarray.cc b/gcc/fortran/coarray.cc
index 2f067f8..ef8fd4e 100644
--- a/gcc/fortran/coarray.cc
+++ b/gcc/fortran/coarray.cc
@@ -503,7 +503,7 @@ check_add_new_comp_handle_array (gfc_expr *e, gfc_symbol *type,
gfc_symbol *add_data)
{
gfc_component *comp;
- int cnt = -1;
+ static int cnt = -1;
gfc_symtree *caller_image;
gfc_code *pre_code = caf_accessor_prepend;
bool static_array_or_scalar = true;
@@ -566,7 +566,7 @@ check_add_new_comp_handle_array (gfc_expr *e, gfc_symbol *type,
else
{
comp->initializer = gfc_copy_expr (e);
- if (e_attr.dimension)
+ if (e_attr.dimension && e->rank)
{
comp->attr.dimension = 1;
comp->as = get_arrayspec_from_expr (e);
@@ -697,7 +697,10 @@ check_add_new_component (gfc_symbol *type, gfc_expr *e, gfc_symbol *add_data)
break;
case EXPR_FUNCTION:
if (!e->symtree->n.sym->attr.pure
- && !e->symtree->n.sym->attr.elemental)
+ && !e->symtree->n.sym->attr.elemental
+ && !(e->value.function.isym
+ && (e->value.function.isym->pure
+ || e->value.function.isym->elemental)))
/* Treat non-pure/non-elemental functions. */
check_add_new_comp_handle_array (e, type, add_data);
else
@@ -743,7 +746,6 @@ create_caf_add_data_parameter_type (gfc_expr *expr, gfc_namespace *ns,
add_data->as->lower[0]
= gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
&expr->where);
- mpz_init (add_data->as->lower[0]->value.integer);
mpz_set_si (add_data->as->lower[0]->value.integer, 1);
for (gfc_ref *ref = expr->ref; ref; ref = ref->next)
@@ -763,6 +765,7 @@ create_caf_add_data_parameter_type (gfc_expr *expr, gfc_namespace *ns,
type->declared_at = expr->where;
gfc_set_sym_referenced (type);
gfc_commit_symbol (type);
+ free (name);
return type;
}
diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index fce5ee2..f1bfd3e 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -1052,7 +1052,7 @@ conv_caf_func_index (stmtblock_t *block, gfc_namespace *ns, const char *pat,
index_st->n.sym->value
= gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
&gfc_current_locus);
- mpz_init_set_si (index_st->n.sym->value->value.integer, -1);
+ mpz_set_si (index_st->n.sym->value->value.integer, -1);
index_st->n.sym->ts.type = BT_INTEGER;
index_st->n.sym->ts.kind = gfc_default_integer_kind;
gfc_set_sym_referenced (index_st->n.sym);
diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog
index 04211a0..f7254f9 100644
--- a/gcc/m2/ChangeLog
+++ b/gcc/m2/ChangeLog
@@ -1,3 +1,9 @@
+2025-07-01 Gaius Mulley <gaiusmod2@gmail.com>
+
+ PR modula2/120912
+ * gm2-libs-iso/IOChanUtils.def (GetFile): New procedure function.
+ * gm2-libs-iso/IOChanUtils.mod (GetFile): New procedure function.
+
2025-06-29 Gaius Mulley <gaiusmod2@gmail.com>
PR modula2/117203
diff --git a/gcc/m2/gm2-libs-iso/IOChanUtils.def b/gcc/m2/gm2-libs-iso/IOChanUtils.def
index e38f83a..3a8a0c6 100644
--- a/gcc/m2/gm2-libs-iso/IOChanUtils.def
+++ b/gcc/m2/gm2-libs-iso/IOChanUtils.def
@@ -11,6 +11,7 @@ DEFINITION MODULE IOChanUtils ;
*)
FROM DynamicStrings IMPORT String ;
+FROM FIO IMPORT File ;
IMPORT IOChan ;
@@ -24,4 +25,11 @@ IMPORT IOChan ;
PROCEDURE GetFileName (c: IOChan.ChanId) : String ;
+(*
+ GetFile - returns the FIO.File associated with ChanId c.
+*)
+
+PROCEDURE GetFile (c: IOChan.ChanId) : File ;
+
+
END IOChanUtils.
diff --git a/gcc/m2/gm2-libs-iso/IOChanUtils.mod b/gcc/m2/gm2-libs-iso/IOChanUtils.mod
index 5cbb2a9..168fe0d 100644
--- a/gcc/m2/gm2-libs-iso/IOChanUtils.mod
+++ b/gcc/m2/gm2-libs-iso/IOChanUtils.mod
@@ -11,8 +11,18 @@ IMPORT IOChan, SFIO, RTio ;
PROCEDURE GetFileName (c: IOChan.ChanId) : String ;
BEGIN
- RETURN SFIO.GetFileName (RTio.GetFile (c))
+ RETURN SFIO.GetFileName (GetFile (c))
END GetFileName ;
+(*
+ GetFile - returns the FIO.File associated with ChanId c.
+*)
+
+PROCEDURE GetFile (c: IOChan.ChanId) : File ;
+BEGIN
+ RETURN RTio.GetFile (c)
+END GetFile ;
+
+
END IOChanUtils.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1e78e86..eaa08db 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,128 @@
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * gcc.dg/ubsan/pointer-counted-by-bounds-2.c: New test.
+ * gcc.dg/ubsan/pointer-counted-by-bounds-3.c: New test.
+ * gcc.dg/ubsan/pointer-counted-by-bounds-4.c: New test.
+ * gcc.dg/ubsan/pointer-counted-by-bounds-5.c: New test.
+ * gcc.dg/ubsan/pointer-counted-by-bounds.c: New test.
+
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * gcc.dg/pointer-counted-by-4-char.c: New test.
+ * gcc.dg/pointer-counted-by-4-float.c: New test.
+ * gcc.dg/pointer-counted-by-4-struct.c: New test.
+ * gcc.dg/pointer-counted-by-4-union.c: New test.
+ * gcc.dg/pointer-counted-by-4.c: New test.
+ * gcc.dg/pointer-counted-by-5.c: New test.
+ * gcc.dg/pointer-counted-by-6.c: New test.
+ * gcc.dg/pointer-counted-by-7.c: New test.
+
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * gcc.dg/flex-array-counted-by.c: Update test.
+ * gcc.dg/pointer-counted-by-1.c: New test.
+ * gcc.dg/pointer-counted-by-2.c: New test.
+ * gcc.dg/pointer-counted-by-3.c: New test.
+ * gcc.dg/pointer-counted-by.c: New test.
+
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR testsuite/120919
+ * gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c (main): Change
+ sc, ss, si and sll vars from scalars to arrays of 2 elements,
+ initialize and test just the first one though.
+
+2025-07-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/finalizable2.ads: New test.
+
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.target/s390/vector/vec-abs-emu.c: Add -fno-stack-protector
+ to dg-options.
+ * gcc.target/s390/vector/vec-max-emu.c: Likewise.
+ * gcc.target/s390/vector/vec-min-emu.c: Likewise.
+
+2025-07-01 Robert Dubner <rdubner@symas.com>
+
+ * cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob:
+ Append INTRINSIC keyword.
+
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/120471
+ * g++.dg/ubsan/pr120471.C: New test.
+ * g++.dg/parse/pr120471.C: New test.
+
+2025-07-01 Remi Machet <rmachet@nvidia.com>
+
+ * gcc.target/aarch64/simd/shrn2subhn.c: New test.
+
+2025-07-01 Andre Vehreschild <vehre@gcc.gnu.org>
+
+ PR fortran/120847
+ * gfortran.dg/coarray/coindexed_7.f90: New test.
+
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR ipa/119318
+ PR testsuite/120082
+ * gcc.dg/ipa/pr119318.c (main): Expect different result on big endian
+ from little endian, on unexpected endianness or int/int128 sizes don't
+ test anything. Formatting fixes.
+
+2025-07-01 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.target/i386/preserve-none-1.c (dg-options): Add
+ -fomit-frame-pointer.
+
+2025-07-01 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * g++.target/i386/memset-pr101366-1.C (dg-options): Add
+ -fasynchronous-unwind-tables -fdwarf2-cfi-asm.
+ * g++.target/i386/memset-pr101366-2.C: Likewise.
+ * g++.target/i386/memset-pr118276-1a.C: Likewise.
+ * g++.target/i386/memset-pr118276-1b.C: Likewise.
+ * g++.target/i386/memset-pr118276-1c.C: Likewise.
+ * gcc.target/i386/memset-pr70308-1a.c: Likewise.
+ * gcc.target/i386/memset-strategy-25.c: Likewise.
+ * gcc.target/i386/memset-strategy-28.c: Likewise.
+ * gcc.target/i386/memset-strategy-29.c: Likewise.
+ * gcc.target/i386/memset-strategy-30.c: Likewise.
+ * gcc.target/i386/pr92080-17.c: Likewise.
+ * gcc.target/i386/memset-pr70308-1b.c: Likewise. Also add
+ -fomit-frame-pointer.
+ * g++.target/i386/memset-pr108585-1a.C: (dg-options): Add
+ -fasynchronous-unwind-tables -fdwarf2-cfi-asm. Also add
+ -mno-stackrealign -fomit-frame-pointer.
+ * g++.target/i386/memset-pr108585-1b.C: Likewise.
+
+2025-07-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/120608
+ * c-c++-common/asan/pr120608-3.c: New test.
+ * c-c++-common/asan/pr120608-4.c: New test.
+ * g++.dg/asan/pr120608-3.C: New test.
+ * g++.dg/asan/pr120608-4.C: New test.
+
+2025-07-01 Andre Vehreschild <vehre@gcc.gnu.org>
+
+ PR fortran/120843
+ * gfortran.dg/coarray/coindexed_6.f90: New test.
+
+2025-07-01 Yuao Ma <c8ef@outlook.com>
+
+ * lib/target-supports.exp (foldable_pi_based_trigonometry): New
+ effective target.
+ * gcc.dg/torture/builtin-math-9.c: New test.
+
+2025-07-01 Alexandre Oliva <oliva@adacore.com>
+
+ PR middle-end/120631
+ * gcc.dg/dfp/pr120631.c: Drop overrider of dg-do default action.
+ * gcc.dg/dfp/bitint-9.c: Likewise.
+ * gcc.dg/dfp/bitint-10.c: Likewise.
+
2025-06-30 Jeff Law <jlaw@ventanamicro.com>
PR rtl-optimization/120242
diff --git a/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob b/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob
index b94adf5..39a0c5b 100644
--- a/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob
+++ b/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob
@@ -5,8 +5,8 @@
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
- FUNCTION PI
- FUNCTION E.
+ FUNCTION PI INTRINSIC
+ FUNCTION E INTRINSIC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Z PIC 99V99.
diff --git a/gcc/testsuite/g++.dg/parse/pr120471.C b/gcc/testsuite/g++.dg/parse/pr120471.C
new file mode 100644
index 0000000..ad47e38
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr120471.C
@@ -0,0 +1,42 @@
+// PR c++/120471
+// { dg-do compile }
+
+extern int a1[], a2[], a3[], a4[];
+
+int corge (int);
+
+int
+foo (int p)
+{
+ return (p ? a1 : a2)[1];
+}
+
+int
+bar (int p, int q)
+{
+ return (p ? a1 : a2)[q];
+}
+
+int
+garply (int p, int q)
+{
+ return (p ? a1 : a2)[corge (q)];
+}
+
+int
+baz (int p, int q)
+{
+ return (p ? q ? a1 : a2 : q ? a3 : a4)[1];
+}
+
+int
+qux (int p, int q, int r)
+{
+ return (p ? q ? a1 : a2 : q ? a3 : a4)[r];
+}
+
+int
+fred (int p, int q, int r)
+{
+ return (p ? q ? a1 : a2 : q ? a3 : a4)[corge (r)];
+}
diff --git a/gcc/testsuite/g++.dg/ubsan/pr120471.C b/gcc/testsuite/g++.dg/ubsan/pr120471.C
new file mode 100644
index 0000000..31b781f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/pr120471.C
@@ -0,0 +1,21 @@
+// PR c++/120471
+// { dg-do run }
+// { dg-options "-fsanitize=undefined" }
+
+volatile int b[1], a[1];
+
+void
+foo (int x)
+{
+ volatile int c = 21;
+ volatile int v = (x % 2 ? b : a)[c % 3];
+ if (v != 0)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ foo (1);
+ foo (2);
+}
diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by.c b/gcc/testsuite/gcc.dg/flex-array-counted-by.c
index 16eb2c6..4fa91ff 100644
--- a/gcc/testsuite/gcc.dg/flex-array-counted-by.c
+++ b/gcc/testsuite/gcc.dg/flex-array-counted-by.c
@@ -10,7 +10,7 @@ int x __attribute ((counted_by (size))); /* { dg-error "attribute is not allowed
struct trailing {
int count;
- int field __attribute ((counted_by (count))); /* { dg-error "attribute is not allowed for a non-array field" } */
+ int field __attribute ((counted_by (count))); /* { dg-error "attribute is not allowed for a non-array or non-pointer field" } */
};
struct trailing_1 {
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-1.c b/gcc/testsuite/gcc.dg/pointer-counted-by-1.c
new file mode 100644
index 0000000..395af34
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-1.c
@@ -0,0 +1,34 @@
+/* More testing the correct usage of attribute counted_by for pointer field. */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+typedef struct item1 Item1;
+typedef union item2 Item2;
+
+struct pointer_array {
+ int count1;
+ Item1 *array_1 __attribute__ ((counted_by (count1)));
+ Item2 *array_2 __attribute__ ((counted_by (count2)));
+ int count2;
+} *pointer_data;
+
+struct item1 {
+ int a;
+ float b[];
+};
+
+union item2 {
+ int c;
+ float d[];
+};
+
+void foo ()
+{
+ pointer_data
+ = (struct pointer_array *) __builtin_malloc (sizeof (struct pointer_array));
+ pointer_data->array_1 /* { dg-error "attribute is not allowed for a pointer to structure or union with flexible array member" } */
+ = (Item1 *) __builtin_malloc (sizeof (Item1) + 3 * sizeof (float));
+ pointer_data->array_2 /* { dg-error "attribute is not allowed for a pointer to structure or union with flexible array member" } */
+ = (Item2 *) __builtin_malloc (sizeof (Item2) + 3 * sizeof (float));
+ return;
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-2.c b/gcc/testsuite/gcc.dg/pointer-counted-by-2.c
new file mode 100644
index 0000000..1f4a278
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-2.c
@@ -0,0 +1,10 @@
+/* Testing the correct usage of attribute counted_by for pointer: _BitInt */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-O2 -std=c23" } */
+
+struct pointer_array {
+ _BitInt(24) count;
+ int *array __attribute__ ((counted_by (count)));
+ int *array1 __attribute__ ((counted_by (count1)));
+ _BitInt(24) count1;
+};
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-3.c b/gcc/testsuite/gcc.dg/pointer-counted-by-3.c
new file mode 100644
index 0000000..7005609
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-3.c
@@ -0,0 +1,127 @@
+ /* Testing the correct usage of attribute counted_by for pointer in c23,
+ multiple definitions of the same tag in same or different scopes.
+ { dg-do compile }
+ { dg-options "-std=c23" }
+ */
+
+/* Allowed redefinitions of the same struct in the same scope, with the
+ same counted_by attribute. */
+struct f {
+ int b;
+ int c;
+ int *a __attribute__ ((counted_by (b))); };
+struct f {
+ int b;
+ int c;
+ int *a __attribute__ ((counted_by (b))); };
+struct f {
+ int b;
+ int c;
+ int *a; }; /* { dg-error "redefinition of struct or union" } */
+
+/* Error when the counted_by attribute is defined differently. */
+struct f {
+ int b;
+ int c;
+ int *a __attribute__ ((counted_by (c))); }; /* { dg-error "redefinition of struct or union" } */
+
+struct h {
+ int b;
+ int c;
+ int *a __attribute__ ((counted_by (b))); } p;
+
+void test (void)
+{
+ struct h {
+ int b;
+ int c;
+ int *a __attribute__ ((counted_by (b))); } x;
+
+ p = x;
+}
+
+void test1 (void)
+{
+ struct h {
+ int b;
+ int c;
+ int *a __attribute__ ((counted_by (c))); } y;
+
+ p = y; /* { dg-error "incompatible types when assigning to type" } */
+}
+
+struct nested_f {
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+ char *c __attribute__ ((counted_by (b)));
+};
+
+struct nested_f {
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+ char *c __attribute__ ((counted_by (b)));
+};
+
+struct nested_f {
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+ char *c __attribute__ ((counted_by (n)));
+}; /* { dg-error "redefinition of struct or union" } */
+
+struct nested_h {
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+ char *c __attribute__ ((counted_by (b)));
+} nested_p;
+
+void test_2 (void)
+{
+struct nested_h {
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+ char *c __attribute__ ((counted_by (b)));
+} nested_x;
+
+ nested_p = nested_x;
+}
+
+void test_3 (void)
+{
+struct nested_h {
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+ char *c __attribute__ ((counted_by (n)));
+} nested_y;
+
+ nested_p = nested_y; /* { dg-error "incompatible types when assigning to type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c
new file mode 100644
index 0000000..c404e5b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c
@@ -0,0 +1,6 @@
+/* Test the attribute counted_by for pointer field and its usage in
+ * __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+#define PTR_TYPE char
+#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c
new file mode 100644
index 0000000..383d8fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c
@@ -0,0 +1,6 @@
+/* Test the attribute counted_by for pointer field and its usage in
+ * __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+#define PTR_TYPE float
+#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c
new file mode 100644
index 0000000..50246d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c
@@ -0,0 +1,10 @@
+/* Test the attribute counted_by for pointer field and its usage in
+ * __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+struct A {
+ int a;
+ char *b;
+};
+#define PTR_TYPE struct A
+#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c
new file mode 100644
index 0000000..e786d99
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c
@@ -0,0 +1,10 @@
+/* Test the attribute counted_by for pointer field and its usage in
+ * __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+union A {
+ int a;
+ float b;
+};
+#define PTR_TYPE union A
+#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4.c
new file mode 100644
index 0000000..c4b3631
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4.c
@@ -0,0 +1,77 @@
+/* Test the attribute counted_by for pointer field and its usage in
+ * __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include "builtin-object-size-common.h"
+#ifndef PTR_TYPE
+#define PTR_TYPE int
+#endif
+struct pointer_array {
+ int b;
+ PTR_TYPE *c;
+} *p_array;
+
+struct annotated {
+ PTR_TYPE *c __attribute__ ((counted_by (b)));
+ int b;
+} *p_array_annotated;
+
+struct nested_annotated {
+ PTR_TYPE *c __attribute__ ((counted_by (b)));
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+} *p_array_nested_annotated;
+
+void __attribute__((__noinline__)) setup (int normal_count, int attr_count)
+{
+ p_array
+ = (struct pointer_array *) malloc (sizeof (struct pointer_array));
+ p_array->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * normal_count);
+ p_array->b = normal_count;
+
+ p_array_annotated
+ = (struct annotated *) malloc (sizeof (struct annotated));
+ p_array_annotated->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * attr_count);
+ p_array_annotated->b = attr_count;
+
+ p_array_nested_annotated
+ = (struct nested_annotated *) malloc (sizeof (struct nested_annotated));
+ p_array_nested_annotated->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * attr_count);
+ p_array_nested_annotated->b = attr_count;
+
+ return;
+}
+
+void __attribute__((__noinline__)) test ()
+{
+ EXPECT(__builtin_dynamic_object_size(p_array->c, 1), -1);
+ EXPECT(__builtin_dynamic_object_size(p_array_annotated->c, 1),
+ p_array_annotated->b * sizeof (PTR_TYPE));
+ EXPECT(__builtin_dynamic_object_size(p_array_nested_annotated->c, 1),
+ p_array_nested_annotated->b * sizeof (PTR_TYPE));
+}
+
+void cleanup ()
+{
+ free (p_array->c);
+ free (p_array);
+ free (p_array_annotated->c);
+ free (p_array_annotated);
+ free (p_array_nested_annotated->c);
+ free (p_array_nested_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ setup (10,10);
+ test ();
+ DONE ();
+ cleanup ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-5.c b/gcc/testsuite/gcc.dg/pointer-counted-by-5.c
new file mode 100644
index 0000000..b43ffdf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-5.c
@@ -0,0 +1,56 @@
+/* Test the attribute counted_by for pointer fields and its usage in
+ * __builtin_dynamic_object_size: when the counted_by field is negative. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include "builtin-object-size-common.h"
+
+struct annotated {
+ int b;
+ int *c __attribute__ ((counted_by (b)));
+} *array_annotated;
+
+struct nested_annotated {
+ int *c __attribute__ ((counted_by (b)));
+ struct {
+ union {
+ int b;
+ float f;
+ };
+ int n;
+ };
+} *array_nested_annotated;
+
+void __attribute__((__noinline__)) setup (int attr_count)
+{
+ array_annotated
+ = (struct annotated *)malloc (sizeof (struct annotated));
+ array_annotated->b = attr_count;
+
+ array_nested_annotated
+ = (struct nested_annotated *)malloc (sizeof (struct nested_annotated));
+ array_nested_annotated->b = attr_count - 1;
+
+ return;
+}
+
+void __attribute__((__noinline__)) test ()
+{
+ EXPECT(__builtin_dynamic_object_size(array_annotated->c, 1), 0);
+ EXPECT(__builtin_dynamic_object_size(array_nested_annotated->c, 1), 0);
+}
+
+void cleanup ()
+{
+ free (array_annotated);
+ free (array_nested_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ setup (-10);
+ test ();
+ DONE ();
+ cleanup ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-6.c b/gcc/testsuite/gcc.dg/pointer-counted-by-6.c
new file mode 100644
index 0000000..355558c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-6.c
@@ -0,0 +1,56 @@
+/* Test the attribute counted_by for pointer fields and its usage in
+ * __builtin_dynamic_object_size: when the type of the pointer
+ * is casting to another type. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include "builtin-object-size-common.h"
+
+typedef unsigned short u16;
+
+struct info {
+ u16 data_len;
+ char *data __attribute__((counted_by(data_len)));
+};
+
+struct foo {
+ int a;
+ int b;
+};
+
+static __attribute__((__noinline__))
+struct info *setup ()
+{
+ struct info *p;
+ size_t bytes = 3 * sizeof(struct foo);
+
+ p = (struct info *) malloc (sizeof (struct info));
+ p->data = (char *) malloc (bytes);
+ p->data_len = bytes;
+
+ return p;
+}
+
+static void
+__attribute__((__noinline__)) report (struct info *p)
+{
+ struct foo *bar = (struct foo *)p->data;
+ EXPECT(__builtin_dynamic_object_size((char *)(bar + 1), 1),
+ sizeof (struct foo) * 2);
+ EXPECT(__builtin_dynamic_object_size((char *)(bar + 2), 1),
+ sizeof (struct foo));
+}
+
+void cleanup (struct info *p)
+{
+ free (p->data);
+ free (p);
+}
+
+int main(int argc, char *argv[])
+{
+ struct info *p = setup();
+ report(p);
+ cleanup (p);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-7.c b/gcc/testsuite/gcc.dg/pointer-counted-by-7.c
new file mode 100644
index 0000000..af1ab27
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-7.c
@@ -0,0 +1,32 @@
+/* Additional test of the attribute counted_by for pointer field and its usage
+ in __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include "builtin-object-size-common.h"
+
+struct annotated {
+ int b;
+ int *c __attribute__ ((counted_by (b)));
+};
+
+struct annotated __attribute__((__noinline__)) setup (int attr_count)
+{
+ struct annotated p_array_annotated;
+ p_array_annotated.c = (int *) malloc (sizeof (int) * attr_count);
+ p_array_annotated.b = attr_count;
+
+ return p_array_annotated;
+}
+
+int main(int argc, char *argv[])
+{
+ struct annotated x = setup (10);
+ int *p = x.c;
+ x = setup (20);
+ EXPECT(__builtin_dynamic_object_size (p, 1), 10 * sizeof (int));
+ EXPECT(__builtin_dynamic_object_size (x.c, 1), 20 * sizeof (int));
+ free (p);
+ free (x.c);
+ DONE ();
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by.c b/gcc/testsuite/gcc.dg/pointer-counted-by.c
new file mode 100644
index 0000000..0f18828
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by.c
@@ -0,0 +1,111 @@
+/* Testing the correct usage of attribute counted_by for pointer field.
+ and also mixed pointer field and FMA field in the same structure. */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+int size;
+int *x __attribute__ ((counted_by (size))); /* { dg-error "attribute is not allowed for a non-field declaration" } */
+
+struct pointer_array_0 {
+ int count;
+ int array __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a non-array or non-pointer field" } */
+ int other;
+};
+
+int count;
+struct pointer_array_1 {
+ int other;
+ int *array_1 __attribute__ ((counted_by (count))); /* { dg-error "attribute is not a field declaration in the same structure as" } */
+ int array_fam[] __attribute__ ((counted_by (count))); /* { dg-error "attribute is not a field declaration in the same structure as" } */
+};
+
+struct pointer_array_2 {
+ float count1;
+ float count2;
+ int *array_2 __attribute__ ((counted_by (count1))); /* { dg-error "attribute is not a field declaration with an integer type" } */
+ int array_fam[] __attribute__ ((counted_by (count2))); /* { dg-error "attribute is not a field declaration with an integer type" } */
+};
+
+struct pointer_array_3 {
+ int count;
+ int *array_3 __attribute__ ((counted_by (count))) __attribute__ ((counted_by (count)));
+};
+
+struct pointer_array_4 {
+ int count1;
+ int count2;
+ int *array_4 __attribute__ ((counted_by (count1))) __attribute__ ((counted_by (count2))); /* { dg-error "conflicts with previous declaration" } */
+ float array_fam[] __attribute__ ((counted_by (count2))) __attribute__ ((counted_by (count1))); /* { dg-error "conflicts with previous declaration" } */
+};
+
+struct pointer_array_5 {
+ _Bool count;
+ int *array_5 __attribute__ ((counted_by (count)));
+};
+
+enum week {Mon, Tue, Wed};
+struct pointer_array_6 {
+ enum week days;
+ int *array_6 __attribute__ ((counted_by (days)));
+};
+
+struct pointer_array_7 {
+ int count;
+ void *array_7 __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a pointer to void" } */
+};
+
+struct pointer_array_8 {
+ int count;
+ int (*fpr)(int,int) __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a pointer to function" } */
+};
+
+struct item1 {
+ int a;
+ float b;
+};
+
+union item2 {
+ char *a;
+ int *b;
+};
+
+typedef struct item3 Item3;
+typedef union item4 Item4;
+
+struct item5 {
+ int a;
+ float b[];
+};
+
+/* Incomplete structure and union are allowed. */
+struct pointer_array_9 {
+ int count1;
+ int count2;
+ int count3;
+ struct item1 *array_1 __attribute__ ((counted_by (count1)));
+ union item2 *array_2 __attribute__ ((counted_by (count2)));
+ Item3 *array_3 __attribute__ ((counted_by (count3)));
+ Item4 *array_4 __attribute__ ((counted_by (count4)));
+ int count4;
+ int count5;
+ /* structure with flexible array member is not allowed. */
+ struct item5 *array_5 __attribute__ ((counted_by (count5))); /* { dg-error "attribute is not allowed for a pointer to structure or union with flexible array member" } */
+};
+
+struct mixed_array {
+ int count1;
+ float *array_1 __attribute__ ((counted_by (count1)));
+ float *array_2 __attribute__ ((counted_by (count1)));
+ int count2;
+ long *array_3 __attribute__ ((counted_by (count2)));
+ long array_4[] __attribute__ ((counted_by (count2)));
+};
+
+struct mixed_array_2 {
+ float *array_1 __attribute__ ((counted_by (count1)));
+ int count1;
+ float *array_2 __attribute__ ((counted_by (count1)));
+ long *array_3 __attribute__ ((counted_by (count2)));
+ int count2;
+ long array_4[] __attribute__ ((counted_by (count2)));
+};
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c
new file mode 100644
index 0000000..0653ecc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c
@@ -0,0 +1,51 @@
+/* Test the attribute counted_by for pointer fields and its usage in
+ bounds sanitizer combined with VLA. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+/* { dg-output "index 11 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 20 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 11 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 10 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+
+
+#include <stdlib.h>
+
+void __attribute__((__noinline__)) setup_and_test_vla (int n, int m)
+{
+ struct foo {
+ int n;
+ int (*p)[n] __attribute__((counted_by(n)));
+ } *f;
+
+ f = (struct foo *) malloc (sizeof (struct foo));
+ f->p = (int (*)[n]) malloc (m * sizeof (int[n]));
+ f->n = m;
+ f->p[m][n-1] = 1;
+ free (f->p);
+ free (f);
+ return;
+}
+
+void __attribute__((__noinline__)) setup_and_test_vla_1 (int n1, int n2, int m)
+{
+ struct foo {
+ int n;
+ int (*p)[n2][n1] __attribute__((counted_by(n)));
+ } *f;
+
+ f = (struct foo *) malloc (sizeof(struct foo));
+ f->p = (int (*)[n2][n1]) malloc (m * sizeof (int[n2][n1]));
+ f->n = m;
+ f->p[m][n2][n1] = 1;
+ free (f->p);
+ free (f);
+ return;
+}
+
+int main(int argc, char *argv[])
+{
+ setup_and_test_vla (10, 11);
+ setup_and_test_vla_1 (10, 11, 20);
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c
new file mode 100644
index 0000000..731422d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c
@@ -0,0 +1,42 @@
+/* Test the attribute counted_by for pointer fields and its usage in bounds
+ sanitizer. when counted_by field is negative value. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+
+#include <stdlib.h>
+
+struct annotated {
+ int b;
+ int *c __attribute__ ((counted_by (b)));
+} *array_annotated;
+
+void __attribute__((__noinline__)) setup (int annotated_count)
+{
+ array_annotated
+ = (struct annotated *)malloc (sizeof (struct annotated));
+ array_annotated->c = (int *) malloc (sizeof (int) * 10);
+ array_annotated->b = annotated_count;
+
+ return;
+}
+
+void __attribute__((__noinline__)) test (int annotated_index)
+{
+ array_annotated->c[annotated_index] = 2;
+}
+
+void cleanup ()
+{
+ free (array_annotated->c);
+ free (array_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ setup (-3);
+ test (2);
+ cleanup ();
+ return 0;
+}
+
+/* { dg-output "25:21: runtime error: index 2 out of bounds for type" } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c
new file mode 100644
index 0000000..52f202f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c
@@ -0,0 +1,42 @@
+/* Test the attribute counted_by for pointer fields and its usage in bounds
+ sanitizer. when counted_by field is zero value. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+
+#include <stdlib.h>
+
+struct annotated {
+ int b;
+ int *c __attribute__ ((counted_by (b)));
+} *array_annotated;
+
+void __attribute__((__noinline__)) setup (int annotated_count)
+{
+ array_annotated
+ = (struct annotated *)malloc (sizeof (struct annotated));
+ array_annotated->c = (int *)malloc (sizeof (int) * 10);
+ array_annotated->b = annotated_count;
+
+ return;
+}
+
+void __attribute__((__noinline__)) test (int annotated_index)
+{
+ array_annotated->c[annotated_index] = 2;
+}
+
+void cleanup ()
+{
+ free (array_annotated->c);
+ free (array_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ setup (0);
+ test (1);
+ cleanup ();
+ return 0;
+}
+
+/* { dg-output "25:21: runtime error: index 1 out of bounds for type" } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c
new file mode 100644
index 0000000..8ad7572
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c
@@ -0,0 +1,40 @@
+/* Test the attribute counted_by for pointer fields and its usage in
+ bounds sanitizer. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+
+#include <stdlib.h>
+
+struct annotated {
+ int b;
+ int *c __attribute__ ((counted_by (b)));
+} *p_array_annotated;
+
+void __attribute__((__noinline__)) setup (int annotated_count)
+{
+ p_array_annotated
+ = (struct annotated *)malloc (sizeof (struct annotated));
+ p_array_annotated->c = (int *) malloc (annotated_count * sizeof (int));
+ p_array_annotated->b = annotated_count;
+
+ return;
+}
+
+void cleanup ()
+{
+ free (p_array_annotated->c);
+ free (p_array_annotated);
+}
+
+int main(int argc, char *argv[])
+{
+ int i;
+ setup (10);
+ for (i = 0; i < 11; i++)
+ p_array_annotated->c[i] = 2; // goes boom at i == 10
+ cleanup ();
+ return 0;
+}
+
+
+/* { dg-output "34:25: runtime error: index 10 out of bounds for type" } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c
new file mode 100644
index 0000000..c5a1ac5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c
@@ -0,0 +1,46 @@
+/* Test the attribute counted_by for pointer fields and its usage in
+ bounds sanitizer. */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+
+#include <stdlib.h>
+
+struct pointer_array {
+ int b;
+ int *c;
+} *p_array;
+
+struct annotated {
+ int b;
+ int *c __attribute__ ((counted_by (b)));
+} *p_array_annotated;
+
+void __attribute__((__noinline__)) setup (int normal_count, int annotated_count)
+{
+ p_array
+ = (struct pointer_array *) malloc (sizeof (struct pointer_array));
+ p_array->c = (int *) malloc (normal_count * sizeof (int));
+ p_array->b = normal_count;
+
+ p_array_annotated
+ = (struct annotated *) malloc (sizeof (struct annotated));
+ p_array_annotated->c = (int *) malloc (annotated_count * sizeof (int));
+ p_array_annotated->b = annotated_count;
+
+ return;
+}
+
+void __attribute__((__noinline__)) test (int normal_index, int annotated_index)
+{
+ p_array->c[normal_index] = 1;
+ p_array_annotated->c[annotated_index] = 2;
+}
+
+int main(int argc, char *argv[])
+{
+ setup (10, 10);
+ test (10, 10);
+ return 0;
+}
+
+/* { dg-output "36:23: runtime error: index 10 out of bounds for type" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c b/gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c
new file mode 100644
index 0000000..f90ea13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd/shrn2subhn.c
@@ -0,0 +1,36 @@
+/* This test case checks that replacing a not+shift by a sub -1 works. */
+/* { dg-do compile } */
+/* { dg-additional-options "-O1" } */
+/* { dg-final { scan-assembler-times "\\tsubhn\\t" 6 } } */
+
+#include<arm_neon.h>
+
+uint8x8_t neg_narrow_v8hi(uint16x8_t a) {
+ uint16x8_t b = vmvnq_u16(a);
+ return vshrn_n_u16(b, 8);
+}
+
+uint8x8_t neg_narrow_vsubhn_v8hi(uint16x8_t a) {
+ uint16x8_t ones = vdupq_n_u16(0xffff);
+ return vsubhn_u16(ones, a);
+}
+
+uint16x4_t neg_narrow_v4si(uint32x4_t a) {
+ uint32x4_t b = vmvnq_u32(a);
+ return vshrn_n_u32(b, 16);
+}
+
+uint16x4_t neg_narrow_vsubhn_v4si(uint32x4_t a) {
+ uint32x4_t ones = vdupq_n_u32(0xffffffff);
+ return vsubhn_u32(ones, a);
+}
+
+uint32x2_t neg_narrow_v2di(uint64x2_t a) {
+ uint64x2_t b = ~a;
+ return vshrn_n_u64(b, 32);
+}
+
+uint32x2_t neg_narrow_vsubhn_v2di(uint64x2_t a) {
+ uint64x2_t ones = vdupq_n_u64(0xffffffffffffffff);
+ return vsubhn_u64(ones, a);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c b/gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c
index 4b90437..fab7a52 100644
--- a/gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c
+++ b/gcc/testsuite/gcc.target/powerpc/builtin_altivec_tr_stxvr_runnable.c
@@ -27,10 +27,10 @@ int
main () {
int i;
signed long sl;
- signed char sc, expected_sc;
- signed short ss, expected_ss;
- signed int si, expected_si;
- signed long long int sll, expected_sll;
+ signed char sc[2], expected_sc;
+ signed short ss[2], expected_ss;
+ signed int si[2], expected_si;
+ signed long long int sll[2], expected_sll;
signed char *psc;
signed short *pss;
signed int *psi;
@@ -41,56 +41,56 @@ main () {
printf("Data to store [%d] = 0x%llx %llx\n", i, val.ull[1], val.ull[0]);
#endif
- psc = &sc;
- pss = &ss;
- psi = &si;
- psll = &sll;
+ psc = &sc[0];
+ pss = &ss[0];
+ psi = &si[0];
+ psll = &sll[0];
sl = 1;
- sc = 0xA1;
+ sc[0] = 0xA1;
expected_sc = 0xA1;
__builtin_altivec_tr_stxvrbx (store_data, sl, psc);
- if (expected_sc != sc & 0xFF)
+ if (expected_sc != sc[0] & 0xFF)
#if DEBUG
printf(" ERROR: Signed char = 0x%x doesn't match expected value 0x%x\n",
- sc & 0xFF, expected_sc);
+ sc[0] & 0xFF, expected_sc);
#else
abort();
#endif
- ss = 0x52;
+ ss[0] = 0x52;
expected_ss = 0x1752;
__builtin_altivec_tr_stxvrhx (store_data, sl, pss);
- if (expected_ss != ss & 0xFFFF)
+ if (expected_ss != ss[0] & 0xFFFF)
#if DEBUG
printf(" ERROR: Signed short = 0x%x doesn't match expected value 0x%x\n",
- ss, expected_ss) & 0xFFFF;
+ ss[0], expected_ss) & 0xFFFF;
#else
abort();
#endif
- si = 0x21;
+ si[0] = 0x21;
expected_si = 0x54321721;
__builtin_altivec_tr_stxvrwx (store_data, sl, psi);
- if (expected_si != si)
+ if (expected_si != si[0])
#if DEBUG
printf(" ERROR: Signed int = 0x%x doesn't match expected value 0x%x\n",
- si, expected_si);
+ si[0], expected_si);
#else
abort();
#endif
- sll = 0x12FFULL;
+ sll[0] = 0x12FFULL;
expected_sll = 0xdcba9876543217FF;
__builtin_altivec_tr_stxvrdx (store_data, sl, psll);
- if (expected_sll != sll)
+ if (expected_sll != sll[0])
#if DEBUG
printf(" ERROR: Signed long long int = 0x%llx doesn't match expected value 0x%llx\n",
- sll, expected_sll);
+ sll[0], expected_sll);
#else
abort();
#endif
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c b/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c
index e0dd222..2fcaa95 100644
--- a/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O3 -mzarch -march=z13 -save-temps" } */
+/* { dg-options "-O3 -mzarch -march=z13 -save-temps -fno-stack-protector" } */
/* { dg-require-effective-target int128 } */
/* { dg-final { check-function-bodies "**" "" "" } } */
/* { dg-final { scan-assembler-not {\tvlpq\t} } } */
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c b/gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c
index 12c7e76..16afd1d 100644
--- a/gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-max-emu.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O3 -mzarch -march=z13 -save-temps" } */
+/* { dg-options "-O3 -mzarch -march=z13 -save-temps -fno-stack-protector" } */
/* { dg-require-effective-target int128 } */
/* { dg-final { check-function-bodies "**" "" "" } } */
/* { dg-final { scan-assembler-not {\tvmxq\t} } } */
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c b/gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c
index a9bcba3..0eb0916 100644
--- a/gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-min-emu.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O3 -mzarch -march=z13 -save-temps" } */
+/* { dg-options "-O3 -mzarch -march=z13 -save-temps -fno-stack-protector" } */
/* { dg-require-effective-target int128 } */
/* { dg-final { check-function-bodies "**" "" "" } } */
/* { dg-final { scan-assembler-not {\tvmnq\t} } } */
diff --git a/gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90 b/gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90
new file mode 100644
index 0000000..0663970
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray/coindexed_7.f90
@@ -0,0 +1,24 @@
+!{ dg-do compile }
+
+! Check PR120847 is fixed.
+
+program p
+ implicit none
+
+ type T
+ integer, allocatable :: i(:, :) [:]
+ end type T
+
+ type(T) :: o
+ integer, allocatable :: c[:]
+ integer :: i
+
+ c = 7
+
+ allocate(o%i(4, 5)[*], source=6)
+
+ do i = 1, 4
+ c = o%i(mod(i, 2), mod(i, 3))[1]
+ end do
+
+end program p
diff --git a/gcc/testsuite/gnat.dg/specs/finalizable2.ads b/gcc/testsuite/gnat.dg/specs/finalizable2.ads
new file mode 100644
index 0000000..b4a6bb1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/finalizable2.ads
@@ -0,0 +1,21 @@
+-- { dg-do compile }
+-- { dg-options "-gnatX0" }
+
+package Finalizable2 is
+
+ type Root is abstract tagged limited null record
+ with Finalizable => (Initialize => Initialize);
+
+ procedure Initialize (this : in out Root) is abstract;
+
+ type Ext (L : Natural) is new Root with record
+ A : String (1 .. L);
+ end record;
+
+ overriding procedure Initialize (this : in out Ext) is null;
+
+ function Make return Ext is (L => 3, A => "asd");
+
+ Obj : Ext := Make;
+
+end Finalizable2;
diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc
index f348673..ec4419f 100644
--- a/gcc/tree-object-size.cc
+++ b/gcc/tree-object-size.cc
@@ -773,10 +773,12 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
4th argument TYPE_OF_SIZE: A constant 0 with its TYPE being the same as the TYPE
of the object referenced by REF_TO_SIZE
6th argument: A constant 0 with the pointer TYPE to the original flexible
- array type.
+ array type or pointer field type.
The size of the element can be retrived from the TYPE of the 6th argument
- of the call, which is the pointer to the array type. */
+ of the call, which is the pointer to the original flexible array type or
+ the type of the original pointer field. */
+
static tree
access_with_size_object_size (const gcall *call, int object_size_type)
{
@@ -786,7 +788,7 @@ access_with_size_object_size (const gcall *call, int object_size_type)
gcc_assert (gimple_call_internal_p (call, IFN_ACCESS_WITH_SIZE));
/* The type of the 6th argument type is the pointer TYPE to the original
- flexible array type. */
+ flexible array type or to the original pointer type. */
tree pointer_to_array_type = TREE_TYPE (gimple_call_arg (call, 5));
gcc_assert (POINTER_TYPE_P (pointer_to_array_type));
tree element_type = TREE_TYPE (TREE_TYPE (pointer_to_array_type));
@@ -1854,6 +1856,17 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
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));
else
expr_object_size (osi, var, rhs);
}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 575987e..2782d61 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -3792,6 +3792,7 @@ vect_analyze_loop (class loop *loop, gimple *loop_vectorized_call,
/* When we selected a first vectorized epilogue, see if the target
suggests to have another one. */
if (!unlimited_cost_model (loop)
+ && !LOOP_VINFO_USING_PARTIAL_VECTORS_P (orig_loop_vinfo)
&& (orig_loop_vinfo->vector_costs->suggested_epilogue_mode ()
!= VOIDmode))
{
diff --git a/gcc/tree.cc b/gcc/tree.cc
index e9a83e4..6a055c8 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -4015,6 +4015,38 @@ decl_address_ip_invariant_p (const_tree op)
return false;
}
+/* Return true if T is an object with invariant address. */
+
+bool
+address_invariant_p (tree t)
+{
+ while (handled_component_p (t))
+ {
+ switch (TREE_CODE (t))
+ {
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ if (!tree_invariant_p (TREE_OPERAND (t, 1))
+ || TREE_OPERAND (t, 2) != NULL_TREE
+ || TREE_OPERAND (t, 3) != NULL_TREE)
+ return false;
+ break;
+
+ case COMPONENT_REF:
+ if (TREE_OPERAND (t, 2) != NULL_TREE)
+ return false;
+ break;
+
+ default:
+ break;
+ }
+ t = TREE_OPERAND (t, 0);
+ }
+
+ STRIP_ANY_LOCATION_WRAPPER (t);
+ return CONSTANT_CLASS_P (t) || decl_address_invariant_p (t);
+}
+
/* Return true if T is function-invariant (internal function, does
not handle arithmetic; that's handled in skip_simple_arithmetic and
@@ -4023,10 +4055,7 @@ decl_address_ip_invariant_p (const_tree op)
static bool
tree_invariant_p_1 (tree t)
{
- tree op;
-
- if (TREE_CONSTANT (t)
- || (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t)))
+ if (TREE_CONSTANT (t) || (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t)))
return true;
switch (TREE_CODE (t))
@@ -4036,30 +4065,7 @@ tree_invariant_p_1 (tree t)
return true;
case ADDR_EXPR:
- op = TREE_OPERAND (t, 0);
- while (handled_component_p (op))
- {
- switch (TREE_CODE (op))
- {
- case ARRAY_REF:
- case ARRAY_RANGE_REF:
- if (!tree_invariant_p (TREE_OPERAND (op, 1))
- || TREE_OPERAND (op, 2) != NULL_TREE
- || TREE_OPERAND (op, 3) != NULL_TREE)
- return false;
- break;
-
- case COMPONENT_REF:
- if (TREE_OPERAND (op, 2) != NULL_TREE)
- return false;
- break;
-
- default:;
- }
- op = TREE_OPERAND (op, 0);
- }
-
- return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op);
+ return address_invariant_p (TREE_OPERAND (t, 0));
default:
break;
diff --git a/gcc/tree.h b/gcc/tree.h
index 5de8d7e1..e87fa0f 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -5347,6 +5347,10 @@ extern tree staticp (tree);
extern tree save_expr (tree);
+/* Return true if T is an object with invariant address. */
+
+extern bool address_invariant_p (tree);
+
/* Return true if T is function-invariant. */
extern bool tree_invariant_p (tree);