diff options
30 files changed, 672 insertions, 132 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f3de0c1..95ca91e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2022-02-16 Andrew MacLeod <amacleod@redhat.com> + + * gimple-range-gori.cc (gori_compute::condexpr_adjust): Use + range_compatible_p instead of direct type comparison. + +2022-02-16 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/104544 + * combine.cc (try_combine): When looking for insn whose links + should be updated from i3 to i2, don't stop on debug insns, instead + skip over them. + +2022-02-16 Richard Sandiford <richard.sandiford@arm.com> + + PR target/100056 + * config/aarch64/iterators.md (LOGICAL_OR_PLUS): New iterator. + * config/aarch64/aarch64.md: Extend the PR100056 patterns + to handle plus in the same way as ior, if the operands have + no set bits in common. + 2022-02-15 Andrew MacLeod <amacleod@redhat.com> PR tree-optimization/104526 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 07f9f51..2215f56 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20220216 +20220217 diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index cab27465..4575f2f 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,37 @@ +2022-02-16 David Malcolm <dmalcolm@redhat.com> + + PR analyzer/104560 + * diagnostic-manager.cc (diagnostic_manager::build_emission_path): + Add region creation events for globals of interest. + (null_assignment_sm_context::get_old_program_state): New. + (diagnostic_manager::add_events_for_eedge): Move check for + changing dynamic extents from PK_BEFORE_STMT case to after the + switch on the dst_point's kind so that we can emit them for the + final stmt in a basic block. + * engine.cc (impl_sm_context::get_old_program_state): New. + * sm-malloc.cc (malloc_state_machine::get_default_state): Rewrite + detection of m_non_heap to use get_memory_space. + (free_of_non_heap::free_of_non_heap): Add freed_reg param. + (free_of_non_heap::subclass_equal_p): Update for changes to + fields. + (free_of_non_heap::emit): Drop m_kind in favor of + get_memory_space. + (free_of_non_heap::describe_state_change): Remove logic for + detecting alloca. + (free_of_non_heap::mark_interesting_stuff): Add region-creation of + m_freed_reg. + (free_of_non_heap::get_memory_space): New. + (free_of_non_heap::kind): Drop enum. + (free_of_non_heap::m_freed_reg): New field. + (free_of_non_heap::m_kind): Drop field. + (malloc_state_machine::on_stmt): Drop transition to m_non_heap. + (malloc_state_machine::handle_free_of_non_heap): New function, + split out from on_deallocator_call and on_realloc_call, adding + detection of the freed region. + (malloc_state_machine::on_deallocator_call): Use it. + (malloc_state_machine::on_realloc_call): Likewise. + * sm.h (sm_context::get_old_program_state): New vfunc. + 2022-02-15 David Malcolm <dmalcolm@redhat.com> PR analyzer/104524 diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc index 80bca6a..680016e 100644 --- a/gcc/analyzer/diagnostic-manager.cc +++ b/gcc/analyzer/diagnostic-manager.cc @@ -1272,6 +1272,35 @@ diagnostic_manager::build_emission_path (const path_builder &pb, interesting_t interest; pb.get_pending_diagnostic ()->mark_interesting_stuff (&interest); + + /* Add region creation events for any globals of interest, at the + beginning of the path. */ + { + for (auto reg : interest.m_region_creation) + switch (reg->get_memory_space ()) + { + default: + continue; + case MEMSPACE_CODE: + case MEMSPACE_GLOBALS: + case MEMSPACE_READONLY_DATA: + { + const region *base_reg = reg->get_base_region (); + if (tree decl = base_reg->maybe_get_decl ()) + if (DECL_P (decl) + && DECL_SOURCE_LOCATION (decl) != UNKNOWN_LOCATION) + { + emission_path->add_region_creation_event + (reg, + DECL_SOURCE_LOCATION (decl), + NULL_TREE, + 0); + } + } + } + } + + /* Walk EPATH, adding events as appropriate. */ for (unsigned i = 0; i < epath.m_edges.length (); i++) { const exploded_edge *eedge = epath.m_edges[i]; @@ -1569,6 +1598,11 @@ struct null_assignment_sm_context : public sm_context return NULL_TREE; } + const program_state *get_old_program_state () const FINAL OVERRIDE + { + return m_old_state; + } + const program_state *m_old_state; const program_state *m_new_state; const gimple *m_stmt; @@ -1729,46 +1763,47 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb, break; } - /* Look for changes in dynamic extents, which will identify - the creation of heap-based regions and alloca regions. */ - if (interest) - { - const region_model *src_model = src_state.m_region_model; - const region_model *dst_model = dst_state.m_region_model; - if (src_model->get_dynamic_extents () - != dst_model->get_dynamic_extents ()) - { - unsigned i; - const region *reg; - FOR_EACH_VEC_ELT (interest->m_region_creation, i, reg) - { - const region *base_reg = reg->get_base_region (); - const svalue *old_extents - = src_model->get_dynamic_extents (base_reg); - const svalue *new_extents - = dst_model->get_dynamic_extents (base_reg); - if (old_extents == NULL && new_extents != NULL) - switch (base_reg->get_kind ()) - { - default: - break; - case RK_HEAP_ALLOCATED: - case RK_ALLOCA: - emission_path->add_region_creation_event - (reg, - src_point.get_location (), - src_point.get_fndecl (), - src_stack_depth); - break; - } - } - } - } } } break; } + /* Look for changes in dynamic extents, which will identify + the creation of heap-based regions and alloca regions. */ + if (interest) + { + const region_model *src_model = src_state.m_region_model; + const region_model *dst_model = dst_state.m_region_model; + if (src_model->get_dynamic_extents () + != dst_model->get_dynamic_extents ()) + { + unsigned i; + const region *reg; + FOR_EACH_VEC_ELT (interest->m_region_creation, i, reg) + { + const region *base_reg = reg->get_base_region (); + const svalue *old_extents + = src_model->get_dynamic_extents (base_reg); + const svalue *new_extents + = dst_model->get_dynamic_extents (base_reg); + if (old_extents == NULL && new_extents != NULL) + switch (base_reg->get_kind ()) + { + default: + break; + case RK_HEAP_ALLOCATED: + case RK_ALLOCA: + emission_path->add_region_creation_event + (reg, + src_point.get_location (), + src_point.get_fndecl (), + src_stack_depth); + break; + } + } + } + } + if (pb.get_feasibility_problem () && &pb.get_feasibility_problem ()->m_eedge == &eedge) { diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index bff3779..f5b85ce 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -500,6 +500,11 @@ public: return m_unknown_side_effects; } + const program_state *get_old_program_state () const FINAL OVERRIDE + { + return m_old_state; + } + log_user m_logger; exploded_graph &m_eg; exploded_node *m_enode_for_diag; diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 69e8fa7..d4d7816 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -72,6 +72,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-phinodes.h" #include "tree-ssa-operands.h" #include "ssa-iterators.h" +#include "calls.h" #if ENABLE_ANALYZER @@ -1271,13 +1272,14 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt, in region-model-impl-calls.cc. Having them split out into separate functions makes it easier to put breakpoints on the handling of specific functions. */ + int callee_fndecl_flags = flags_from_decl_or_type (callee_fndecl); if (fndecl_built_in_p (callee_fndecl, BUILT_IN_NORMAL) && gimple_builtin_call_types_compatible_p (call, callee_fndecl)) switch (DECL_UNCHECKED_FUNCTION_CODE (callee_fndecl)) { default: - if (!DECL_PURE_P (callee_fndecl)) + if (!(callee_fndecl_flags & (ECF_CONST | ECF_PURE))) unknown_side_effects = true; break; case BUILT_IN_ALLOCA: @@ -1433,7 +1435,7 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt, /* Handle in "on_call_post". */ } else if (!fndecl_has_gimple_body_p (callee_fndecl) - && !DECL_PURE_P (callee_fndecl) + && (!(callee_fndecl_flags & (ECF_CONST | ECF_PURE))) && !fndecl_built_in_p (callee_fndecl)) unknown_side_effects = true; } diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc index 2f7a387..a5fa60d 100644 --- a/gcc/analyzer/sm-malloc.cc +++ b/gcc/analyzer/sm-malloc.cc @@ -356,10 +356,16 @@ public: if (const region_svalue *ptr = sval->dyn_cast_region_svalue ()) { const region *reg = ptr->get_pointee (); - const region *base_reg = reg->get_base_region (); - if (base_reg->get_kind () == RK_DECL - || base_reg->get_kind () == RK_STRING) - return m_non_heap; + switch (reg->get_memory_space ()) + { + default: + break; + case MEMSPACE_CODE: + case MEMSPACE_GLOBALS: + case MEMSPACE_STACK: + case MEMSPACE_READONLY_DATA: + return m_non_heap; + } } return m_start; } @@ -425,6 +431,11 @@ private: const gcall *call, const deallocator_set *deallocators, bool returns_nonnull = false) const; + void handle_free_of_non_heap (sm_context *sm_ctxt, + const supernode *node, + const gcall *call, + tree arg, + const deallocator *d) const; void on_deallocator_call (sm_context *sm_ctxt, const supernode *node, const gcall *call, @@ -1289,8 +1300,9 @@ class free_of_non_heap : public malloc_diagnostic { public: free_of_non_heap (const malloc_state_machine &sm, tree arg, + const region *freed_reg, const char *funcname) - : malloc_diagnostic (sm, arg), m_funcname (funcname), m_kind (KIND_UNKNOWN) + : malloc_diagnostic (sm, arg), m_freed_reg (freed_reg), m_funcname (funcname) { } @@ -1300,7 +1312,8 @@ public: FINAL OVERRIDE { const free_of_non_heap &other = (const free_of_non_heap &)base_other; - return (same_tree_p (m_arg, other.m_arg) && m_kind == other.m_kind); + return (same_tree_p (m_arg, other.m_arg) + && m_freed_reg == other.m_freed_reg); } bool emit (rich_location *rich_loc) FINAL OVERRIDE @@ -1308,44 +1321,32 @@ public: auto_diagnostic_group d; diagnostic_metadata m; m.add_cwe (590); /* CWE-590: Free of Memory not on the Heap. */ - switch (m_kind) + switch (get_memory_space ()) { default: + case MEMSPACE_HEAP: gcc_unreachable (); - case KIND_UNKNOWN: + case MEMSPACE_UNKNOWN: + case MEMSPACE_CODE: + case MEMSPACE_GLOBALS: + case MEMSPACE_READONLY_DATA: return warning_meta (rich_loc, m, OPT_Wanalyzer_free_of_non_heap, "%<%s%> of %qE which points to memory" " not on the heap", m_funcname, m_arg); break; - case KIND_ALLOCA: + case MEMSPACE_STACK: return warning_meta (rich_loc, m, OPT_Wanalyzer_free_of_non_heap, - "%<%s%> of memory allocated on the stack by" - " %qs (%qE) will corrupt the heap", - m_funcname, "alloca", m_arg); + "%<%s%> of %qE which points to memory" + " on the stack", + m_funcname, m_arg); break; } } - label_text describe_state_change (const evdesc::state_change &change) + label_text describe_state_change (const evdesc::state_change &) FINAL OVERRIDE { - /* Attempt to reconstruct what kind of pointer it is. - (It seems neater for this to be a part of the state, though). */ - if (change.m_expr && TREE_CODE (change.m_expr) == SSA_NAME) - { - gimple *def_stmt = SSA_NAME_DEF_STMT (change.m_expr); - if (gcall *call = dyn_cast <gcall *> (def_stmt)) - { - if (is_special_named_call_p (call, "alloca", 1) - || is_special_named_call_p (call, "__builtin_alloca", 1)) - { - m_kind = KIND_ALLOCA; - return label_text::borrow - ("memory is allocated on the stack here"); - } - } - } return label_text::borrow ("pointer is from here"); } @@ -1354,14 +1355,23 @@ public: return ev.formatted_print ("call to %qs here", m_funcname); } + void mark_interesting_stuff (interesting_t *interest) FINAL OVERRIDE + { + if (m_freed_reg) + interest->add_region_creation (m_freed_reg); + } + private: - enum kind + enum memory_space get_memory_space () const { - KIND_UNKNOWN, - KIND_ALLOCA - }; + if (m_freed_reg) + return m_freed_reg->get_memory_space (); + else + return MEMSPACE_UNKNOWN; + } + + const region *m_freed_reg; const char *m_funcname; - enum kind m_kind; }; /* struct allocation_state : public state_machine::state. */ @@ -1701,26 +1711,6 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt, if (any_pointer_p (lhs)) on_zero_assignment (sm_ctxt, stmt,lhs); - /* If we have "LHS = &EXPR;" and EXPR is something other than a MEM_REF, - transition LHS from start to non_heap. - Doing it for ADDR_EXPR(MEM_REF()) is likely wrong, and can lead to - unbounded chains of unmergeable sm-state on pointer arithmetic in loops - when optimization is enabled. */ - if (const gassign *assign_stmt = dyn_cast <const gassign *> (stmt)) - { - enum tree_code op = gimple_assign_rhs_code (assign_stmt); - if (op == ADDR_EXPR) - { - tree lhs = gimple_assign_lhs (assign_stmt); - if (lhs) - { - tree addr_expr = gimple_assign_rhs1 (assign_stmt); - if (TREE_CODE (TREE_OPERAND (addr_expr, 0)) != MEM_REF) - sm_ctxt->on_transition (node, stmt, lhs, m_start, m_non_heap); - } - } - } - /* Handle dereferences. */ for (unsigned i = 0; i < gimple_num_ops (stmt); i++) { @@ -1789,6 +1779,30 @@ malloc_state_machine::on_allocator_call (sm_context *sm_ctxt, } } +/* Handle deallocations of non-heap pointers. + non-heap -> stop, with warning. */ + +void +malloc_state_machine::handle_free_of_non_heap (sm_context *sm_ctxt, + const supernode *node, + const gcall *call, + tree arg, + const deallocator *d) const +{ + tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); + const region *freed_reg = NULL; + if (const program_state *old_state = sm_ctxt->get_old_program_state ()) + { + const region_model *old_model = old_state->m_region_model; + const svalue *ptr_sval = old_model->get_rvalue (arg, NULL); + freed_reg = old_model->deref_rvalue (ptr_sval, arg, NULL); + } + sm_ctxt->warn (node, call, arg, + new free_of_non_heap (*this, diag_arg, freed_reg, + d->m_name)); + sm_ctxt->set_next_state (call, arg, m_stop); +} + void malloc_state_machine::on_deallocator_call (sm_context *sm_ctxt, const supernode *node, @@ -1835,11 +1849,7 @@ malloc_state_machine::on_deallocator_call (sm_context *sm_ctxt, else if (state == m_non_heap) { /* non-heap -> stop, with warning. */ - tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); - sm_ctxt->warn (node, call, arg, - new free_of_non_heap (*this, diag_arg, - d->m_name)); - sm_ctxt->set_next_state (call, arg, m_stop); + handle_free_of_non_heap (sm_ctxt, node, call, arg, d); } } @@ -1894,11 +1904,7 @@ malloc_state_machine::on_realloc_call (sm_context *sm_ctxt, else if (state == m_non_heap) { /* non-heap -> stop, with warning. */ - tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); - sm_ctxt->warn (node, call, arg, - new free_of_non_heap (*this, diag_arg, - d->m_name)); - sm_ctxt->set_next_state (call, arg, m_stop); + handle_free_of_non_heap (sm_ctxt, node, call, arg, d); if (path_context *path_ctxt = sm_ctxt->get_path_context ()) path_ctxt->terminate_path (); } diff --git a/gcc/analyzer/sm.h b/gcc/analyzer/sm.h index fccfc88..7ce1c73 100644 --- a/gcc/analyzer/sm.h +++ b/gcc/analyzer/sm.h @@ -274,6 +274,10 @@ public: /* Are we handling an external function with unknown side effects? */ virtual bool unknown_side_effects_p () const { return false; } + virtual const program_state *get_old_program_state () const = 0; + + const svalue *get_old_svalue (tree expr) const; + protected: sm_context (int sm_idx, const state_machine &sm) : m_sm_idx (sm_idx), m_sm (sm) {} diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 340e2c0..77950b4 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,16 @@ +2022-02-16 Jakub Jelinek <jakub@redhat.com> + + PR c/104531 + * c-omp.cc (c_finish_omp_atomic): For MIN_EXPR/MAX_EXPR, try first + build_binary_op with LT_EXPR and only if that doesn't return + error_mark_node call build_modify_expr. + +2022-02-16 Jakub Jelinek <jakub@redhat.com> + + PR c/104510 + * c-common.cc (shorten_compare): Convert original arguments to + the original *restype_ptr when mixing binary and decimal float. + 2022-02-14 Richard Biener <rguenther@suse.de> PR c/104505 diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc index 15251ef..d2e480a 100644 --- a/gcc/config/rs6000/rs6000-c.cc +++ b/gcc/config/rs6000/rs6000-c.cc @@ -623,7 +623,11 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile) if (TARGET_FRSQRTES) builtin_define ("__RSQRTEF__"); if (TARGET_FLOAT128_TYPE) - builtin_define ("__FLOAT128_TYPE__"); + builtin_define ("__FLOAT128_TYPE__"); + if (ibm128_float_type_node) + builtin_define ("__SIZEOF_IBM128__=16"); + if (ieee128_float_type_node) + builtin_define ("__SIZEOF_FLOAT128__=16"); #ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB builtin_define ("__BUILTIN_CPU_SUPPORTS__"); #endif diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 90d4a79..2bc4c0e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2022-02-16 Patrick Palka <ppalka@redhat.com> + + PR c++/104507 + * constexpr.cc (potential_constant_expression_1) + <case NON_DEPENDENT_EXPR>: Return false instead of recursing. + Assert tf_error isn't set. + 2022-02-15 Jason Merrill <jason@redhat.com> PR c++/104107 diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index b9d0735..8274a4d 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,23 @@ +2022-02-16 Iain Buclaw <ibuclaw@gdcproject.org> + + * d-builtins.cc (d_build_builtins_module): Set purity of DECL_PURE_P + functions to PURE::const_. + * d-gimplify.cc (bit_field_ref): New function. + (d_gimplify_modify_expr): Handle implicit casting for assignments to + bit-fields. + (d_gimplify_unary_expr): New function. + (d_gimplify_binary_expr): New function. + (d_gimplify_expr): Handle UNARY_CLASS_P and BINARY_CLASS_P. + * d-target.cc (Target::_init): Initialize bitFieldStyle. + (TargetCPP::parameterType): Update signature. + (Target::supportsLinkerDirective): New function. + * dmd/MERGE: Merge upstream dmd 52844d4b1. + * expr.cc (ExprVisitor::visit (ThrowExp *)): New function. + * types.cc (d_build_bitfield_integer_type): New function. + (insert_aggregate_bitfield): New function. + (layout_aggregate_members): Handle inserting bit-fields into an + aggregate type. + 2022-01-31 Martin Liska <mliska@suse.cz> PR d/104287 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5230f00..7ddcc12 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,62 @@ +2022-02-16 David Malcolm <dmalcolm@redhat.com> + + PR analyzer/104560 + * g++.dg/analyzer/placement-new.C: Update expected wording. + * g++.dg/analyzer/pr100244.C: Likewise. + * gcc.dg/analyzer/attr-malloc-1.c (test_7): Likewise. + * gcc.dg/analyzer/malloc-1.c (test_24): Likewise. + (test_25): Likewise. + (test_26): Likewise. + (test_50a, test_50b, test_50c): New. + * gcc.dg/analyzer/malloc-callbacks.c (test_5): Update expected + wording. + * gcc.dg/analyzer/malloc-paths-8.c: Likewise. + * gcc.dg/analyzer/pr104560-1.c: New test. + * gcc.dg/analyzer/pr104560-2.c: New test. + * gcc.dg/analyzer/realloc-1.c (test_7): Updated expected wording. + * gcc.dg/analyzer/vla-1.c (test_2): New. Prune output from + -Wfree-nonheap-object. + +2022-02-16 Patrick Palka <ppalka@redhat.com> + + PR c++/104507 + * g++.dg/template/non-dependent21.C: New test. + +2022-02-16 Jakub Jelinek <jakub@redhat.com> + + PR target/104448 + * gcc.target/i386/pr104448.c: New test. + +2022-02-16 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/104544 + * gcc.dg/pr104544.c: New test. + +2022-02-16 Richard Sandiford <richard.sandiford@arm.com> + + * gcc.target/aarch64/atomic-inst-cas.c: Add + -Wno-invalid-memory-model. + +2022-02-16 Richard Sandiford <richard.sandiford@arm.com> + + * gcc.target/aarch64/bic-bitmask-1.c: Remove XFAIL. + +2022-02-16 Richard Sandiford <richard.sandiford@arm.com> + + PR target/100056 + * gcc.target/aarch64/pr100056.c: XFAIL the original UBFIZ test + and instead expect two UBFIZs + two ADD UXTBs. + +2022-02-16 Jakub Jelinek <jakub@redhat.com> + + PR c/104531 + * c-c++-common/gomp/atomic-31.c: New test. + +2022-02-16 Jakub Jelinek <jakub@redhat.com> + + PR c/104510 + * gcc.dg/dfp/pr104510.c: New test. + 2022-02-15 Peter Bergner <bergner@linux.ibm.com> * gcc.target/powerpc/htm-1.c: Retry intermittent failing tbegins. diff --git a/gcc/testsuite/g++.dg/analyzer/placement-new.C b/gcc/testsuite/g++.dg/analyzer/placement-new.C index b648a42..8905549 100644 --- a/gcc/testsuite/g++.dg/analyzer/placement-new.C +++ b/gcc/testsuite/g++.dg/analyzer/placement-new.C @@ -20,9 +20,9 @@ void test_2 (void) void test_3 (void) { - char buf[sizeof(int)]; + char buf[sizeof(int)]; // { dg-message "region created on stack here" } int *p = new(buf) int (42); - delete p; // { dg-warning "memory not on the heap" } + delete p; // { dg-warning "memory on the stack" } } // { dg-prune-output "-Wfree-nonheap-object" } diff --git a/gcc/testsuite/g++.dg/analyzer/pr100244.C b/gcc/testsuite/g++.dg/analyzer/pr100244.C index 261b3cf..1d5e13d 100644 --- a/gcc/testsuite/g++.dg/analyzer/pr100244.C +++ b/gcc/testsuite/g++.dg/analyzer/pr100244.C @@ -11,7 +11,7 @@ struct _Hashtable_alloc { int _M_single_bucket; int *_M_buckets; _Hashtable_alloc () { _M_buckets = &_M_single_bucket; } - ~_Hashtable_alloc () { delete _M_buckets; } // { dg-warning "not on the heap" } + ~_Hashtable_alloc () { delete _M_buckets; } // { dg-warning "on the stack" } }; void diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c index a9a2a3d..e956cf5 100644 --- a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c @@ -70,7 +70,7 @@ void test_6 (struct foo *p) void test_7 () { struct foo f; - foo_release (&f); /* { dg-warning "not on the heap" "analyzer" } */ + foo_release (&f); /* { dg-warning "on the stack" "analyzer" } */ /* { dg-warning "'foo_release' called on unallocated object 'f'" "non-analyzer" { target *-*-* } .-1 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c index 3219f85..d69a605 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c @@ -271,23 +271,23 @@ int *test_23a (int n) int test_24 (void) { - void *ptr = __builtin_alloca (sizeof (int)); /* { dg-message "memory is allocated on the stack here" } */ - free (ptr); /* { dg-warning "'free' of memory allocated on the stack by 'alloca' \\('ptr'\\) will corrupt the heap \\\[CWE-590\\\]" } */ + void *ptr = __builtin_alloca (sizeof (int)); /* { dg-message "region created on stack here" } */ + free (ptr); /* { dg-warning "'free' of 'ptr' which points to memory on the stack \\\[CWE-590\\\]" } */ } int test_25 (void) { - char tmp[100]; - void *p = tmp; /* { dg-message "pointer is from here" } */ - free (p); /* { dg-warning "'free' of 'p' which points to memory not on the heap \\\[CWE-590\\\]" } */ + char tmp[100]; /* { dg-message "region created on stack here" } */ + void *p = tmp; + free (p); /* { dg-warning "'free' of 'p' which points to memory on the stack \\\[CWE-590\\\]" } */ /* TODO: more precise messages here. */ } -char global_buffer[100]; +char global_buffer[100]; /* { dg-message "region created here" } */ int test_26 (void) { - void *p = global_buffer; /* { dg-message "pointer is from here" } */ + void *p = global_buffer; free (p); /* { dg-warning "'free' of 'p' which points to memory not on the heap \\\[CWE-590\\\]" } */ /* TODO: more precise messages here. */ } @@ -608,4 +608,22 @@ int test_49 (int i) return x; } +/* Free of function, and of label within function. */ + +void test_50a (void) +{ +} + +void test_50b (void) +{ + free (test_50a); /* { dg-warning "'free' of '&test_50a' which points to memory not on the heap \\\[CWE-590\\\]" } */ +} + +void test_50c (void) +{ + my_label: + free (&&my_label); /* { dg-warning "'free' of '&my_label' which points to memory not on the heap \\\[CWE-590\\\]" } */ +} + + /* { dg-prune-output "\\\[-Wfree-nonheap-object" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c b/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c index 8820ddd..c79f80d 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c @@ -61,9 +61,8 @@ int *test_5 (void) { allocator_t alloc_fn = get_alloca (); deallocator_t dealloc_fn = get_free (); - int *ptr = alloc_fn (sizeof (int)); /* { dg-message "pointer is from here" } */ - /* TODO: message should read "memory is allocated on the stack here". */ - dealloc_fn (ptr); /* { dg-warning "'free' of 'ptr' which points to memory not on the heap" } */ + int *ptr = alloc_fn (sizeof (int)); /* dg-message "region created on stack here" } */ + dealloc_fn (ptr); /* { dg-warning "'free' of 'ptr' which points to memory on the stack" } */ } static void __attribute__((noinline)) diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c index 9a7c414..4988f53 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c @@ -40,7 +40,7 @@ void test_3 (size_t sz) { void *ptr; if (sz <= LIMIT) - ptr = __builtin_alloca (sz); /* { dg-message "memory is allocated on the stack here" } */ + ptr = __builtin_alloca (sz); /* { dg-message "region created on stack here" } */ else ptr = malloc (sz); @@ -49,7 +49,7 @@ void test_3 (size_t sz) /* Bug: the "sz <= LIMIT" above should have been "sz < LIMIT", so there's a free-of-alloca when sz == LIMIT. */ if (sz >= LIMIT) - free (ptr); /* { dg-warning "'free' of memory allocated on the stack by 'alloca'" } */ + free (ptr); /* { dg-warning "'free' of 'ptr' which points to memory on the stack" } */ } /* { dg-bogus "leak of 'ptr'" } */ /* This can't happen, as "sz > 1024" && "sz <= 1023" is impossible. */ diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104560-1.c b/gcc/testsuite/gcc.dg/analyzer/pr104560-1.c new file mode 100644 index 0000000..aeab4b9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr104560-1.c @@ -0,0 +1,43 @@ +/* Reduced/adapted from false positive from -Wanalyzer-free-of-non-heap + seen on rdma-core. */ + +#include <stddef.h> + +#define check_types_match(expr1, expr2) \ + ((typeof(expr1) *)0 != (typeof(expr2) *)0) + +#define container_of(member_ptr, containing_type, member) \ + ((containing_type *) \ + ((char *)(member_ptr) \ + - container_off(containing_type, member)) \ + + check_types_match(*(member_ptr), ((containing_type *)0)->member)) + +#define container_off(containing_type, member) \ + offsetof(containing_type, member) + +struct ibv_device { + /* [...snip...] */ +}; + +struct verbs_device { + struct ibv_device device; /* Must be first */ + /* [...snip...] */ + int placeholder; +}; + +struct mlx5_device { + struct verbs_device verbs_dev; + int placeholder; +}; + +static inline struct mlx5_device *to_mdev(struct ibv_device *ibdev) +{ + return container_of(ibdev, struct mlx5_device, verbs_dev.device); +} + +static void mlx5_uninit_device(struct verbs_device *verbs_device) +{ + struct mlx5_device *dev = to_mdev(&verbs_device->device); + + __builtin_free(dev); /* { dg-bogus "not on the heap" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104560-2.c b/gcc/testsuite/gcc.dg/analyzer/pr104560-2.c new file mode 100644 index 0000000..f968a58 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr104560-2.c @@ -0,0 +1,26 @@ +struct ibv_device { + /* [...snip...] */ + int placeholder; +}; + +struct verbs_device { + struct ibv_device device; /* Must be first */ + /* [...snip...] */ + int placeholder; +}; + +struct mlx5_device { + struct verbs_device verbs_dev; + int placeholder; +}; + +static inline struct mlx5_device *to_mdev(struct ibv_device *ibdev) +{ + return (struct mlx5_device *)ibdev; +} + +static void mlx5_uninit_device(struct verbs_device *verbs_device) +{ + struct mlx5_device *dev = to_mdev(&verbs_device->device); + __builtin_free(dev); /* { dg-bogus "not on the heap" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c b/gcc/testsuite/gcc.dg/analyzer/realloc-1.c index ef117ad..9951e11 100644 --- a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/realloc-1.c @@ -59,8 +59,8 @@ void test_6 (size_t sz) void *test_7 (size_t sz) { - char buf[100]; - void *p = realloc (&buf, sz); /* { dg-warning "'realloc' of '&buf' which points to memory not on the heap" } */ + char buf[100]; /* { dg-message "region created on stack here" } */ + void *p = realloc (&buf, sz); /* { dg-warning "'realloc' of '&buf' which points to memory on the stack" } */ return p; } diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr63311.c b/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr63311.c new file mode 100644 index 0000000..a73289c --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr63311.c @@ -0,0 +1,134 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +int foo () +{ + static volatile int v = 42; + int __result_foo; + + __result_foo = (int) v; + return __result_foo; +} + +void test (int * restrict n, int * restrict flag) +{ + int i; + int j; + int k; + double t; + int tt; + double v; + + if (*flag) + { + t = 4.2e+1; + tt = foo (); + } + L_1: ; + v = 0.0; + { + int D_3353; + + D_3353 = *n; + i = 1; + if (i <= D_3353) + { + while (1) + { + { + int D_3369; + + v = 0.0; + if (*flag) + { + if (tt == i) + { + { + double M_0; + + M_0 = v; + if (t > M_0 || (int) (M_0 != M_0)) + { + M_0 = t; + } + v = M_0; + } + } + L_5:; + } + L_4:; + { + int D_3359; + + D_3359 = *n; + j = 1; + if (j <= D_3359) + { + while (1) + { + { + int D_3368; + + { + int D_3362; + + D_3362 = *n; + k = 1; + if (k <= D_3362) + { + while (1) + { + { + int D_3367; + + { + double D_3366; + double M_1; + + M_1 = v; + D_3366 = (double) __builtin_sinf ((float) (j * k)); + if (D_3366 > M_1 || (int) (M_1 != M_1)) + { + M_1 = D_3366; + } + v = M_1; + } + L_8:; + D_3367 = k == D_3362; + k = k + 1; + if (D_3367) goto L_9; + } + } + } + L_9:; + } + L_6:; + D_3368 = j == D_3359; + j = j + 1; + if (D_3368) goto L_7; + } + } + } + L_7:; + } + L_2:; + D_3369 = i == D_3353; + i = i + 1; + if (D_3369) goto L_3; + } + } + } + L_3:; + } +} + + +int main () +{ + int flag; + int n; + + n = 4; + flag = 0; + test (&n, &flag); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-pr104576.c b/gcc/testsuite/gcc.dg/analyzer/uninit-pr104576.c new file mode 100644 index 0000000..0b59acd --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/uninit-pr104576.c @@ -0,0 +1,16 @@ +float +test_1 (int *flag, float theta) +{ + float t; + float f; + + if (*flag) + t = 2.0f; + + f = __builtin_sinf (theta); + + if (*flag) + f *= t; + + return f; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/vla-1.c b/gcc/testsuite/gcc.dg/analyzer/vla-1.c index e5971c8..9561d74 100644 --- a/gcc/testsuite/gcc.dg/analyzer/vla-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/vla-1.c @@ -12,3 +12,12 @@ void test_1 (int n) s.b = 17; __analyzer_eval (s.b == 17); /* { dg-warning "TRUE" } */ } + +void test_2 (int n) +{ + int arr[n]; /* { dg-message "region created on stack here" } */ + __builtin_free (arr); /* { dg-warning "'free' of '<unknown>' which points to memory on the stack" } */ + // TODO: fix the "unknown" here +} + +/* { dg-prune-output "\\\[-Wfree-nonheap-object" } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr99708.c b/gcc/testsuite/gcc.target/powerpc/pr99708.c new file mode 100644 index 0000000..d478f7bc --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr99708.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { require-effective-target ppc_float128_sw } */ +/* { dg-options "-O2 -mvsx -mfloat128" } */ + +/* + * PR target/99708 + * + * Verify that __SIZEOF_FLOAT128__ and __SIZEOF_IBM128__ are properly defined. + */ + +#include <stdlib.h> + +int main (void) +{ + if (__SIZEOF_FLOAT128__ != sizeof (__float128) + || __SIZEOF_IBM128__ != sizeof (__ibm128)) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gfortran.dg/analyzer/uninit-pr63311.f90 b/gcc/testsuite/gfortran.dg/analyzer/uninit-pr63311.f90 new file mode 100644 index 0000000..34cc25d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/analyzer/uninit-pr63311.f90 @@ -0,0 +1,39 @@ +! { dg-additional-options "-O0" } + +MODULE M1 + IMPLICIT NONE +CONTAINS + INTEGER FUNCTION foo() + INTEGER, VOLATILE :: v=42 + foo=v + END FUNCTION + SUBROUTINE test(n,flag) + INTEGER :: n,i,j,k,l,tt + LOGICAL :: flag + REAL(KIND=8) :: v,t + IF (flag) THEN + t=42 + tt=foo() + ENDIF + v=0 + DO i=1,n + v=0 + IF (flag) THEN + IF (tt==i) v=MAX(v,t) + ENDIF + DO j=1,n + DO k=1,n + v=MAX(v,sin(REAL(j*k))) + ENDDO + ENDDO + ENDDO + END SUBROUTINE +END MODULE M1 + +USE M1 +INTEGER :: n +LOGICAL :: flag +n=4 +flag=.FALSE. +CALL test(n,flag) +END diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog index c77fe7a..e857dfc 100644 --- a/libbacktrace/ChangeLog +++ b/libbacktrace/ChangeLog @@ -1,3 +1,7 @@ +2022-02-16 Ian Lance Taylor <iant@golang.org> + + * dwarf.c (build_address_map): Initialize DWARF 5 fields of unit. + 2022-02-03 David Seifert <soap@gentoo.org> Jakub Jelinek <jakub@redhat.com> diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c index 2158bc1..45cc9e7 100644 --- a/libbacktrace/dwarf.c +++ b/libbacktrace/dwarf.c @@ -1989,14 +1989,16 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, break; case DW_AT_stmt_list: - if (abbrev->tag == DW_TAG_compile_unit + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) && (val.encoding == ATTR_VAL_UINT || val.encoding == ATTR_VAL_REF_SECTION)) u->lineoff = val.u.uint; break; case DW_AT_name: - if (abbrev->tag == DW_TAG_compile_unit) + if (abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) { name_val = val; have_name_val = 1; @@ -2004,7 +2006,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, break; case DW_AT_comp_dir: - if (abbrev->tag == DW_TAG_compile_unit) + if (abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) { comp_dir_val = val; have_comp_dir_val = 1; @@ -2012,19 +2015,22 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, break; case DW_AT_str_offsets_base: - if (abbrev->tag == DW_TAG_compile_unit + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) && val.encoding == ATTR_VAL_REF_SECTION) u->str_offsets_base = val.u.uint; break; case DW_AT_addr_base: - if (abbrev->tag == DW_TAG_compile_unit + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) && val.encoding == ATTR_VAL_REF_SECTION) u->addr_base = val.u.uint; break; case DW_AT_rnglists_base: - if (abbrev->tag == DW_TAG_compile_unit + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) && val.encoding == ATTR_VAL_REF_SECTION) u->rnglists_base = val.u.uint; break; @@ -2052,7 +2058,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, } if (abbrev->tag == DW_TAG_compile_unit - || abbrev->tag == DW_TAG_subprogram) + || abbrev->tag == DW_TAG_subprogram + || abbrev->tag == DW_TAG_skeleton_unit) { if (!add_ranges (state, dwarf_sections, base_address, is_bigendian, u, pcrange.lowpc, &pcrange, @@ -2060,9 +2067,10 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, (void *) addrs)) return 0; - /* If we found the PC range in the DW_TAG_compile_unit, we - can stop now. */ - if (abbrev->tag == DW_TAG_compile_unit + /* If we found the PC range in the DW_TAG_compile_unit or + DW_TAG_skeleton_unit, we can stop now. */ + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) && (pcrange.have_ranges || (pcrange.have_lowpc && pcrange.have_highpc))) return 1; @@ -3274,7 +3282,8 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata, /* The compile unit sets the base address for any address ranges in the function entries. */ - if (abbrev->tag == DW_TAG_compile_unit + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) && abbrev->attrs[i].name == DW_AT_low_pc) { if (val.encoding == ATTR_VAL_ADDRESS) diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index e329ffb..5359674 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,16 @@ +2022-02-16 Iain Buclaw <ibuclaw@gdcproject.org> + + * Makefile.in: Regenerate. + * libdruntime/MERGE: Merge upstream druntime dbd0c874. + * libdruntime/Makefile.am (DRUNTIME_CSOURCES): Add core/int128.d. + (DRUNTIME_DISOURCES): Add __builtins.di. + * libdruntime/Makefile.in: Regenerate. + * src/MERGE: Merge upstream phobos 896b1d0e1. + * src/Makefile.am (PHOBOS_DSOURCES): Add std/checkedint.d. + * src/Makefile.in: Regenerate. + * testsuite/testsuite_flags.in: Add -fall-instantiations to + --gdcflags. + 2022-01-03 Iain Buclaw <ibuclaw@gdcproject.org> * libdruntime/MERGE: Merge upstream druntime 759e6023. |