aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2022-02-16 20:22:34 -0800
committerIan Lance Taylor <iant@golang.org>2022-02-16 20:22:34 -0800
commit71e955da39cea0ebffcfee3432effa622d14ca99 (patch)
treea690b84e725e0c8c3ab35c53f16f3e156d1f10d7 /gcc
parentb43d6db9780462273c4d885a0111e3376c114c61 (diff)
parent837eb12629dd8a8a45fac9b8db57b29ecda46f14 (diff)
downloadgcc-71e955da39cea0ebffcfee3432effa622d14ca99.zip
gcc-71e955da39cea0ebffcfee3432effa622d14ca99.tar.gz
gcc-71e955da39cea0ebffcfee3432effa622d14ca99.tar.bz2
Merge from trunk revision 837eb12629dd8a8a45fac9b8db57b29ecda46f14.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/analyzer/ChangeLog34
-rw-r--r--gcc/analyzer/diagnostic-manager.cc105
-rw-r--r--gcc/analyzer/engine.cc5
-rw-r--r--gcc/analyzer/region-model.cc6
-rw-r--r--gcc/analyzer/sm-malloc.cc134
-rw-r--r--gcc/analyzer/sm.h4
-rw-r--r--gcc/c-family/ChangeLog13
-rw-r--r--gcc/config/rs6000/rs6000-c.cc6
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/d/ChangeLog20
-rw-r--r--gcc/testsuite/ChangeLog59
-rw-r--r--gcc/testsuite/g++.dg/analyzer/placement-new.C4
-rw-r--r--gcc/testsuite/g++.dg/analyzer/pr100244.C2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/attr-malloc-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-1.c32
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c5
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c4
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr104560-1.c43
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr104560-2.c26
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/realloc-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr63311.c134
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/uninit-pr104576.c16
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/vla-1.c9
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr99708.c21
-rw-r--r--gcc/testsuite/gfortran.dg/analyzer/uninit-pr63311.f9039
27 files changed, 635 insertions, 121 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