This patch resolves PR target/106278 a regression on x86_64 caused by my
recent TImode STV improvements. Now that TImode STV can handle comparisons
such as "(set (regs:CC) (compare:CC (reg:TI) ...))" the convert_insn method
sensibly checks that the mode of the SET_DEST is TImode before setting
it to V1TImode [to avoid V1TImode appearing on the hard reg CC_FLAGS.
Hence the current code looks like:
if (GET_MODE (dst) == TImode)
{
tmp = find_reg_equal_equiv_note (insn);
if (tmp && GET_MODE (XEXP (tmp, 0)) == TImode)
PUT_MODE (XEXP (tmp, 0), V1TImode);
PUT_MODE (dst, V1TImode);
fix_debug_reg_uses (dst);
}
break;
which checks GET_MODE (dst) before calling PUT_MODE, and when a
change is made updating the REG_EQUAL_NOTE tmp if it exists.
The logical flaw (oversight) is that due to RTL sharing, the destination
of this set may already have been updated to V1TImode, as this chain is
being converted, but we still need to update any REG_EQUAL_NOTE that
still has TImode. Hence the correct code is actually:
if (GET_MODE (dst) == TImode)
{
PUT_MODE (dst, V1TImode);
fix_debug_reg_uses (dst);
}
if (GET_MODE (dst) == V1TImode)
{
tmp = find_reg_equal_equiv_note (insn);
if (tmp && GET_MODE (XEXP (tmp, 0)) == TImode)
PUT_MODE (XEXP (tmp, 0), V1TImode);
}
break;
While fixing this behavior, I noticed I had some indentation whitespace
issues and some vestigial dead code in this function/method that I've
taken the liberty of cleaning up (as obvious) in this patch.
2022-07-15 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
PR target/106278
* config/i386/i386-features.cc (general_scalar_chain::convert_insn):
Fix indentation whitespace.
(timode_scalar_chain::fix_debug_reg_uses): Likewise.
(timode_scalar_chain::convert_insn): Delete dead code.
Update TImode REG_EQUAL_NOTE even if the SET_DEST is already V1TI.
Fix indentation whitespace.
(convertible_comparison_p): Likewise.
(timode_scalar_to_vector_candidate_p): Likewise.
gcc/testsuite/ChangeLog
* gcc.dg/pr106278.c: New test case.
This changes the ad-hoc dumping of ranges in the gimple pretty printer
to use the pp_vrange utility function, which has the benefit of
handling all range types going forward and unifying the dumping code.
Instead of:
# RANGE [0, 51] NONZERO 0x3f
# RANGE ~[5, 10]
we would now get:
# RANGE [irange] long unsigned int [0, 51] NONZERO 0x3f
# RANGE [irange] int [-MIN, 4][11, MAX]
Tested on x86-64 Linux.
gcc/ChangeLog:
* gimple-pretty-print.cc (dump_ssaname_info): Use pp_vrange.
We need to dump global ranges from the gimple pretty printer code, but
all the vrange dumping facilities work with FILE handles. This patch
converts all the dumping methods to work with pretty printers, and
provides a wrapper so the FILE * methods continue to work for
debugging. I also cleaned up the code a bit.
Tested on x86-64 Linux.
gcc/ChangeLog:
* Makefile.in (OBJS): Add value-range-pretty-print.o.
* pretty-print.h (pp_vrange): New.
* value-range.cc (vrange::dump): Call pp version.
(unsupported_range::dump): Move to its own file.
(dump_bound_with_infinite_markers): Same.
(irange::dump): Same.
(irange::dump_bitmasks): Same.
(vrange::debug): Remove.
* value-range.h: Remove virtual designation for dump methods.
Remove dump_bitmasks method.
* value-range-pretty-print.cc: New file.
* value-range-pretty-print.h: New file.
We frequently do operations on the various (upcoming) range types.
The cascading if/switch statements of is_a<> are getting annoying and
repetitive.
The classic visitor pattern provides a clean way to implement classes
handling various range types without the need for endless
conditionals. It also helps us keep polluting the vrange API with
functionality that should frankly live elsewhere.
In a follow-up patch I will add pretty printing facilities for vrange
and unify them with the dumping code. This is a prime candidate for
the pattern, as the code isn't performance sensitive. Other instances
(?? the dispatch code in range-ops ??) may still benefit from the hand
coded conditionals, since they elide vtables in favor of the
discriminator bit in vrange.
Tested on x86-64 Linux.
gcc/ChangeLog:
* value-range.cc (irange::accept): New.
(unsupported_range::accept): New.
* value-range.h (class vrange_visitor): New.
(class vrange): Add accept method.
(class unsupported_range): Same.
(class Value_Range): Same.
This adjusts the API of label_text so that the data members are private
and cannot be modified by callers. Add accessors for them instead, and
make the accessors const-correct. Also rename moved_from () to the more
idiomatic release (). Also remove the unused take_or_copy () member
function which has confusing ownership semantics.
gcc/analyzer/ChangeLog:
* call-info.cc (call_info::print): Adjust to new label_text API.
* checker-path.cc (checker_event::dump): Likewise.
(region_creation_event::get_desc): Likewise.
(state_change_event::get_desc): Likewise.
(superedge_event::should_filter_p): Likewise.
(start_cfg_edge_event::get_desc): Likewise.
(call_event::get_desc): Likewise.
(return_event::get_desc): Likewise.
(warning_event::get_desc): Likewise.
(checker_path::dump): Likewise.
(checker_path::debug): Likewise.
* diagnostic-manager.cc (diagnostic_manager::prune_for_sm_diagnostic):
Likewise.
(diagnostic_manager::prune_interproc_events): Likewise.
* engine.cc (feasibility_state::maybe_update_for_edge):
Likewise.
* program-state.cc (sm_state_map::to_json): Likewise.
* region-model-impl-calls.cc (region_model::impl_call_analyzer_describe): Likewise.
(region_model::impl_call_analyzer_dump_capacity): Likewise.
* region.cc (region::to_json): Likewise.
* sm-malloc.cc (inform_nonnull_attribute): Likewise.
* store.cc (binding_map::to_json): Likewise.
(store::to_json): Likewise.
* supergraph.cc (superedge::dump): Likewise.
* svalue.cc (svalue::to_json): Likewise.
gcc/c-family/ChangeLog:
* c-format.cc (class range_label_for_format_type_mismatch):
Adjust to new label_text API.
gcc/ChangeLog:
* diagnostic-format-json.cc (json_from_location_range): Adjust
to new label_text API.
* diagnostic-format-sarif.cc (sarif_builder::make_location_object):
Likewise.
* diagnostic-show-locus.cc (struct pod_label_text): Likewise.
(layout::print_any_labels): Likewise.
* tree-diagnostic-path.cc (class path_label): Likewise.
(struct event_range): Likewise.
(default_tree_diagnostic_path_printer): Likewise.
(default_tree_make_json_for_path): Likewise.
libcpp/ChangeLog:
* include/line-map.h (label_text::take_or_copy): Remove.
(label_text::moved_from): Rename to release.
(label_text::m_buffer, label_text::m_owned): Make private.
(label_text::get, label_text::is_owned): New accessors.
When memchr is applied on a constant string of no more than the bytes of
a word, simplify memchr by checking each byte in the constant string.
int f (int a)
{
return __builtin_memchr ("AE", a, 2) != 0;
}
is simplified to
int f (int a)
{
return ((char) a == 'A' || (char) a == 'E') != 0;
}
gcc/
PR tree-optimization/103798
* tree-ssa-forwprop.cc: Include "tree-ssa-strlen.h".
(simplify_builtin_call): Inline memchr with constant strings of
no more than the bytes of a word.
* tree-ssa-strlen.cc (use_in_zero_equality): Make it global.
* tree-ssa-strlen.h (use_in_zero_equality): New.
gcc/testsuite/
PR tree-optimization/103798
* c-c++-common/pr103798-1.c: New test.
* c-c++-common/pr103798-2.c: Likewise.
* c-c++-common/pr103798-3.c: Likewise.
* c-c++-common/pr103798-4.c: Likewise.
* c-c++-common/pr103798-5.c: Likewise.
* c-c++-common/pr103798-6.c: Likewise.
* c-c++-common/pr103798-7.c: Likewise.
* c-c++-common/pr103798-8.c: Likewise.
* c-c++-common/pr103798-9.c: Likewise.
* c-c++-common/pr103798-10.c: Likewise.
gcc/fortran/ChangeLog:
PR fortran/106209
* decl.cc (add_init_expr_to_sym): Handle bad initializers for
implied-shape arrays.
gcc/testsuite/ChangeLog:
PR fortran/106209
* gfortran.dg/pr106209.f90: New test.
Co-authored-by: Steven G. Kargl <kargl@gcc.gnu.org>
Use -pthread only if we are going to use pthread functionality.
PR bootstrap/106156
lto-plugin/ChangeLog:
* Makefile.am: Use ac_lto_plugin_extra_ldflags for AM_LDFLAGS.
* configure.ac: Use AC_SUBST(ac_lto_plugin_extra_ldflags).
* Makefile.in: Regenerate.
* configure: Regenerate.
This happens from prepare_gimple_addressable for the variable to be marked
with DECL_NOT_GIMPLE_REG_P when its initialization is gimplified, so it's
apparently just a matter of setting the flag earlier.
gcc/
* gimplify.cc (lookup_tmp_var): Add NOT_GIMPLE_REG boolean parameter
and set DECL_NOT_GIMPLE_REG_P on the variable according to it.
(internal_get_tmp_var): Add NOT_GIMPLE_REG boolean parameter and
pass it in the call to lookup_tmp_var.
(get_formal_tmp_var): Pass false in the call to lookup_tmp_var.
(get_initialized_tmp_var): Likewise.
(prepare_gimple_addressable): Call internal_get_tmp_var instead of
get_initialized_tmp_var with NOT_GIMPLE_REG set to true.
gcc/testsuite/
* gnat.dg/opt98.ads, gnat.dg/opt98.adb: New test.
This patch fixes an non-fatal issue about negative constant values derived
from FP constant synthesis on hosts whose 'long' is wider than 'int32_t'.
And also replaces the dedicated code in FP constant synthesis split
pattern with the appropriate existing function call.
gcc/ChangeLog:
* config/xtensa/xtensa.md:
In FP constant synthesis split pattern, subcontract to
avoid_constant_pool_reference() as in the case of integer,
because it can handle well too. And cast to int32_t before
calling xtensa_constantsynth() in order to ignore upper 32-bit.
gcc/testsuite/ChangeLog:
* gcc.target/xtensa/constsynth_double.c:
Modify in order to catch the issue.
std::move in a return statement can prevent the NRVO:
<https://developers.redhat.com/blog/2019/04/12/understanding-when-not-to-stdmove-in-c>
PR106272 reports that we have two such cases in class label_text's
member functions. We have -Wpessimizing-move that's supposed to detect
problematic std::move uses, but in this case it didn't trigger. I've filed
PR106276 to track that.
PR preprocessor/106272
libcpp/ChangeLog:
* include/line-map.h (class label_text): Don't std::move in a return
statement.
Here we're crashing when substituting a non-dependent call to a
consteval operator, whose CALL_EXPR_OPERATOR_SYNTAX flag we try to
propagate to the result, but the result isn't a CALL_EXPR since the
selected function is consteval. This patch fixes this by checking the
result of extract_call_expr accordingly. (Note that we can't check
DECL_IMMEDIATE_FUNCTION_P here because we don't know which function was
selected by overload resolution from here.)
PR c++/105912
gcc/cp/ChangeLog:
* pt.cc (tsubst_copy_and_build) <case CALL_EXPR>: Guard against
NULL_TREE extract_call_expr result.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/consteval31.C: New test.
Here we incorrectly deem the calls to func1, func2 and tmpl2 as
ambiguous ahead of time ultimately because we mishandle dependence
of a constrained member function from the current instantiation.
In type_dependent_expression_p, we already consider dependence of a
TEMPLATE_DECL's constraints (via uses_outer_template_parms), but
neglect to do the same for a FUNCTION_DECL (such as that for func1).
And in satisfy_declaration_constraints, we give up if _any_ template
argument is dependent, but for non-dependent member functions from
the current instantiation (such as func2 and tmpl2), we can and must
check constraints as long as the innermost arguments aren't dependent.
PR c++/105842
gcc/cp/ChangeLog:
* constraint.cc (satisfy_declaration_constraints): Refine early
exit test for argument dependence.
* cp-tree.h (uses_outer_template_parms_in_constraints): Declare.
* pt.cc (template_class_depth): Handle TI_TEMPLATE being a
FIELD_DECL.
(usse_outer_template_parms): Factor out constraint dependence
test into ...
(uses_outer_template_parms_in_constraints): ... here.
(type_dependent_expression_p): Use it for FUNCTION_DECL.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/concepts-memtmpl6.C: New test.
For a signed integer, x < 0 is false if the sign bit in the nonzero
bits of X is clear.
Both CCP and ipa-cp can set the global nonzero bits in a range, which
means we can now use some of that information in evrp and subsequent
passes. I've adjusted two tests which now fold things earlier because
of this optimization.
Tested on x86-64 Linux.
gcc/ChangeLog:
* range-op.cc (operator_lt::fold_range): Use nonzero bits.
gcc/testsuite/ChangeLog:
* g++.dg/ipa/pure-const-3.C: Adjust.
* gcc.dg/pr102983.c: Adjust.
Every time we set a range we should take into account the nonzero
mask. This happens automatically for the set() methods, plus all the
other assignment, intersect, and union methods. Unfortunately I
forgot about the invert code.
Also, for good measure I audited the rest of the setters in
value_range.cc and plugged the legacy code to pessimize the masks to
-1 for union/intersect, since we don't support the masks on them (or
rather, we don't keep very good track of them).
Tested on x86-64 Linux.
gcc/ChangeLog:
* value-range.cc (irange::copy_to_legacy): Set nonzero mask.
(irange::legacy_intersect): Clear nonzero mask.
(irange::legacy_union): Same.
(irange::invert): Same.
The following gets away computing a dominance bitmap when
fast queries are not available and we are doing
back_propagate_equivalences. The comuted bitmap can be
cheaply kept up-to-date during the domwalk since it is
simply the set of blocks on the domwalk stack.
Abstraction of the threading makes this somewhat awkward
but it also fulfills the fixme comment in only considering
equivalences in already (domwalk) visited blocks, even when
querying from the outgoing block of a forward thread. Maybe
that's not what is intended but at least we have no testsuite
coverage of such missed equivalences.
* tree-ssa-dom.h (record_temporary_equivalences): Remove.
* tree-ssa-dom.cc (dom_jt_state::m_blocks_on_stack): New.
(dom_jt_state::get_blocks_on_stack): Likewise.
(dom_opt_dom_walker::dom_opt_dom_walker): Take dom_jt_state.
(back_propagate_equivalences): Remove dominator bitmap
compute and instead use passed in m_blocks_on_stack.
(record_temporary_equivalences): Likewise.
(record_equivalences_from_incoming_edge): Likewise.
(dom_opt_dom_walker::before_dom_children): Maintain and
pass down blocks on stack.
(dom_opt_dom_walker::after_dom_children): Likewise.
This reports violations for 4 units from gigi.
gcc/ada/
* gcc-interface/trans.cc (gigi): Report a violation of No_Dependence
on System.Stack_Checking if Stack_Check_Probes_On_Target is not set
and -fstack-check is specified.
(build_binary_op_trapv): Report violatiosn of No_Dependence on both
System.Arith_64 and System.Arith_128.
(add_decl_expr): If an initialized variable, report a violation of
No_Dependence on System.Memory_Copy for large aggregate types.
(gnat_to_gnu) <N_Op_Eq>: Report a violation
of No_Dependence on System.Memory_Compare for large aggregate types.
<N_Assignment_Statement>! Report a violation of No_Dependence on
System.Memory_Set, System.Memory_Move or else System.Memory_Copy for
large aggregate types.
* gcc-interface/utils2.cc (maybe_wrap_malloc): Report a violation of
No_Dependence on System.Memory.
(maybe_wrap_free): Add GNAT_NODE parameter and report a violation of
No_Dependence on System.Memory.
(build_call_alloc_dealloc): Adjust call to maybe_wrap_free.
This makes sure that the objects present in instantiations always have the
actual type instead of a local variant of the formal type in the debugging
information generated by the compiler (this was already the case when the
actual type is a record, a protected or a task type).
gcc/ada/
* gcc-interface/decl.cc (Gigi_Cloned_Subtype): New function.
(gnat_to_gnu_entity) <E_Signed_Integer_Subtype>: Call it to get the
cloned subtype, if any.
<E_Floating_Point_Subtype>: Likewise.
<E_Array_Subtype>: Likewise.
<E_Record_Subtype>: Likewise.
<E_Access_Subtype>: Likewise.
Deal with all cloned subtypes on the main path.
This is consistent with the other kinds of subtypes.
gcc/ada/
* gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Access_Subtype>: Do
not reuse the TYPE_DECL of the base type.
It no longer serves any useful purpose at this point.
gcc/ada/
* gcc-interface/utils.cc (gnat_pushdecl): Build DECL_ORIGINAL_TYPE
only for pointer types.
It comes from an overzealous assertion.
gcc/ada/
* gcc-interface/utils2.cc (build_binary_op) <EQ_EXPR>: Also accept
pointer-to-function types that are not variant of each other.
This happens when there is a size mismatch, but this must be accepted.
gcc/ada/
* gcc-interface/utils.cc (unchecked_convert): Also pad in most cases
if the source is not a scalar type but the destination is.
The current implementation may create dangling references from a superset
of the alias set of the dummy pointer-to-array type when it exists.
gcc/ada/
* gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Array_Type>: Save
and restore the alias set of the dummy pointer-to-array type.
gcc/ada/
* sem_ch13.adb (Check_And_Resolve_Storage_Model_Type_Argument):
Call the System.Case_Util.To_Mixed procedure rather than the
function, to avoid bootstrap problems.
The compiler currently rejects a Storage_Model_Type aspect that is not
specified with an aggregate, or that has an aggregate that does not
specify all defined "subaspects" (Address_Type, Null_Address, Allocate,
etc.). The RFC for this feature defines the aspect to fully default to
the native memory model when no aggregate is given, and also allows any
subaspects to be specified and others to default in the case where the
address type is the native address type (System.Address), whether that
address type is explicitly specified or defaulted. This set of changes
now supports that defaulting semantics. Note that the subaspect
retrieval functions in Sem_Util.Storage_Model_Support (which are called
by the compiler back ends) will now return Empty for any subprogram
subaspects (Allocate, Deallocate, etc.) that are defaulted in the aspect
(that is, in the native model case where the address type is
System.Address). Also in the native case, retrieval of defaulted
subaspects Address_Type and Null_Address will return the entities for
System.Address and System.Null_Address, respectively. Additionally,
error checks for multiple associations given for the same subaspect are
now done.
gcc/ada/
* aspects.ads (Aspect_Argument): Change the association for
Aspect_Storage_Model_Type from Expression to
Optional_Expression.
* exp_util.ads (Find_Storage_Op): Update comment to indicate
that Empty can be returned in the case where a storage-model
operation is defaulted.
* exp_util.adb (Find_Storage_Op): Allow the function to return
Empty in Storage_Model_Type case rather than raising
Program_Error, so that Procedure_To_Call fields in N_Allocator
and N_Free_Statement nodes will be set to Empty in the defaulted
native storage-model case.
* sem_ch13.adb: Add with and use of System.Case_Util (and
reformat context_clause).
(Check_Aspect_At_Freeze_Point): Return with no action for a
Storage_Model_Type aspect with no expression (fully-defaulted
native memory-model case).
(Resolve_Storage_Model_Type_Argument): If an Address_Type has
not been explicitly specified, then set Addr_Type to denote type
System.Address.
(Validate_Storage_Model_Type_Aspect): Return immediately in the
case where the aspect has no Expression (fully-defaulted native
memory-model case). No longer issue an error when Address_Type
isn't specified, and instead use type System.Address as the
default address type. When the address type is
System.Address (whether specified or defaulted), no longer issue
errors for any other "subaspects" that aren't specified, since
in that case those are allowed to default as well. Remove ???
comment about needing to check for duplicates, which is now
addressed.
(Check_And_Resolve_Storage_Model_Type_Argument): New procedure
to check that an association for a storage-model subaspect in
the aggregate has not been specified earlier in the aggregate,
and to then resolve the expression of the association and save
the resolved entity. Called by
Validate_Storage_Model_Type_Aspect.
* sem_util.ads (Storage_Model_Support): Update comments on specs
of the functions Get_Storage_Model_Type_Entity,
Storage_Model_Address_Type, and Storage_Model_Null_Address to
indicate the behavior when the address type is System.Address
(the native memory-model case).
* sem_util.adb
(Storage_Model_Support.Get_Storage_Model_Type_Entity): Suppress
the search for the given subaspect name (Nam) when the
Storage_Model_Type aspect is fully defaulted (i.e., no
Expression is present) and simply return. In cases where the
search is done, but no association that matches Nam is found,
return System.Address for the Name_Address_Type case, return
System.Null_Address for the Name_Null_Address case, and return
Empty for all other cases.
When a generic unit contains references to global entities (i.e.
entities declared outside of this generic unit), those references are
saved: from the analyzed copy of a generic unit (which is then
discarded) into a generic template (which is then instantiated, possibly
many times). To save those references we maintain an association from
nodes in the generic template to nodes in the analyzed copy. However,
this association breaks when analysis of the generic copy calls
Relocate_Node, which conceptually only moves the node, while in fact it
creates a copy with a new Node_Id.
In particular, this association was broken by calls to Relocate_Node
that happen when transforming various aspects into corresponding pragmas
or attribute definition clases. For the most common Pre and Post aspects
this was fixed years ago by not using Relocate_Node and simply sharing
the tree. This patch extends this fix to other aspects, in particular
those that allow non-static expressions.
gcc/ada/
* sem_ch13.adb (Relocate_Expression): New routine with code that
previously was only applied to Pre and Post aspects.
(Analyze_Aspect_Specifications): Apply the above routine to
other aspects, in particular to aspects Address, Attach_Handler,
Predicate and Interrupt_Priority.
Originally bodies-to-inline created for the frontend inlining were
analyzed with expansion disabled. Then, to facilitate inlining in
GNATprove mode, the analysis was changed to preanalysis.
However, preanalysis in this context works badly for calls in prefix
notation, because preanalysis assigns entities and types to nodes but
doesn't convert calls from prefix to ordinary notation. When the
body-to-inline is actually inlined, the (re)analysis of calls in prefix
notation fails.
The proper solution is rather to handle bodies-to-inline just like
generic templates.
From the user point of view, this patch fixes spurious errors both in
GNATprove (which uses frontend inlining by default) and in GNAT (where
frontend inlining is typically explicitly requested with -gnatN and
pragma Inline_Always).
gcc/ada/
* inline.adb (Build_Body_To_Inline): Instead of manipulating the
Full_Analysis flag, use the Inside_A_Generic flag (which is
conveniently manipulated by Start_Generic/End_Generic, together
with Expander_Active).
* sem_attr.adb (Analyze_Attribute_Old_Result): Adapt comment and
assertion to different flag that is set while building
body-to-inline.
Prefixes -fzero-call-used-regs and -fstrub could be mistaken for full
command-line options with the references to them in the GNAT RM. Make
it clearer that they require explicit choices.
gcc/ada/
* doc/gnat_rm/security_hardening_features.rst: Clarify the need
for choices after -fzero-call-used-regs and -fstrub.
* gnat_rm.texi: Regenerate.
When a formal generic type is marked as Ghost, the instantiation of that
generic will contain a generic subtype for the actual with the Ghost
pragma. Recognize this case.
gcc/ada/
* sem_prag.adb (Analyze_Pragma): Recognize a generated subtype
with Ghost pragma for generic instantiations.
After changes in provers and Why3, changes are needed to recover
automatic proof of System.Arith_64. This is the first part of it.
gcc/ada/
* libgnat/s-aridou.adb (Lemma_Mult_Div, Lemma_Powers): New
lemmas.
(Prove_Sign_Quotient): New local lemma.
(Prove_Signs): Expand definition of Big_R and Big_Q in the
postcondition. Add intermediate assertions.
(Double_Divide): Call new lemma.
(Lemma_Div_Eq): Provide body for proving lemma.
(Lemma_Powers_Of_2, Lemma_Shift_Without_Drop,
Prove_Dividend_Scaling, Prove_Multiplication, Prove_Z_Low): Call
lemmas, add intermediate assertions.
When examining expression of the first declaration of the inlined body
make sure that this declaration is in fact an object declaration.
gcc/ada/
* inline.adb (Has_Single_Return): Add guard for the subsequent
call to Expression.
In Ada 2012, the RM 4.5.2(9.8) clause prevents an equality operator for an
untagged record type from being declared after the type is frozen. While
the clause is implemented in GNAT, the implementation has a loophole which
lets subprogram bodies that are not the completion of a declaration pass
the check without being flagged.
gcc/ada/
* sem_ch6.adb (Analyze_Subprogram_Body_Helper): Set Acts_As_Spec
earlier if the body is not the completion of a declaration.
(Check_Untagged_Equality): Deal with subprogram bodies that are
not the completion of a declaration and make sure that they are
not flagged when they cause the freezing of the type themselves.
Give a warning on the freezing point of the type in more cases.
* sem_res.adb (Resolve_Equality_Op): Revert latest change.
The compiler incorrectly assumed the prefix for a slice returned in one
branch of an if expression has its bounds known at compile time and would
crash when this is not true.
gcc/ada/
* exp_ch4.adb (Expand_N_If_Expression): Test for compile time
known bounds when handling slices.