We implement class-scope using enum by injecting clones of the enum's
CONST_DECLs as fields of the class, for which CONST_DECL_USING_P is
true, so that qualified lookup naturally finds the enumerators.
Substitution into such a CONST_DECL currently ICEs however, because we
assume the DECL_CONTEXT is always the ENUMERAL_TYPE (which has
TYPE_VALUES) but in this case it's the RECORD_TYPE for the class scope
(which has TYPE_FIELDS).
Since these CONST_DECLs appear to always be non-dependent, this patch
fixes this by shortcutting substitution for CONST_DECLs that have
non-dependent DECL_CONTEXT. This subsumes the existing (and seemingly
dead) DECL_NAMESPACE_SCOPE_P early exit test and also benefits
substitution into ordinary non-dependent CONST_DECLs.
PR c++/103081
gcc/cp/ChangeLog:
* pt.cc (tsubst_copy) <case CONST_DECL>: Generalize
early exit test for namespace-scope decls to check dependence of
the enclosing scope instead. Remove dead early exit test.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/using-enum-10.C: New test.
* g++.dg/cpp2a/using-enum-10a.C: New test.
On riscv64, despite being lp64, we choose two IV candidates as on arm,
which prevents some of the expected sinking. Add an xfail for it.
for gcc/testsuite/ChangeLog
* gcc.dg/tree-ssa/ssa-sink-18.c: xfail sink2 on riscv64.
Like other platforms, riscv hits the uninitialized warning because the
optimizations don't eliminate the nonviable path that would enable it
to be omitted.
for gcc/testsuite/ChangeLog
* gcc.dg/uninit-pred-9_b.c: Add riscv*-*-* to the xfail list
for the bogus warning.
In r13-2573-gc81b60b8c6ff3d I split up the analyzer's region-creation
events to describe the memory space and capacity of the region as two
separate events to avoid combinatorial explosion of message wordings.
However I didn't take into account r13-1405-ge6c3bb379f515b which
added a pending_diagnostic::describe_region_creation_event vfunc which
could change the wording of region creation events.
Hence for:
#include <stdlib.h>
#include <stdint.h>
void test ()
{
int32_t *ptr = malloc (1);
free (ptr);
}
trunk currently emits:
Compiler Explorer (x86_64 trunk): https://godbolt.org/z/e3Td7c9s5:
<source>: In function 'test':
<source>:6:18: warning: allocated buffer size is not a multiple of the pointee's size [CWE-131] [-Wanalyzer-allocation-size]
6 | int32_t *ptr = malloc (1);
| ^~~~~~~~~~
'test': events 1-3
|
| 6 | int32_t *ptr = malloc (1);
| | ^~~~~~~~~~
| | |
| | (1) allocated 1 bytes here
| | (2) allocated 1 bytes here
| | (3) assigned to 'int32_t *' {aka 'int *'} here; 'sizeof (int32_t {aka int})' is '4'
|
where events (1) and (2) are different region_creation_events that have
had their wording overridden (also, with a "1 bytes" issue).
This patch reorganizes region creation events so that each
pending_diagnostic instead creates the events that is appropriate for it,
and the events have responsibility for their own wording.
With this patch, the above emits:
<source>: In function 'test':
<source>:6:18: warning: allocated buffer size is not a multiple of the pointee's size [CWE-131] [-Wanalyzer-allocation-size]
6 | int32_t *ptr = malloc (1);
| ^~~~~~~~~~
'test': events 1-2
|
| 6 | int32_t *ptr = malloc (1);
| | ^~~~~~~~~~
| | |
| | (1) allocated 1 byte here
| | (2) assigned to 'int32_t *' {aka 'int *'} here; 'sizeof (int32_t {aka int})' is '4'
|
fixing the duplicate event, and fixing the singular/plural issue.
gcc/analyzer/ChangeLog:
PR analyzer/107851
* analyzer.cc (make_label_text_n): Convert param "n" from int to
unsigned HOST_WIDE_INT.
* analyzer.h (make_label_text_n): Likewise for decl.
* bounds-checking.cc: Include "analyzer/checker-event.h" and
"analyzer/checker-path.h".
(out_of_bounds::add_region_creation_events): New.
(concrete_past_the_end::describe_region_creation_event): Replace
with...
(concrete_past_the_end::add_region_creation_events): ...this.
(symbolic_past_the_end::describe_region_creation_event): Delete.
* checker-event.cc (region_creation_event::region_creation_event):
Update for dropping all member data.
(region_creation_event::get_desc): Delete, splitting out into
region_creation_event_memory_space::get_desc,
region_creation_event_capacity::get_desc, and
region_creation_event_debug::get_desc.
(region_creation_event_memory_space::get_desc): New.
(region_creation_event_capacity::get_desc): New.
(region_creation_event_allocation_size::get_desc): New.
(region_creation_event_debug::get_desc): New.
* checker-event.h: Include "analyzer/program-state.h".
(enum rce_kind): Delete.
(class region_creation_event): Drop all member data.
(region_creation_event::region_creation_event): Make protected.
(region_creation_event::get_desc): Delete.
(class region_creation_event_memory_space): New.
(class region_creation_event_capacity): New.
(class region_creation_event_allocation_size): New.
(class region_creation_event_debug): New.
* checker-path.cc (checker_path::add_region_creation_events): Add
"pd" param. Call pending_diangnostic::add_region_creation_events.
Update for conversion of RCE_DEBUG to region_creation_event_debug.
* checker-path.h (checker_path::add_region_creation_events): Add
"pd" param.
* diagnostic-manager.cc (diagnostic_manager::build_emission_path):
Pass pending_diagnostic to
emission_path::add_region_creation_events.
(diagnostic_manager::build_emission_path): Pass path_builder to
add_event_on_final_node.
(diagnostic_manager::add_event_on_final_node): Add "pb" param.
Pass pending_diagnostic to
emission_path::add_region_creation_events.
(diagnostic_manager::add_events_for_eedge): Pass
pending_diagnostic to emission_path::add_region_creation_events.
* diagnostic-manager.h
(diagnostic_manager::add_event_on_final_node): Add "pb" param.
* pending-diagnostic.cc
(pending_diagnostic::add_region_creation_events): New.
* pending-diagnostic.h (struct region_creation): Delete.
(pending_diagnostic::describe_region_creation_event): Delete.
(pending_diagnostic::add_region_creation_events): New vfunc.
* region-model.cc: Include "analyzer/checker-event.h" and
"analyzer/checker-path.h".
(dubious_allocation_size::dubious_allocation_size): Initialize
m_has_allocation_event.
(dubious_allocation_size::describe_region_creation_event): Delete.
(dubious_allocation_size::describe_final_event): Update for
replacement of m_allocation_event with m_has_allocation_event.
(dubious_allocation_size::add_region_creation_events): New.
(dubious_allocation_size::m_allocation_event): Replace with...
(dubious_allocation_size::m_has_allocation_event): ...this.
gcc/testsuite/ChangeLog:
PR analyzer/107851
* gcc.dg/analyzer/allocation-size-4.c: Update expected wording.
* gcc.dg/analyzer/allocation-size-multiline-1.c: New test.
* gcc.dg/analyzer/allocation-size-multiline-2.c: New test.
* gcc.dg/analyzer/out-of-bounds-multiline-1.c: Update expected
wording.
* gcc.dg/analyzer/out-of-bounds-multiline-2.c: New test.
* gcc.dg/analyzer/out-of-bounds-read-char-arr.c: Update expected
wording.
* gcc.dg/analyzer/out-of-bounds-read-int-arr.c: Likewise.
* gcc.dg/analyzer/out-of-bounds-write-char-arr.c: Likewise.
* gcc.dg/analyzer/out-of-bounds-write-int-arr.c: Likewise.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Some of the new tests were failing with -fimplicit-constexpr. This
patch adjusts the expected diagnostic. Tested with
GXX_TESTSUITE_STDS=98,11,14,17,20,23 make check-c++ RUNTESTFLAGS="--target_board=unix\{,-fimplicit-constexpr\} dg.exp=spaceship-eq3.C"
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/constexpr-ex1.C: Adjust dg-error.
* g++.dg/cpp23/constexpr-nonlit10.C: Adjust dg-warning.
* g++.dg/cpp23/constexpr-nonlit11.C: Likewise.
* g++.dg/cpp2a/spaceship-eq3.C: Add dg-error.
This consists of 3 changes which stronger type checking has indicated
are incorrect.
gcc/
* fold-const.cc (fold_unary_loc): Check TREE_TYPE of node.
(tree_invalid_nonnegative_warnv_p): Likewise.
gcc/c-family/
* c-attribs.cc (handle_deprecated_attribute): Use type when
using TYPE_NAME.
Under the old logic for validate_switches, once suffix or starred got set,
they stayed set for all later switches found in the spec. So for e.g.
%{g*:%{%:debug-level-gt(0):
Once we see g*, starred is set. Then we see %:, and it sees that as a
zero-length switch, which because starred is still set, matches any and all
command-line options. So targets that use such a spec accept all options in
the driver, while ones that don't reject some, such as the recent
-nostdlib++.
This patch fixes the inconsistency, so all targets would complain about
-nostdlib++, and then sets SKIPOPT for it so they don't.
gcc/ChangeLog:
* gcc.cc (validate_switches): Reset suffix/starred on loop.
gcc/cp/ChangeLog:
* g++spec.cc (lang_specific_driver): Set SKIPOPT for nostdlib++.
Do not reload subreg pseudo if there are hard regs for subreg mode
but there are no hard regs for pseudo mode.
PR target/106462
gcc/ChangeLog:
* lra-constraints.cc (curr_insn_transform): Check available hard
regs for pseudo and its subreg to decide what to reload.
gcc/testsuite/ChangeLog:
* gcc.target/mips/pr106462.c: New test.
After supporting extendbfsf2_1, ix86_expand_fast_convert_bf_to_sf can
be improved with pslld either.
CONST_INT_P is not handled since constant shift can be optimized off.
gcc/ChangeLog:
* config/i386/i386-expand.cc
(ix86_expand_fast_convert_bf_to_sf): Use extendbfsf2_1 for
nonimmediate operand.
gcc/testsuite/ChangeLog:
* gcc.target/i386/cbranchbf4.c: New test.
On Tue, Aug 16, 2022 at 09:14:06AM +0100, Richard Sandiford via Gcc-patches wrote:
> IMO the correct low-effort fix is to save and restore recog_data
> in ix86_vector_duplicate_value. It's a relatively big copy,
> but the current code is pretty wasteful anyway (allocating at
> least a new SET and INSN for every query). Compared to the
> overhead of doing that, a copy to and from the stack shouldn't
> be too bad.
The following patch does that.
It isn't the first spot in the compiler that does that, not even the first
spot in the i386 backend.
In i386-expand.cc beyond these 2 recog_memoized calls there is one in
expand_vselect, but I think it is unlikely we'd run into these issues trying
to expand new permutations from splitters.
2022-12-02 Jakub Jelinek <jakub@redhat.com>
PR target/106577
* config/i386/i386-expand.cc (ix86_vector_duplicate_value): Save/restore
recog_data around recog_memoized calls.
* gcc.target/i386/pr106577.c: New test.
The PR84469 patch I've just posted regresses the for-21.C testcase,
when in OpenMP loop there are at least 2 associated loops and
in a template outer structured binding with non type dependent expression
is used in the expressions of some inner loop, we don't diagnose those
any longer, as the (weirdly worded) diagnostics was only done during
finish_id_expression -> mark_used which for the inner loop expressions
happens before the structured bindings are finalized. When in templates,
mark_used doesn't diagnose uses of non-deduced variables, and if the
range for expression is type dependent, it is similarly diagnosed during
instantiation. But newly with the PR84469 fix if the range for expression
is not type dependent, there is no place that would diagnose it, as during
instantiation the structured bindings are already deduced.
This patch ensures that the bug of using structured bindings from one
associated loop in other associated loops is diagnosed by the
c_omp_check_loop_iv code by ensuring that cp_finish_decomp is called
already during cp_convert_omp_range_for if the artificial iterator
has been successfully auto-deduced.
2022-12-02 Jakub Jelinek <jakub@redhat.com>
PR c++/84469
gcc/c-family/
* c-omp.cc (c_omp_is_loop_iterator): For range for with structured
binding return TREE_VEC_LENGTH (d->declv) even if decl is equal
to any of the structured binding decls.
gcc/cp/
* parser.cc (cp_convert_omp_range_for): After do_auto_deduction if
!processing_template_decl call cp_finish_decomp with
processing_template_decl temporarily incremented.
gcc/testsuite/
* g++.dg/gomp/for-21.C (f3, f6, f9): Adjust expected diagnostics.
* g++.dg/gomp/for-22.C: New test.
As shown on the decomp56.C testcase, if the range for expression
when using structured bindings is not type dependent, we deduce
the finish the structured binding types only when not in template
(cp_convert_range_for takes care of that), but if in templates,
do_range_for_auto_deduction is called instead and it doesn't handle
structured bindings. During instantiation they are handled later,
but during the parsing keeping the structured bindings type
dependent when they shouldn't be changes behavior.
The following patch calls cp_finish_decomp even from
do_range_for_auto_deduction.
The patch regresses the OpenMP g++.dg/gomp/for-21.C test (3 errors
are gone), I'll post an incremental patch for it momentarily.
2022-12-02 Jakub Jelinek <jakub@redhat.com>
PR c++/84469
* parser.cc (do_range_for_auto_deduction): Add DECOMP_FIRST_NAME
and DECOMP_CNT arguments. Call cp_finish_decomp if DECL
is a structured binding.
(cp_parser_range_for): Adjust do_range_for_auto_deduction caller.
(cp_convert_omp_range_for): Likewise.
* g++.dg/cpp1z/decomp56.C: New test.
* g++.dg/gomp/pr84469.C: New test.
This patches transforms ((x & 0x1) == 0) ? y : z <op> y -into
(-(typeof(y))(x & 0x1) & z) <op> y, where op is a '^' or a '|'. It also
transforms (cond (and (x , 0x1) != 0), (z op y), y ) into (-(and (x ,
0x1)) & z ) op y.
Matching this patterns allows GCC to generate branchless code for one of
the functions in coremark.
* match.pd ((x & 0x1) == 0) ? y : z <op> y
-> (-(typeof(y))(x & 0x1) & z) <op> y.
* gcc.dg/tree-ssa/branchless-cond.c: New test.
The following adds a --param to limit the depth of unswitched loop
nests. One can use --param max-unswitch-depth=1 to disable unswitching
of outer loops (the innermost loop will then be unswitched).
PR tree-optimization/107946
* params.opt (-param=max-unswitch-depth=): New.
* doc/invoke.texi (--param=max-unswitch-depth): Document.
* tree-ssa-loop-unswitch.cc (init_loop_unswitch_info): Honor
--param=max-unswitch-depth
This patch includes "(or later)" in the documentation of the gcc
subdirectory's --with-dwarf2 configure flag. Closes PR59447.
gcc/ChangeLog:
PR bootstrap/59447
* configure: Regenerate.
* configure.ac: Document --with-dwarf2 flag as also
applying to later DWARF standards.
* doc/install.texi: Likewise.
gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/string-ops-concat-pair.c: New test.
* gcc.dg/analyzer/string-ops-dup.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
;; if reg/mem op
(define_insn_reservation "slm_sseishft_3" 2
(and (eq_attr "cpu" "slm")
(and (eq_attr "type" "sseishft")
(not (match_operand 2 "immediate_operand"))))
"slm-complex, slm-all-eu")
in slm.md it will check operands[2] for type sseishft, but for
extendbfsf2_1 there's no second operand which caused ICE.
The patch set type from sseishft to sseishft1 to fix the issue.
gcc/ChangeLog:
PR target/107934
* config/i386/i386.md (extendbfsf2_1): Change type from
sseishft to sseishft1.
gcc/testsuite/ChangeLog:
* gcc.target/i386/pr107934.c: New test.
Here we end up giving the two BOUND_TEMPLATE_TEMPLATE_PARMs
C<decltype(f::t)> and C<decltype(g::t)> the same TYPE_CANONICAL because
the hash table that interns TYPE_CANONICAL for template type parameters
doesn't set the comparing_specializations flag which controls how
PARM_DECLs from different contexts compare equal.
Later, from spec_hasher::equal for the corresponding two specializations
A<C<decltype(f::t)>> and A<C<decltype(g::t)>>, we compare the two bound
ttps with comparing_specializations set hence they now (structurally)
compare different despite having the same TYPE_CANONICAL, and so we get
the error:
internal compiler error: same canonical type node for different types
'C<decltype (t)>' and 'C<decltype (t)>'
This suggests that we should be setting comparing_specializations from
ctp_hasher::equal to match spec_hasher::equal. But doing so introduces
a separate ICE in cpp2a/concepts-placeholder3.C:
internal compiler error: canonical types differ for identical types
'auto [requires ::same_as<<placeholder>, decltype(f::x)>]' and
'auto [requires ::same_as<<placeholder>, decltype(g::x)>]'
because norm_hasher::equal doesn't set comparing_specializations either.
I'm not sure when exactly we need to set comparing_specializations given
what it controls (TYPENAME_TYPE equality/hashing and PARM_DECL equality)
but it seems to be the conservative choice to set the flag wherever we
have a global hash table that relies on type equality. To that end this
patch sets comparing_specializations in ctp_hasher and norm_hasher, as
well as in atom_hasher and sat_hasher for good measure. This turns out
to be a compile time win of about 2% in some concepts tests, probably
because of the improved TYPENAME_TYPE hashing enabled by the flag.
PR c++/107539
gcc/cp/ChangeLog:
* constraint.cc (norm_hasher::hash, norm_hasher::equal): Set
comparing_specializations.
(sat_hasher::hash, sat_hasher::equal): Likewise.
* cp-tree.h (atom_hasher::hash, atom_hasher::equal): Likewise.
* pt.cc (ctp_hasher::hash, ctp_hasher::equal): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/template/canon-type-19.C: New test.
Not providing an error handler results in a null pointer dereference
when an error occurs.
Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
* include/std/stacktrace (stacktrace_entry::_S_err_handler): New
static function.
(stacktrace_entry, basic_stacktrace): Pass &_S_err_handler to
all calls to libbacktrace.
This patch fixes a type confusion bug in varasm.cc:assemble_variable.
The problem is that the current code calls:
sect = get_variable_section (decl, false);
and then accesses sect->named.name without checking whether the section
is in fact a named section. In the surrounding else clause, we only know
that SECTION_STYLE (sect) != SECTION_NOSWITCH, so it is possible that
the section is an unnamed section.
In practice, this means that we end up doing a wild string compare
between a function pointer and the string literal ".vtable_map_vars".
This is because sect->named.name aliases sect->unnamed.callback in the
section union.
This can be seen in GDB with a simple testcase such as "int x;".
This patch fixes the issue by checking the SECTION_STYLE of the section
is in fact SECTION_NAMED before trying to do the string comparison.
We drop the existing check of whether sect->named.name is non-NULL
because this should presumably always be the case for a named section.
gcc/ChangeLog:
* varasm.cc (assemble_variable): Fix type confusion bug when
checking for ".vtable_map_vars" section.
1. vector.md: remove tail && mask policy operand for mask mode operations since
we don't need them according to RVV ISA.
2. riscv-v.cc: adapt emit_pred_op for mask mode predicated mov since all RVV modes
including vector integer mode && vector float mode && vector bool mode are
all use emit_pred_op function. For vector integer mode && vector float mode,
we have instruction like vle.v/vse.v that we need tail && mask policy.
However, for vector bool mode, the instruction is vlm/vsm that we don't need
tail && mask policy. So we add a condition here to add tail && mask policy operand
during expand if it is not a vector bool modes.
This patch is to cleanup the code and make it be consistent with RVV ISA.
gcc/ChangeLog:
* config/riscv/riscv-v.cc (emit_pred_op): Adapt for mask mode.
* config/riscv/vector.md: Remove Tail && make policy operand for mask mode mov.
Provide a specific builtin for each possible value of '-march'.
gcc/ChangeLog:
* config/gcn/gcn-opts.h (TARGET_FIJI): -march=fiji.
(TARGET_VEGA10): -march=gfx900.
(TARGET_VEGA20): -march=gfx906.
(TARGET_GFX908): -march=gfx908.
(TARGET_GFX90a): -march=gfx90a.
* config/gcn/gcn.h (TARGET_CPU_CPP_BUILTINS): Define a builtin that
uniquely maps to '-march'.
This is necessary for unconstrained allocators with qualified expression.
gcc/ada/
* gcc-interface/trans.cc (get_storage_model_access): Strip any type
conversion around the node before looking into it.
Ada 2022 requires that an Aggregate aspect specification shall specify a
a name for at least one of Add_Named, Add_Unnamed, or Assign_Indexed.
Enforce this rule.
gcc/ada/
* sem_ch13.adb
(Validate_Aspect_Aggregate): Reject illegal case where none of
Add_Named, Add_Unnamed, and Assign_Indexed are specified.
When an Address attribute applies to an object that is a dereference of
an access value whose type has aspect Designated_Storage_Model, the
attribute will now be treated as having the address type associated
with the Storage_Model_Type of the access type's associated Storage_Model
object instead of being of type System.Address.
gcc/ada/
* sem_attr.adb (Analyze_Attribute, Attribute_Address): In the case
where the attribute's prefix is a dereference of a value of an
access type that has aspect Designated_Storage_Model (or a
renaming of such a dereference), set the attribute's type to the
corresponding Storage_Model_Type's associated address type rather
than System.Address.
This patch fixes a few minor issues in the GNAT library section of
the reference manual.
gcc/ada/
* doc/gnat_rm/the_gnat_library.rst: Fix minor issues.
* gnat_rm.texi: Regenerate.
After the recent patches to improve / tidy up MVE tests and patterns,
a few more tests need to be updated (replacing spaces with tabs).
gcc/testsuite/ChangeLog:
* gcc.target/arm/simd/mve-compare-1.c: Update.
* gcc.target/arm/simd/mve-compare-scalar-1.c: Update.
* gcc.target/arm/simd/mve-vabs.c: Update.
* gcc.target/arm/simd/mve-vadd-1.c: Update.
* gcc.target/arm/simd/mve-vadd-scalar-1.c: Update.
* gcc.target/arm/simd/mve-vcmp.c: Update.
* gcc.target/arm/simd/pr101325.c: Update.
The following changes the predicate representation to record the
value of a predicate with an empty set of AND predicates. That's
necessary to properly represent the conservative fallback for the
def vs use predicates. Since simplification now can result in
such an empty set this distinction becomes important and we need
to check for this as we otherwise ICE.
PR tree-optimization/107937
* gimple-predicate-analysis.h (predicate::is_true): New.
(predicate::is_false): Likewise.
(predicate::empty_val): Likewise.
(uninit_analysis::uninit_analysis): Properly initialize
def_preds.
* gimple-predicate-analysis.cc (simplify_1b): Indicate
whether the chain became empty.
(predicate::simplify): Release emptied chain before removing it.
(predicate::normalize): Replace temporary object with assertion.
(uninit_analysis::is_use_guarded): Deal with predicates
that simplify to true/false.
* gcc.dg/pr107937.c: New testcase.
The following makes sure to honor the backedge processing logic
that forces VARYING there.
PR tree-optimization/107935
* tree-ssa-sccvn.cc (visit_phi): Honor forced VARYING on
backedges.
* gcc.dg/torture/pr107935.c: New testcase.
On the first testcase we've regressed since 12 at -O2:
- movq 8(%rsi), %rax
- movq %rdi, %r8
- movq (%rsi), %rdi
+ movq (%rsi), %rax
+ movq 8(%rsi), %r8
movl %edx, %ecx
- shrdq %rdi, %rax
- movq %rax, (%r8)
+ xorl %r9d, %r9d
+ movq %rax, %rdx
+ xorl %eax, %eax
+ orq %r8, %rax
+ orq %r9, %rdx
+ shrdq %rdx, %rax
+ movq %rax, (%rdi)
On the second testcase we've emitted such terrible code
with the useless xors and ors for a long time.
For PR91681 the *concat<mode><dwi>3_{1,2,3,4} patterns have been added
but they allow just register inputs and register or memory offsettable
output.
The following patch fixes this by allowing also memory inputs on those
patterns, because the pattern is then split to 0-2 emit_move_insns or
one xchg and those can handle loads from memory too just fine.
So that we don't narrow memory loads (source has 128-bit (or for ia32
64-bit) load and we would make 64-bit (or for ia32 32-bit) load out of it),
register_operand -> nonmemory_operand change is done only for operands
in zero_extend arguments. o <- m, m or o <- m, r or o <- r, m alternatives
aren't used, we'd lack registers to perform the moves. But what is
in addition to the current ro <- r, r supported are r <- m, r and r <- r, m
(in that case we just need to be careful about corner cases, see what
emit_move_insn we'd call and if we wouldn't clobber registers used in m's
address before loading - split_double_concat handles that now) and
&r <- m, m (in that case I think the early clobber is the easiest solution).
The first testcase then on 12 -> patched trunk at -O2 changes:
- movq 8(%rsi), %rax
- movq %rdi, %r8
- movq (%rsi), %rdi
+ movq 8(%rsi), %r9
+ movq (%rsi), %r10
movl %edx, %ecx
- shrdq %rdi, %rax
- movq %rax, (%r8)
+ movq %r9, %rax
+ shrdq %r10, %rax
+ movq %rax, (%rdi)
so same amount of instructions and second testcase 12 -> patched trunk
at -O2 -m32:
- pushl %edi
- xorl %edi, %edi
pushl %esi
- movl 16(%esp), %esi
+ pushl %ebx
+ movl 16(%esp), %eax
movl 20(%esp), %ecx
- movl (%esi), %eax
- movl 4(%esi), %esi
- movl %eax, %edx
- movl $0, %eax
- orl %edi, %edx
- orl %esi, %eax
- shrdl %edx, %eax
movl 12(%esp), %edx
+ movl 4(%eax), %ebx
+ movl (%eax), %esi
+ movl %ebx, %eax
+ shrdl %esi, %eax
movl %eax, (%edx)
+ popl %ebx
popl %esi
- popl %edi
BTW, I wonder if we couldn't add additional patterns which would catch
the case where one of the operands is constant and how does this interact
with the stv pass in 32-bit mode where I think stv is right after combine,
so if we match these patterns, perhaps it would be nice to handle them
in stv (unless they are handled there already).
2022-12-01 Jakub Jelinek <jakub@redhat.com>
PR target/107627
* config/i386/i386.md (*concat<mode><dwi>3_1, *concat<mode><dwi>3_2):
For operands which are zero_extend arguments allow memory if
output operand is a register.
(*concat<mode><dwi>3_3, *concat<mode><dwi>3_4): Likewise. If
both input operands are memory, use early clobber on output operand.
* config/i386/i386-expand.cc (split_double_concat): Deal with corner
cases where one input is memory and the other is not and the address
of the memory input uses a register we'd overwrite before loading
the memory into a register.
* gcc.target/i386/pr107627-1.c: New test.
* gcc.target/i386/pr107627-2.c: New test.
The first is an actual bug: remove_contract_attributes was only keeping one
attribute. The second just helps flow analysis in optimizers and static
analyzers.
gcc/cp/ChangeLog:
* contracts.cc (remove_contract_attributes): Actually prepend
to the list.
* pt.cc (tsubst_contract): Only look for a postcondition if type is
nonnull.
For __builtin_ia32_vec_set_v16qi (a, -1, 2) with
!flag_signed_char. it's transformed to
__builtin_ia32_vec_set_v16qi (_4, 255, 2) in the gimple,
and expanded to (const_int 255) in the rtl. But for immediate_operand,
it expects (const_int 255) to be signed extended to
(const_int -1). The mismatch caused an unrecognizable insn error.
The patch converts (const_int 255) to (const_int -1) in the backend
expander.
gcc/ChangeLog:
PR target/107863
* config/i386/i386-expand.cc (ix86_expand_vec_set_builtin):
Convert op1 to target mode whenever mode mismatch.
gcc/testsuite/ChangeLog:
* gcc.target/i386/pr107863.c: New test.
gcc/analyzer/ChangeLog:
PR analyzer/106626
* bounds-checking.cc
(symbolic_past_the_end::describe_final_event): Delete, moving to
symbolic_buffer_overflow::describe_final_event and
symbolic_buffer_over_read::describe_final_event, eliminating
composition of text strings via "byte_str" and "m_dir_str".
(symbolic_past_the_end::m_dir_str): Delete field.
(symbolic_buffer_overflow::symbolic_buffer_overflow): Drop
m_dir_str.
(symbolic_buffer_overflow::describe_final_event): New, as noted
above.
(symbolic_buffer_over_read::symbolic_buffer_overflow): Drop
m_dir_str.
(symbolic_buffer_over_read::describe_final_event): New, as noted
above.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Convert out-of-bounds class hierarchy from:
pending_diagnostic
out_of_bounds
past_the_end
buffer_overflow (*)
buffer_over_read (*)
buffer_underwrite (*)
buffer_under_read (*)
symbolic_past_the_end
symbolic_buffer_overflow (*)
symbolic_buffer_over_read (*)
to:
pending_diagnostic
out_of_bounds
concrete_out_of_bounds
concrete_past_the_end
concrete_buffer_overflow (*)
concrete_buffer_over_read (*)
concrete_buffer_underwrite (*)
concrete_buffer_under_read (*)
symbolic_past_the_end
symbolic_buffer_overflow (*)
symbolic_buffer_over_read (*)
where the concrete classes (i.e. the instantiable ones) are marked
with a (*).
Doing so undercovered a bug where, for CWE-131-examples.c, we were
emitting an extra:
warning: heap-based buffer over-read [CWE-122] [-Wanalyzer-out-of-bounds]
at the:
WidgetList[numWidgets] = NULL;
The issue was that within set_next_state we get the rvalue for the LHS,
which looks like a read to the bounds-checker. The patch fixes this by
passing NULL as the region_model_context * for such accesses.
gcc/analyzer/ChangeLog:
* bounds-checking.cc (class out_of_bounds): Split out from...
(class concrete_out_of_bounds): New abstract subclass.
(class past_the_end): Rename to...
(class concrete_past_the_end): ...this, and make a subclass of
concrete_out_of_bounds.
(class buffer_overflow): Rename to...
(class concrete_buffer_overflow): ...this, and make a subclass of
concrete_past_the_end.
(class buffer_over_read): Rename to...
(class concrete_buffer_over_read): ...this, and make a subclass of
concrete_past_the_end.
(class buffer_underwrite): Rename to...
(class concrete_buffer_underwrite): ...this, and make a subclass
of concrete_out_of_bounds.
(class buffer_under_read): Rename to...
(class concrete_buffer_under_read): ...this, and make a subclass
of concrete_out_of_bounds.
(class symbolic_past_the_end): Convert to a subclass of
out_of_bounds.
(symbolic_buffer_overflow::get_kind): New.
(symbolic_buffer_over_read::get_kind): New.
(region_model::check_region_bounds): Update for renamings.
* engine.cc (impl_sm_context::set_next_state): Eliminate
"new_ctxt", passing NULL to get_rvalue instead.
(impl_sm_context::warn): Likewise.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
The region-creation event at the start of...
<source>: In function 'int_arr_write_element_after_end_off_by_one':
<source>:14:11: warning: buffer overflow [CWE-787] [-Wanalyzer-out-of-bounds]
14 | arr[10] = x;
| ~~~~~~~~^~~
event 1
|
| 10 | int32_t arr[10];
| | ^~~
| | |
| | (1) capacity is 40 bytes
|
+--> 'int_arr_write_element_after_end_off_by_one': events 2-3
|
| 12 | void int_arr_write_element_after_end_off_by_one(int32_t x)
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (2) entry to 'int_arr_write_element_after_end_off_by_one'
| 13 | {
| 14 | arr[10] = x; /* { dg-line line } */
| | ~~~~~~~~~~~
| | |
| | (3) out-of-bounds write from byte 40 till byte 43 but 'arr' ends at byte 40
|
<source>:14:11: note: write of 4 bytes to beyond the end of 'arr'
14 | arr[10] = x;
| ~~~~~~~~^~~
<source>:14:11: note: valid subscripts for 'arr' are '[0]' to '[9]'
...makes diagnostic_manager::finish_pruning consider the path to be
interprocedural, and so it doesn't prune the function entry event.
This patch tweaks diagnostic_path::interprocedural_p to ignore
leading events outside of any function, so that it considers the
path to be intraprocedural, and thus diagnostic_manager::finish_pruning
prunes the function entry event, leading to this simpler output:
<source>: In function 'int_arr_write_element_after_end_off_by_one':
<source>:14:11: warning: buffer overflow [CWE-787] [-Wanalyzer-out-of-bounds]
14 | arr[10] = x;
| ~~~~~~~~^~~
event 1
|
| 10 | int32_t arr[10];
| | ^~~
| | |
| | (1) capacity is 40 bytes
|
+--> 'int_arr_write_element_after_end_off_by_one': event 2
|
| 14 | arr[10] = x;
| | ~~~~~~~~^~~
| | |
| | (2) out-of-bounds write from byte 40 till byte 43 but 'arr' ends at byte 40
|
<source>:14:11: note: write of 4 bytes to beyond the end of 'arr'
<source>:14:11: note: valid subscripts for 'arr' are '[0]' to '[9]'
gcc/ChangeLog:
PR analyzer/106626
* diagnostic-path.h
(diagnostic_path::get_first_event_in_a_function): New decl.
* diagnostic.cc (diagnostic_path::get_first_event_in_a_function):
New.
(diagnostic_path::interprocedural_p): Ignore leading events that
are outside of any function.
gcc/testsuite/ChangeLog:
PR analyzer/106626
* gcc.dg/analyzer/out-of-bounds-multiline-1.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This patch tweaks the wording of -Wanalyzer-out-of-bounds:
* use the spellings/terminology of CWE:
* replace "underread" with "under-read", as per:
https://cwe.mitre.org/data/definitions/127.html
* replace "overread" with "over-read" as per:
https://cwe.mitre.org/data/definitions/126.html
* replace "underflow" with "underwrite" as per:
https://cwe.mitre.org/data/definitions/124.html
* wherever known, specify the memory region of the bad access,
so that it says e.g. "heap-based buffer over-read"
or "stack-based buffer over-read"
gcc/analyzer/ChangeLog:
PR analyzer/106626
* bounds-checking.cc (out_of_bounds::get_memory_space): New.
(buffer_overflow::emit): Use it.
(class buffer_overread): Rename to...
(class buffer_over_read): ...this.
(buffer_over_read::emit): Specify which memory space the read is
from, where known. Change "overread" to "over-read".
(class buffer_underflow): Rename to...
(class buffer_underwrite): ...this.
(buffer_underwrite::emit): Specify which memory space the write is
to, where known. Change "underflow" to "underwrite".
(class buffer_underread): Rename to...
(class buffer_under_read): Rename to...
(buffer_under_read::emit): Specify which memory space the read is
from, where known. Change "underread" to "under-read".
(symbolic_past_the_end::get_memory_space): New.
(symbolic_buffer_overflow::emit): Use it.
(class symbolic_buffer_overread): Rename to...
(class symbolic_buffer_over_read): ...this.
(symbolic_buffer_over_read::emit): Specify which memory space the
read is from, where known. Change "overread" to "over-read".
(region_model::check_symbolic_bounds): Update for class renaming.
(region_model::check_region_bounds): Likewise.
gcc/testsuite/ChangeLog:
PR analyzer/106626
* gcc.dg/analyzer/call-summaries-2.c: Update expected results.
* gcc.dg/analyzer/out-of-bounds-1.c: Likewise.
* gcc.dg/analyzer/out-of-bounds-2.c: Likewise.
* gcc.dg/analyzer/out-of-bounds-3.c: Likewise.
* gcc.dg/analyzer/out-of-bounds-4.c: Likewise.
* gcc.dg/analyzer/out-of-bounds-5.c: Likewise.
* gcc.dg/analyzer/out-of-bounds-container_of.c: Likewise.
* gcc.dg/analyzer/out-of-bounds-read-char-arr.c: Likewise. Rename
functions from "int_arr_" to "char_arr_".
* gcc.dg/analyzer/out-of-bounds-read-int-arr.c: Update expected
results.
* gcc.dg/analyzer/out-of-bounds-read-struct-arr.c: New test.
* gcc.dg/analyzer/out-of-bounds-write-char-arr.c: Update expected
results. Rename functions from "int_arr_" to "char_arr_".
* gcc.dg/analyzer/out-of-bounds-write-int-arr.c: Update expected
results.
* gcc.dg/analyzer/out-of-bounds-write-struct-arr.c: New test.
* gcc.dg/analyzer/pr101962.c: Update expected results.
* gcc.dg/analyzer/realloc-5.c: Update expected results.
* gcc.dg/analyzer/zlib-3.c: Update expected results.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>