Update GCC80 to version 8.3
authorzrj <rimvydas.jasinskas@gmail.com>
Tue, 16 Apr 2019 02:37:34 +0000 (05:37 +0300)
committerzrj <zrj@dragonflybsd.org>
Tue, 16 Apr 2019 03:02:28 +0000 (06:02 +0300)
267 files changed:
contrib/gcc-8.0/LAST_UPDATED
contrib/gcc-8.0/gcc/BASE-VER
contrib/gcc-8.0/gcc/asan.c
contrib/gcc-8.0/gcc/asan.h
contrib/gcc-8.0/gcc/attribs.c
contrib/gcc-8.0/gcc/bb-reorder.c
contrib/gcc-8.0/gcc/c-family/c-ada-spec.c
contrib/gcc-8.0/gcc/c-family/c-attribs.c
contrib/gcc-8.0/gcc/c-family/c-common.c
contrib/gcc-8.0/gcc/c-family/c-common.h
contrib/gcc-8.0/gcc/c-family/c-cppbuiltin.c
contrib/gcc-8.0/gcc/c-family/c-omp.c
contrib/gcc-8.0/gcc/c-family/c-opts.c
contrib/gcc-8.0/gcc/c-family/c-ubsan.c
contrib/gcc-8.0/gcc/c-family/c-warn.c
contrib/gcc-8.0/gcc/c-family/c.opt
contrib/gcc-8.0/gcc/c/c-convert.c
contrib/gcc-8.0/gcc/c/c-decl.c
contrib/gcc-8.0/gcc/c/c-fold.c
contrib/gcc-8.0/gcc/c/c-parser.c
contrib/gcc-8.0/gcc/c/c-tree.h
contrib/gcc-8.0/gcc/c/c-typeck.c
contrib/gcc-8.0/gcc/calls.c
contrib/gcc-8.0/gcc/cfgcleanup.c
contrib/gcc-8.0/gcc/cfgexpand.c
contrib/gcc-8.0/gcc/cfgrtl.c
contrib/gcc-8.0/gcc/cgraph.c
contrib/gcc-8.0/gcc/cgraph.h
contrib/gcc-8.0/gcc/cgraphunit.c
contrib/gcc-8.0/gcc/collect2.c
contrib/gcc-8.0/gcc/combine.c
contrib/gcc-8.0/gcc/common.opt
contrib/gcc-8.0/gcc/common/config/i386/i386-common.c
contrib/gcc-8.0/gcc/config/i386/avx512bitalgintrin.h
contrib/gcc-8.0/gcc/config/i386/avx512bwintrin.h
contrib/gcc-8.0/gcc/config/i386/avx512fintrin.h
contrib/gcc-8.0/gcc/config/i386/avx512vbmi2vlintrin.h
contrib/gcc-8.0/gcc/config/i386/avx512vlbwintrin.h
contrib/gcc-8.0/gcc/config/i386/avx512vlintrin.h
contrib/gcc-8.0/gcc/config/i386/emmintrin.h
contrib/gcc-8.0/gcc/config/i386/i386-builtin.def
contrib/gcc-8.0/gcc/config/i386/i386.c
contrib/gcc-8.0/gcc/config/i386/i386.h
contrib/gcc-8.0/gcc/config/i386/i386.md
contrib/gcc-8.0/gcc/config/i386/predicates.md
contrib/gcc-8.0/gcc/config/i386/sse.md
contrib/gcc-8.0/gcc/config/i386/vpclmulqdqintrin.h
contrib/gcc-8.0/gcc/config/i386/x86-tune.def
contrib/gcc-8.0/gcc/config/i386/xsaveintrin.h
contrib/gcc-8.0/gcc/coverage.c
contrib/gcc-8.0/gcc/cp/call.c
contrib/gcc-8.0/gcc/cp/class.c
contrib/gcc-8.0/gcc/cp/constexpr.c
contrib/gcc-8.0/gcc/cp/cp-gimplify.c
contrib/gcc-8.0/gcc/cp/cp-tree.h
contrib/gcc-8.0/gcc/cp/cvt.c
contrib/gcc-8.0/gcc/cp/decl.c
contrib/gcc-8.0/gcc/cp/decl2.c
contrib/gcc-8.0/gcc/cp/error.c
contrib/gcc-8.0/gcc/cp/expr.c
contrib/gcc-8.0/gcc/cp/init.c
contrib/gcc-8.0/gcc/cp/lambda.c
contrib/gcc-8.0/gcc/cp/method.c
contrib/gcc-8.0/gcc/cp/name-lookup.c
contrib/gcc-8.0/gcc/cp/optimize.c
contrib/gcc-8.0/gcc/cp/parser.c
contrib/gcc-8.0/gcc/cp/pt.c
contrib/gcc-8.0/gcc/cp/search.c
contrib/gcc-8.0/gcc/cp/semantics.c
contrib/gcc-8.0/gcc/cp/tree.c
contrib/gcc-8.0/gcc/cp/typeck.c
contrib/gcc-8.0/gcc/cp/typeck2.c
contrib/gcc-8.0/gcc/dce.c
contrib/gcc-8.0/gcc/defaults.h
contrib/gcc-8.0/gcc/diagnostic-show-locus.c
contrib/gcc-8.0/gcc/diagnostic.c
contrib/gcc-8.0/gcc/dojump.c
contrib/gcc-8.0/gcc/dwarf2out.c
contrib/gcc-8.0/gcc/except.c
contrib/gcc-8.0/gcc/expmed.c
contrib/gcc-8.0/gcc/expr.c
contrib/gcc-8.0/gcc/expr.h
contrib/gcc-8.0/gcc/final.c
contrib/gcc-8.0/gcc/fold-const.c
contrib/gcc-8.0/gcc/function-tests.c
contrib/gcc-8.0/gcc/function.c
contrib/gcc-8.0/gcc/gcov.c
contrib/gcc-8.0/gcc/gcse.c
contrib/gcc-8.0/gcc/genmatch.c
contrib/gcc-8.0/gcc/gimple-fold.c
contrib/gcc-8.0/gcc/gimple-loop-interchange.cc
contrib/gcc-8.0/gcc/gimple-loop-jam.c
contrib/gcc-8.0/gcc/gimple-match-head.c
contrib/gcc-8.0/gcc/gimple-pretty-print.c
contrib/gcc-8.0/gcc/gimple-ssa-backprop.c
contrib/gcc-8.0/gcc/gimple-ssa-isolate-paths.c
contrib/gcc-8.0/gcc/gimple-ssa-sprintf.c
contrib/gcc-8.0/gcc/gimple-ssa-store-merging.c
contrib/gcc-8.0/gcc/gimple-ssa-strength-reduction.c
contrib/gcc-8.0/gcc/gimple.h
contrib/gcc-8.0/gcc/gimplify.c
contrib/gcc-8.0/gcc/graphite.h
contrib/gcc-8.0/gcc/ipa-cp.c
contrib/gcc-8.0/gcc/ipa-devirt.c
contrib/gcc-8.0/gcc/ipa-icf-gimple.c
contrib/gcc-8.0/gcc/ipa-icf.c
contrib/gcc-8.0/gcc/ipa-icf.h
contrib/gcc-8.0/gcc/ipa-inline.c
contrib/gcc-8.0/gcc/ipa-polymorphic-call.c
contrib/gcc-8.0/gcc/ipa-prop.c
contrib/gcc-8.0/gcc/ipa-pure-const.c
contrib/gcc-8.0/gcc/ipa-reference.c
contrib/gcc-8.0/gcc/ipa-utils.c
contrib/gcc-8.0/gcc/ipa-utils.h
contrib/gcc-8.0/gcc/ipa-visibility.c
contrib/gcc-8.0/gcc/ipa.c
contrib/gcc-8.0/gcc/langhooks.c
contrib/gcc-8.0/gcc/lower-subreg.c
contrib/gcc-8.0/gcc/lra.c
contrib/gcc-8.0/gcc/lto-cgraph.c
contrib/gcc-8.0/gcc/lto-opts.c
contrib/gcc-8.0/gcc/lto-streamer-out.c
contrib/gcc-8.0/gcc/lto-streamer.h
contrib/gcc-8.0/gcc/lto-wrapper.c
contrib/gcc-8.0/gcc/lto/lto-partition.c
contrib/gcc-8.0/gcc/lto/lto-symtab.c
contrib/gcc-8.0/gcc/lto/lto.c
contrib/gcc-8.0/gcc/match.pd
contrib/gcc-8.0/gcc/omp-expand.c
contrib/gcc-8.0/gcc/omp-low.c
contrib/gcc-8.0/gcc/omp-simd-clone.c
contrib/gcc-8.0/gcc/optabs.c
contrib/gcc-8.0/gcc/optc-save-gen.awk
contrib/gcc-8.0/gcc/opth-gen.awk
contrib/gcc-8.0/gcc/opts.c
contrib/gcc-8.0/gcc/passes.c
contrib/gcc-8.0/gcc/pretty-print.c
contrib/gcc-8.0/gcc/pretty-print.h
contrib/gcc-8.0/gcc/profile-count.h
contrib/gcc-8.0/gcc/profile.c
contrib/gcc-8.0/gcc/regcprop.c
contrib/gcc-8.0/gcc/regrename.c
contrib/gcc-8.0/gcc/rtl.h
contrib/gcc-8.0/gcc/rtlanal.c
contrib/gcc-8.0/gcc/stor-layout.c
contrib/gcc-8.0/gcc/store-motion.c
contrib/gcc-8.0/gcc/symtab.c
contrib/gcc-8.0/gcc/tracer.c
contrib/gcc-8.0/gcc/tree-cfg.c
contrib/gcc-8.0/gcc/tree-chrec.c
contrib/gcc-8.0/gcc/tree-complex.c
contrib/gcc-8.0/gcc/tree-core.h
contrib/gcc-8.0/gcc/tree-data-ref.c
contrib/gcc-8.0/gcc/tree-dump.c
contrib/gcc-8.0/gcc/tree-inline.c
contrib/gcc-8.0/gcc/tree-loop-distribution.c
contrib/gcc-8.0/gcc/tree-predcom.c
contrib/gcc-8.0/gcc/tree-profile.c
contrib/gcc-8.0/gcc/tree-ssa-alias.c
contrib/gcc-8.0/gcc/tree-ssa-ccp.c
contrib/gcc-8.0/gcc/tree-ssa-coalesce.c
contrib/gcc-8.0/gcc/tree-ssa-copy.c
contrib/gcc-8.0/gcc/tree-ssa-dom.c
contrib/gcc-8.0/gcc/tree-ssa-loop-ivcanon.c
contrib/gcc-8.0/gcc/tree-ssa-loop-split.c
contrib/gcc-8.0/gcc/tree-ssa-math-opts.c
contrib/gcc-8.0/gcc/tree-ssa-phiprop.c
contrib/gcc-8.0/gcc/tree-ssa-propagate.c
contrib/gcc-8.0/gcc/tree-ssa-propagate.h
contrib/gcc-8.0/gcc/tree-ssa-reassoc.c
contrib/gcc-8.0/gcc/tree-ssa-sccvn.c
contrib/gcc-8.0/gcc/tree-ssa-strlen.c
contrib/gcc-8.0/gcc/tree-ssa-strlen.h
contrib/gcc-8.0/gcc/tree-ssa-structalias.c
contrib/gcc-8.0/gcc/tree-ssa-tail-merge.c
contrib/gcc-8.0/gcc/tree-ssa-threadupdate.c
contrib/gcc-8.0/gcc/tree-ssa-uncprop.c
contrib/gcc-8.0/gcc/tree-ssa.c
contrib/gcc-8.0/gcc/tree-streamer-in.c
contrib/gcc-8.0/gcc/tree-streamer-out.c
contrib/gcc-8.0/gcc/tree-switch-conversion.c
contrib/gcc-8.0/gcc/tree-vect-data-refs.c
contrib/gcc-8.0/gcc/tree-vect-generic.c
contrib/gcc-8.0/gcc/tree-vect-loop.c
contrib/gcc-8.0/gcc/tree-vect-slp.c
contrib/gcc-8.0/gcc/tree-vect-stmts.c
contrib/gcc-8.0/gcc/tree-vectorizer.h
contrib/gcc-8.0/gcc/tree-vrp.c
contrib/gcc-8.0/gcc/tree.c
contrib/gcc-8.0/gcc/tree.h
contrib/gcc-8.0/gcc/valtrack.c
contrib/gcc-8.0/gcc/value-prof.c
contrib/gcc-8.0/gcc/value-prof.h
contrib/gcc-8.0/gcc/var-tracking.c
contrib/gcc-8.0/gcc/varasm.c
contrib/gcc-8.0/gcc/varpool.c
contrib/gcc-8.0/gcc/vr-values.c
contrib/gcc-8.0/libbacktrace/elf.c
contrib/gcc-8.0/libgcc/config/i386/cpuinfo.c
contrib/gcc-8.0/libgcc/unwind-dw2.c
contrib/gcc-8.0/libiberty/simple-object-elf.c
contrib/gcc-8.0/libiberty/simple-object.c
contrib/gcc-8.0/libstdc++-v3/include/bits/alloc_traits.h
contrib/gcc-8.0/libstdc++-v3/include/bits/basic_string.h
contrib/gcc-8.0/libstdc++-v3/include/bits/basic_string.tcc
contrib/gcc-8.0/libstdc++-v3/include/bits/c++config
contrib/gcc-8.0/libstdc++-v3/include/bits/char_traits.h
contrib/gcc-8.0/libstdc++-v3/include/bits/cpp_type_traits.h
contrib/gcc-8.0/libstdc++-v3/include/bits/forward_list.h
contrib/gcc-8.0/libstdc++-v3/include/bits/forward_list.tcc
contrib/gcc-8.0/libstdc++-v3/include/bits/fs_dir.h
contrib/gcc-8.0/libstdc++-v3/include/bits/fs_path.h
contrib/gcc-8.0/libstdc++-v3/include/bits/hashtable.h
contrib/gcc-8.0/libstdc++-v3/include/bits/locale_conv.h
contrib/gcc-8.0/libstdc++-v3/include/bits/locale_facets.h
contrib/gcc-8.0/libstdc++-v3/include/bits/node_handle.h
contrib/gcc-8.0/libstdc++-v3/include/bits/quoted_string.h
contrib/gcc-8.0/libstdc++-v3/include/bits/random.tcc
contrib/gcc-8.0/libstdc++-v3/include/bits/regex.h
contrib/gcc-8.0/libstdc++-v3/include/bits/regex_automaton.h
contrib/gcc-8.0/libstdc++-v3/include/bits/regex_compiler.tcc
contrib/gcc-8.0/libstdc++-v3/include/bits/regex_executor.tcc
contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr.h
contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr_base.h
contrib/gcc-8.0/libstdc++-v3/include/bits/stl_bvector.h
contrib/gcc-8.0/libstdc++-v3/include/bits/stl_iterator.h
contrib/gcc-8.0/libstdc++-v3/include/bits/stl_list.h
contrib/gcc-8.0/libstdc++-v3/include/bits/stl_map.h
contrib/gcc-8.0/libstdc++-v3/include/bits/stl_multimap.h
contrib/gcc-8.0/libstdc++-v3/include/bits/stl_pair.h
contrib/gcc-8.0/libstdc++-v3/include/bits/stl_queue.h
contrib/gcc-8.0/libstdc++-v3/include/bits/stl_stack.h
contrib/gcc-8.0/libstdc++-v3/include/bits/stl_vector.h
contrib/gcc-8.0/libstdc++-v3/include/bits/unique_ptr.h
contrib/gcc-8.0/libstdc++-v3/include/bits/unordered_map.h
contrib/gcc-8.0/libstdc++-v3/include/bits/valarray_array.h
contrib/gcc-8.0/libstdc++-v3/include/bits/vector.tcc
contrib/gcc-8.0/libstdc++-v3/include/debug/map.h
contrib/gcc-8.0/libstdc++-v3/include/debug/multimap.h
contrib/gcc-8.0/libstdc++-v3/include/debug/multiset.h
contrib/gcc-8.0/libstdc++-v3/include/debug/set.h
contrib/gcc-8.0/libstdc++-v3/include/debug/string
contrib/gcc-8.0/libstdc++-v3/include/experimental/algorithm
contrib/gcc-8.0/libstdc++-v3/include/experimental/memory_resource
contrib/gcc-8.0/libstdc++-v3/include/experimental/regex
contrib/gcc-8.0/libstdc++-v3/include/experimental/string
contrib/gcc-8.0/libstdc++-v3/include/experimental/string_view
contrib/gcc-8.0/libstdc++-v3/include/ext/aligned_buffer.h
contrib/gcc-8.0/libstdc++-v3/include/ext/pointer.h
contrib/gcc-8.0/libstdc++-v3/include/ext/random
contrib/gcc-8.0/libstdc++-v3/include/ext/vstring.h
contrib/gcc-8.0/libstdc++-v3/include/std/chrono
contrib/gcc-8.0/libstdc++-v3/include/std/functional
contrib/gcc-8.0/libstdc++-v3/include/std/iomanip
contrib/gcc-8.0/libstdc++-v3/include/std/optional
contrib/gcc-8.0/libstdc++-v3/include/std/string_view
contrib/gcc-8.0/libstdc++-v3/include/std/thread
contrib/gcc-8.0/libstdc++-v3/include/std/type_traits
contrib/gcc-8.0/libstdc++-v3/include/std/utility
contrib/gcc-8.0/libstdc++-v3/include/std/variant
contrib/gcc-8.0/libstdc++-v3/include/tr1/cmath
contrib/gcc-8.0/libstdc++-v3/libsupc++/cxxabi_init_exception.h
contrib/gcc-8.0/libstdc++-v3/libsupc++/exception_ptr.h
contrib/gcc-8.0/libstdc++-v3/libsupc++/new_opa.cc
contrib/gcc-8.0/libstdc++-v3/src/c++11/codecvt.cc
contrib/gcc-8.0/libstdc++-v3/src/c++11/string-inst.cc
contrib/gcc-8.0/libstdc++-v3/src/c++11/system_error.cc

index 5eef1f9..8331296 100644 (file)
@@ -1 +1 @@
-Obtained from SVN: tags/gcc_8_1_0_release revision 259830
+Obtained from SVN: tags/gcc_8_3_0_release revision 269117
index e71ab2c..235e219 100644 (file)
@@ -253,7 +253,7 @@ static tree last_alloca_addr;
 /* Set of variable declarations that are going to be guarded by
    use-after-scope sanitizer.  */
 
-static hash_set<tree> *asan_handled_variables = NULL;
+hash_set<tree> *asan_handled_variables = NULL;
 
 hash_set <tree> *asan_used_labels = NULL;
 
index 412af22..2f431b4 100644 (file)
@@ -110,6 +110,8 @@ extern bool asan_sanitize_stack_p (void);
 
 extern bool asan_sanitize_allocas_p (void);
 
+extern hash_set<tree> *asan_handled_variables;
+
 /* Return TRUE if builtin with given FCODE will be intercepted by
    libasan.  */
 
index bfadf12..f5f660a 100644 (file)
@@ -1685,6 +1685,8 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
             a function global scope, unless declared static.  */
          if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
            TREE_PUBLIC (node) = 1;
+         /* Clear TREE_STATIC because DECL_EXTERNAL is set.  */
+         TREE_STATIC (node) = 0;
        }
 
       if (*no_add_attrs == false)
index d2b4160..57edde6 100644 (file)
 #include "fibonacci_heap.h"
 #include "stringpool.h"
 #include "attribs.h"
+#include "common/common-target.h"
 
 /* The number of rounds.  In most cases there will only be 4 rounds, but
    when partitioning hot and cold basic blocks into separate sections of
@@ -1408,36 +1409,25 @@ get_uncond_jump_length (void)
   return length;
 }
 
-/* The landing pad OLD_LP, in block OLD_BB, has edges from both partitions.
-   Add a new landing pad that will just jump to the old one and split the
-   edges so that no EH edge crosses partitions.  */
+/* Create a forwarder block to OLD_BB starting with NEW_LABEL and in the
+   other partition wrt OLD_BB.  */
 
-static void
-fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb)
+static basic_block
+create_eh_forwarder_block (rtx_code_label *new_label, basic_block old_bb)
 {
-  eh_landing_pad new_lp;
-  basic_block new_bb, last_bb;
-  rtx_insn *jump;
-  unsigned new_partition;
-  edge_iterator ei;
-  edge e;
-
-  /* Generate the new landing-pad structure.  */
-  new_lp = gen_eh_landing_pad (old_lp->region);
-  new_lp->post_landing_pad = old_lp->post_landing_pad;
-  new_lp->landing_pad = gen_label_rtx ();
-  LABEL_PRESERVE_P (new_lp->landing_pad) = 1;
-
-  /* Put appropriate instructions in new bb.  */
-  rtx_code_label *new_label = emit_label (new_lp->landing_pad);
+  /* Split OLD_BB, so that EH pads have always only incoming EH edges,
+     bb_has_eh_pred bbs are treated specially by DF infrastructure.  */
+  old_bb = split_block_after_labels (old_bb)->dest;
 
+  /* Put the new label and a jump in the new basic block.  */
+  rtx_insn *label = emit_label (new_label);
   rtx_code_label *old_label = block_label (old_bb);
-  jump = emit_jump_insn (targetm.gen_jump (old_label));
+  rtx_insn *jump = emit_jump_insn (targetm.gen_jump (old_label));
   JUMP_LABEL (jump) = old_label;
 
-  /* Create new basic block to be dest for lp.  */
-  last_bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
-  new_bb = create_basic_block (new_label, jump, last_bb);
+  /* Create the new basic block and put it in last position.  */
+  basic_block last_bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
+  basic_block new_bb = create_basic_block (label, jump, last_bb);
   new_bb->aux = last_bb->aux;
   new_bb->count = old_bb->count;
   last_bb->aux = new_bb;
@@ -1446,14 +1436,87 @@ fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb)
 
   make_single_succ_edge (new_bb, old_bb, 0);
 
-  /* Make sure new bb is in the other partition.  */
-  new_partition = BB_PARTITION (old_bb);
+  /* Make sure the new basic block is in the other partition.  */
+  unsigned new_partition = BB_PARTITION (old_bb);
   new_partition ^= BB_HOT_PARTITION | BB_COLD_PARTITION;
   BB_SET_PARTITION (new_bb, new_partition);
 
+  return new_bb;
+}
+
+/* The common landing pad in block OLD_BB has edges from both partitions.
+   Add a new landing pad that will just jump to the old one and split the
+   edges so that no EH edge crosses partitions.  */
+
+static void
+sjlj_fix_up_crossing_landing_pad (basic_block old_bb)
+{
+  const unsigned lp_len = cfun->eh->lp_array->length ();
+  edge_iterator ei;
+  edge e;
+
+  /* Generate the new common landing-pad label.  */
+  rtx_code_label *new_label = gen_label_rtx ();
+  LABEL_PRESERVE_P (new_label) = 1;
+
+  /* Create the forwarder block.  */
+  basic_block new_bb = create_eh_forwarder_block (new_label, old_bb);
+
+  /* Create the map from old to new lp index and initialize it.  */
+  unsigned *index_map = (unsigned *) alloca (lp_len * sizeof (unsigned));
+  memset (index_map, 0, lp_len * sizeof (unsigned));
+
   /* Fix up the edges.  */
   for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)) != NULL; )
-    if (e->src != new_bb && BB_PARTITION (e->src) == new_partition)
+    if (e->src != new_bb && BB_PARTITION (e->src) == BB_PARTITION (new_bb))
+      {
+       rtx_insn *insn = BB_END (e->src);
+       rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+
+       gcc_assert (note != NULL);
+       const unsigned old_index = INTVAL (XEXP (note, 0));
+
+       /* Generate the new landing-pad structure.  */
+       if (index_map[old_index] == 0)
+         {
+           eh_landing_pad old_lp = (*cfun->eh->lp_array)[old_index];
+           eh_landing_pad new_lp = gen_eh_landing_pad (old_lp->region);
+           new_lp->post_landing_pad = old_lp->post_landing_pad;
+           new_lp->landing_pad = new_label;
+           index_map[old_index] = new_lp->index;
+         }
+       XEXP (note, 0) = GEN_INT (index_map[old_index]);
+
+       /* Adjust the edge to the new destination.  */
+       redirect_edge_succ (e, new_bb);
+      }
+    else
+      ei_next (&ei);
+}
+
+/* The landing pad OLD_LP, in block OLD_BB, has edges from both partitions.
+   Add a new landing pad that will just jump to the old one and split the
+   edges so that no EH edge crosses partitions.  */
+
+static void
+dw2_fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb)
+{
+  eh_landing_pad new_lp;
+  edge_iterator ei;
+  edge e;
+
+  /* Generate the new landing-pad structure.  */
+  new_lp = gen_eh_landing_pad (old_lp->region);
+  new_lp->post_landing_pad = old_lp->post_landing_pad;
+  new_lp->landing_pad = gen_label_rtx ();
+  LABEL_PRESERVE_P (new_lp->landing_pad) = 1;
+
+  /* Create the forwarder block.  */
+  basic_block new_bb = create_eh_forwarder_block (new_lp->landing_pad, old_bb);
+
+  /* Fix up the edges.  */
+  for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)) != NULL; )
+    if (e->src != new_bb && BB_PARTITION (e->src) == BB_PARTITION (new_bb))
       {
        rtx_insn *insn = BB_END (e->src);
        rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
@@ -1572,6 +1635,7 @@ sanitize_hot_paths (bool walk_up, unsigned int cold_bb_count,
           hot_bbs_to_check.safe_push (reach_bb);
         }
     }
+  hot_bbs_to_check.release ();
 
   return cold_bb_count;
 }
@@ -1651,9 +1715,11 @@ find_rarely_executed_basic_blocks_and_crossing_edges (void)
 
   /* The format of .gcc_except_table does not allow landing pads to
      be in a different partition as the throw.  Fix this by either
-     moving or duplicating the landing pads.  */
+     moving the landing pads or inserting forwarder landing pads.  */
   if (cfun->eh->lp_array)
     {
+      const bool sjlj
+       = (targetm_common.except_unwind_info (&global_options) == UI_SJLJ);
       unsigned i;
       eh_landing_pad lp;
 
@@ -1685,13 +1751,18 @@ find_rarely_executed_basic_blocks_and_crossing_edges (void)
              which ^= BB_HOT_PARTITION | BB_COLD_PARTITION;
              BB_SET_PARTITION (bb, which);
            }
+         else if (sjlj)
+           sjlj_fix_up_crossing_landing_pad (bb);
          else
-           fix_up_crossing_landing_pad (lp, bb);
+           dw2_fix_up_crossing_landing_pad (lp, bb);
+
+         /* There is a single, common landing pad in SJLJ mode.  */
+         if (sjlj)
+           break;
        }
     }
 
   /* Mark every edge that crosses between sections.  */
-
   FOR_EACH_BB_FN (bb, cfun)
     FOR_EACH_EDGE (e, ei, bb->succs)
       {
@@ -2861,8 +2932,8 @@ pass_partition_blocks::gate (function *fun)
 {
   /* The optimization to partition hot/cold basic blocks into separate
      sections of the .o file does not work well with linkonce or with
-     user defined section attributes.  Don't call it if either case
-     arises.  */
+     user defined section attributes or with naked attribute.  Don't call
+     it if either case arises.  */
   return (flag_reorder_blocks_and_partition
          && optimize
          /* See pass_reorder_blocks::gate.  We should not partition if
@@ -2870,6 +2941,7 @@ pass_partition_blocks::gate (function *fun)
          && optimize_function_for_speed_p (fun)
          && !DECL_COMDAT_GROUP (current_function_decl)
          && !lookup_attribute ("section", DECL_ATTRIBUTES (fun->decl))
+         && !lookup_attribute ("naked", DECL_ATTRIBUTES (fun->decl))
          /* Workaround a bug in GDB where read_partial_die doesn't cope
             with DIEs with DW_AT_ranges, see PR81115.  */
          && !(in_lto_p && MAIN_NAME_P (DECL_NAME (fun->decl))));
index bc137a6..30fdb59 100644 (file)
@@ -2734,19 +2734,25 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
 
          if (TYPE_NAME (typ))
            {
-             /* If types have same representation, and same name (ignoring
-                casing), then ignore the second type.  */
+             /* If the types have the same name (ignoring casing), then ignore
+                the second type, but forward declare the first if need be.  */
              if (type_name (typ) == type_name (TREE_TYPE (t))
                  || !strcasecmp (type_name (typ), type_name (TREE_TYPE (t))))
                {
+                 if (RECORD_OR_UNION_TYPE_P (typ) && !TREE_VISITED (stub))
+                   {
+                     INDENT (spc);
+                     dump_forward_type (buffer, typ, t, 0);
+                   }
+
                  TREE_VISITED (t) = 1;
                  return 0;
                }
 
              INDENT (spc);
 
-             if (RECORD_OR_UNION_TYPE_P (typ))
-               dump_forward_type (buffer, stub, t, spc);
+             if (RECORD_OR_UNION_TYPE_P (typ) && !TREE_VISITED (stub))
+               dump_forward_type (buffer, typ, t, spc);
 
              pp_string (buffer, "subtype ");
              dump_ada_node (buffer, t, type, spc, false, true);
index e063088..c9e799e 100644 (file)
@@ -403,7 +403,7 @@ const struct attribute_spec c_common_attribute_table[] =
                              0, 0, true, false, false, false,
                              handle_no_address_safety_analysis_attribute,
                              NULL },
-  { "no_sanitize",           1, 1, true, false, false, false,
+  { "no_sanitize",           1, -1, true, false, false, false,
                              handle_no_sanitize_attribute, NULL },
   { "no_sanitize_address",    0, 0, true, false, false, false,
                              handle_no_sanitize_address_attribute, NULL },
@@ -445,6 +445,8 @@ const struct attribute_spec c_common_attribute_table[] =
                              handle_omp_declare_target_attribute, NULL },
   { "omp declare target link", 0, 0, true, false, false, false,
                              handle_omp_declare_target_attribute, NULL },
+  { "omp declare target implicit", 0, 0, true, false, false, false,
+                             handle_omp_declare_target_attribute, NULL },
   { "alloc_align",           1, 1, false, true, true, false,
                              handle_alloc_align_attribute,
                              attr_alloc_exclusions },
@@ -517,8 +519,13 @@ handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
   if (TYPE_P (*node))
     {
       if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
-       *node = build_variant_type_copy (*node);
-      TYPE_PACKED (*node) = 1;
+       {
+         warning (OPT_Wattributes,
+                  "%qE attribute ignored for type %qT", name, *node);
+         *no_add_attrs = true;
+       }
+      else
+       TYPE_PACKED (*node) = 1;
     }
   else if (TREE_CODE (*node) == FIELD_DECL)
     {
@@ -683,22 +690,26 @@ static tree
 handle_no_sanitize_attribute (tree *node, tree name, tree args, int,
                              bool *no_add_attrs)
 {
+  unsigned int flags = 0;
   *no_add_attrs = true;
-  tree id = TREE_VALUE (args);
   if (TREE_CODE (*node) != FUNCTION_DECL)
     {
       warning (OPT_Wattributes, "%qE attribute ignored", name);
       return NULL_TREE;
     }
 
-  if (TREE_CODE (id) != STRING_CST)
+  for (; args; args = TREE_CHAIN (args))
     {
-      error ("no_sanitize argument not a string");
-      return NULL_TREE;
-    }
+      tree id = TREE_VALUE (args);
+      if (TREE_CODE (id) != STRING_CST)
+       {
+         error ("no_sanitize argument not a string");
+         return NULL_TREE;
+       }
 
-  char *string = ASTRDUP (TREE_STRING_POINTER (id));
-  unsigned int flags = parse_no_sanitize_attribute (string);
+      char *string = ASTRDUP (TREE_STRING_POINTER (id));
+      flags |= parse_no_sanitize_attribute (string);
+    }
 
   add_no_sanitize_value (*node, flags);
 
index 7e6905e..dbbaa81 100644 (file)
@@ -5403,10 +5403,8 @@ check_nonnull_arg (void *ctx, tree param, unsigned HOST_WIDE_INT param_num)
   if (TREE_CODE (TREE_TYPE (param)) != POINTER_TYPE)
     return;
 
-  /* When not optimizing diagnose the simple cases of null arguments.
-     When optimization is enabled defer the checking until expansion
-     when more cases can be detected.  */
-  if (integer_zerop (param))
+  /* Diagnose the simple cases of null arguments.  */
+  if (integer_zerop (fold_for_warn (param)))
     {
       warning_at (pctx->loc, OPT_Wnonnull, "null argument where non-null "
                  "required (argument %lu)", (unsigned long) param_num);
@@ -6168,10 +6166,11 @@ c_common_to_target_charset (HOST_WIDE_INT c)
 
 /* Fold an offsetof-like expression.  EXPR is a nested sequence of component
    references with an INDIRECT_REF of a constant at the bottom; much like the
-   traditional rendering of offsetof as a macro.  Return the folded result.  */
+   traditional rendering of offsetof as a macro.  TYPE is the desired type of
+   the whole expression.  Return the folded result.  */
 
 tree
-fold_offsetof_1 (tree expr, enum tree_code ctx)
+fold_offsetof (tree expr, tree type, enum tree_code ctx)
 {
   tree base, off, t;
   tree_code code = TREE_CODE (expr);
@@ -6196,10 +6195,10 @@ fold_offsetof_1 (tree expr, enum tree_code ctx)
          error ("cannot apply %<offsetof%> to a non constant address");
          return error_mark_node;
        }
-      return TREE_OPERAND (expr, 0);
+      return convert (type, TREE_OPERAND (expr, 0));
 
     case COMPONENT_REF:
-      base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code);
+      base = fold_offsetof (TREE_OPERAND (expr, 0), type, code);
       if (base == error_mark_node)
        return base;
 
@@ -6216,7 +6215,7 @@ fold_offsetof_1 (tree expr, enum tree_code ctx)
       break;
 
     case ARRAY_REF:
-      base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code);
+      base = fold_offsetof (TREE_OPERAND (expr, 0), type, code);
       if (base == error_mark_node)
        return base;
 
@@ -6273,23 +6272,16 @@ fold_offsetof_1 (tree expr, enum tree_code ctx)
       /* Handle static members of volatile structs.  */
       t = TREE_OPERAND (expr, 1);
       gcc_checking_assert (VAR_P (get_base_address (t)));
-      return fold_offsetof_1 (t);
+      return fold_offsetof (t, type);
 
     default:
       gcc_unreachable ();
     }
 
+  if (!POINTER_TYPE_P (type))
+    return size_binop (PLUS_EXPR, base, convert (type, off));
   return fold_build_pointer_plus (base, off);
 }
-
-/* Likewise, but convert it to the return type of offsetof.  */
-
-tree
-fold_offsetof (tree expr)
-{
-  return convert (size_type_node, fold_offsetof_1 (expr));
-}
-
 \f
 /* *PTYPE is an incomplete array.  Complete it with a domain based on
    INITIAL_VALUE.  If INITIAL_VALUE is not present, use 1 if DO_DEFAULT
index 6cf7614..f2c6662 100644 (file)
@@ -1033,8 +1033,8 @@ extern bool c_dump_tree (void *, tree);
 
 extern void verify_sequence_points (tree);
 
-extern tree fold_offsetof_1 (tree, tree_code ctx = ERROR_MARK);
-extern tree fold_offsetof (tree);
+extern tree fold_offsetof (tree, tree = size_type_node,
+                          tree_code ctx = ERROR_MARK);
 
 extern int complete_array_type (tree *, tree, bool);
 
index 3fc4fa9..18821ec 100644 (file)
@@ -972,9 +972,13 @@ c_cpp_builtins (cpp_reader *pfile)
          cpp_define (pfile, "__cpp_aggregate_bases=201603");
          cpp_define (pfile, "__cpp_deduction_guides=201611");
          cpp_define (pfile, "__cpp_noexcept_function_type=201510");
+         /* Old macro, superseded by
+            __cpp_nontype_template_parameter_auto.  */
          cpp_define (pfile, "__cpp_template_auto=201606");
          cpp_define (pfile, "__cpp_structured_bindings=201606");
          cpp_define (pfile, "__cpp_variadic_using=201611");
+         cpp_define (pfile, "__cpp_guaranteed_copy_elision=201606");
+         cpp_define (pfile, "__cpp_nontype_template_parameter_auto=201606");
        }
       if (flag_concepts)
        cpp_define (pfile, "__cpp_concepts=201507");
index a076e3c..8922759 100644 (file)
@@ -373,8 +373,11 @@ c_finish_omp_atomic (location_t loc, enum tree_code code,
            }
        }
       if (blhs)
-       x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
-                       bitsize_int (bitsize), bitsize_int (bitpos));
+       {
+         x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
+                         bitsize_int (bitsize), bitsize_int (bitpos));
+         type = TREE_TYPE (blhs);
+       }
       x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
                             loc, x, NULL_TREE);
       if (rhs1 && rhs1 != orig_lhs)
@@ -1611,5 +1614,13 @@ c_omp_predetermined_sharing (tree decl)
   if (TREE_READONLY (decl))
     return OMP_CLAUSE_DEFAULT_SHARED;
 
+  /* Predetermine artificial variables holding integral values, those
+     are usually result of gimplify_one_sizepos or SAVE_EXPR
+     gimplification.  */
+  if (VAR_P (decl)
+      && DECL_ARTIFICIAL (decl)
+      && INTEGRAL_TYPE_P (TREE_TYPE (decl)))
+    return OMP_CLAUSE_DEFAULT_SHARED;
+
   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
 }
index 3db01d4..9011902 100644 (file)
@@ -417,8 +417,6 @@ c_common_handle_option (size_t scode, const char *arg, int value,
          value = 2;
        }
       warn_abi_version = value;
-      if (flag_abi_compat_version == -1)
-       flag_abi_compat_version = value;
       break;
 
     case OPT_fcanonical_system_headers:
@@ -915,31 +913,48 @@ c_common_post_options (const char **pfilename)
   if (flag_declone_ctor_dtor == -1)
     flag_declone_ctor_dtor = optimize_size;
 
-  if (warn_abi_version == -1)
-    {
-      if (flag_abi_compat_version != -1)
-       warn_abi_version = flag_abi_compat_version;
-      else
-       warn_abi_version = 0;
-    }
-
   if (flag_abi_compat_version == 1)
     {
       warning (0, "%<-fabi-compat-version=1%> is not supported, using =2");
       flag_abi_compat_version = 2;
     }
-  else if (flag_abi_compat_version == -1)
+
+  /* Change flag_abi_version to be the actual current ABI level, for the
+     benefit of c_cpp_builtins, and to make comparison simpler.  */
+  const int latest_abi_version = 13;
+  /* Generate compatibility aliases for ABI v11 (7.1) by default.  */
+  const int abi_compat_default = 11;
+
+#define clamp(X) if (X == 0 || X > latest_abi_version) X = latest_abi_version
+  clamp (flag_abi_version);
+  clamp (warn_abi_version);
+  clamp (flag_abi_compat_version);
+#undef clamp
+
+  /* Default -Wabi= or -fabi-compat-version= from each other.  */
+  if (warn_abi_version == -1 && flag_abi_compat_version != -1)
+    warn_abi_version = flag_abi_compat_version;
+  else if (flag_abi_compat_version == -1 && warn_abi_version != -1)
+    flag_abi_compat_version = warn_abi_version;
+  else if (warn_abi_version == -1 && flag_abi_compat_version == -1)
     {
-      /* Generate compatibility aliases for ABI v11 (7.1) by default. */
-      flag_abi_compat_version
-       = (flag_abi_version == 0 ? 11 : 0);
+      warn_abi_version = latest_abi_version;
+      if (flag_abi_version == latest_abi_version)
+       {
+         if (warning (OPT_Wabi, "-Wabi won't warn about anything"))
+           {
+             inform (input_location, "-Wabi warns about differences "
+                     "from the most up-to-date ABI, which is also used "
+                     "by default");
+             inform (input_location, "use e.g. -Wabi=11 to warn about "
+                     "changes from GCC 7");
+           }
+         flag_abi_compat_version = abi_compat_default;
+       }
+      else
+       flag_abi_compat_version = latest_abi_version;
     }
 
-  /* Change flag_abi_version to be the actual current ABI level for the
-     benefit of c_cpp_builtins.  */
-  if (flag_abi_version == 0)
-    flag_abi_version = 12;
-
   /* By default, enable the new inheriting constructor semantics along with ABI
      11.  New and old should coexist fine, but it is a change in what
      artificial symbols are generated.  */
index ae6e250..b803680 100644 (file)
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "stringpool.h"
 #include "attribs.h"
 #include "asan.h"
+#include "langhooks.h"
 
 /* Instrument division by zero and INT_MIN / -1.  If not instrumenting,
    return NULL_TREE.  */
@@ -44,8 +45,9 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1)
   /* At this point both operands should have the same type,
      because they are already converted to RESULT_TYPE.
      Use TYPE_MAIN_VARIANT since typedefs can confuse us.  */
-  gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
-             == TYPE_MAIN_VARIANT (TREE_TYPE (op1)));
+  tree top0 = TYPE_MAIN_VARIANT (type);
+  tree top1 = TYPE_MAIN_VARIANT (TREE_TYPE (op1));
+  gcc_checking_assert (lang_hooks.types_compatible_p (top0, top1));
 
   op0 = unshare_expr (op0);
   op1 = unshare_expr (op1);
index d0d9c78..0991312 100644 (file)
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gcc-rich-location.h"
 #include "gimplify.h"
 #include "c-family/c-indentation.h"
+#include "calls.h"
 
 /* Print a warning if a constant expression had overflow in folding.
    Invoke this function on every expression that the language
@@ -798,6 +799,13 @@ sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee,
          tem = tree_strip_nop_conversions (src);
          if (TREE_CODE (tem) == ADDR_EXPR)
            tem = TREE_OPERAND (tem, 0);
+
+         /* Avoid diagnosing sizeof SRC when SRC is declared with
+            attribute nonstring.  */
+         tree dummy;
+         if (get_attr_nonstring_decl (tem, &dummy))
+           return;
+
          if (operand_equal_p (tem, sizeof_arg[idx], OEP_ADDRESS_OF))
            warning_at (sizeof_arg_loc[idx], OPT_Wsizeof_pointer_memaccess,
                        "argument to %<sizeof%> in %qD call is the same "
@@ -1897,7 +1905,8 @@ warn_for_memset (location_t loc, tree arg0, tree arg2,
        {
          tree elt_type = TREE_TYPE (type);
          tree domain = TYPE_DOMAIN (type);
-         if (!integer_onep (TYPE_SIZE_UNIT (elt_type))
+         if (COMPLETE_TYPE_P (elt_type)
+             && !integer_onep (TYPE_SIZE_UNIT (elt_type))
              && domain != NULL_TREE
              && TYPE_MAX_VALUE (domain)
              && TYPE_MIN_VALUE (domain)
@@ -2246,18 +2255,16 @@ diagnose_mismatched_attributes (tree olddecl, tree newdecl)
                       newdecl);
 
   /* Diagnose inline __attribute__ ((noinline)) which is silly.  */
-  const char *noinline = "noinline";
-
   if (DECL_DECLARED_INLINE_P (newdecl)
       && DECL_UNINLINABLE (olddecl)
-      && lookup_attribute (noinline, DECL_ATTRIBUTES (olddecl)))
+      && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
     warned |= warning (OPT_Wattributes, "inline declaration of %qD follows "
-                      "declaration with attribute %qs", newdecl, noinline);
+                      "declaration with attribute %qs", newdecl, "noinline");
   else if (DECL_DECLARED_INLINE_P (olddecl)
           && DECL_UNINLINABLE (newdecl)
           && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
     warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute "
-                      "%qs follows inline declaration", newdecl, noinline);
+                      "%qs follows inline declaration", newdecl, "noinline");
 
   return warned;
 }
index a4c8c8f..f591b39 100644 (file)
@@ -1339,8 +1339,8 @@ Driver
 static-libmpxwrappers
 Driver
 
-fcilkplus Undocumented
-C ObjC C++ ObjC++ LTO Report Var(flag_cilkplus) Init(0)
+fcilkplus
+C ObjC C++ ObjC++ LTO Report Var(flag_cilkplus) Init(0) Undocumented
 Deprecated in GCC 8.  This switch has no effect.
 
 fconcepts
index b57bb8e..6165e14 100644 (file)
@@ -115,6 +115,7 @@ convert (tree type, tree expr)
          && COMPLETE_TYPE_P (type))
        {
          expr = save_expr (expr);
+         expr = c_fully_fold (expr, false, NULL);
          tree check = ubsan_instrument_float_cast (loc, type, expr);
          expr = fold_build1 (FIX_TRUNC_EXPR, type, expr);
          if (check == NULL_TREE)
index f0198ec..4da9fe9 100644 (file)
@@ -1239,8 +1239,9 @@ pop_scope (void)
              && DECL_ABSTRACT_ORIGIN (p) != NULL_TREE
              && DECL_ABSTRACT_ORIGIN (p) != p)
            TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (p)) = 1;
-         if (!DECL_EXTERNAL (p)
+         if (!TREE_PUBLIC (p)
              && !DECL_INITIAL (p)
+             && !b->nested
              && scope != file_scope
              && scope != external_scope)
            {
@@ -1256,7 +1257,7 @@ pop_scope (void)
                 in the same translation unit."  */
              if (!flag_gnu89_inline
                  && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (p))
-                 && scope != external_scope)
+                 && scope == external_scope)
                pedwarn (input_location, 0,
                         "inline function %q+D declared but never defined", p);
              DECL_EXTERNAL (p) = 1;
@@ -4632,8 +4633,8 @@ c_decl_attributes (tree *node, tree attributes, int flags)
     {
       if (VAR_P (*node)
          && !lang_hooks.types.omp_mappable_type (TREE_TYPE (*node)))
-       error ("%q+D in declare target directive does not have mappable type",
-              *node);
+       attributes = tree_cons (get_identifier ("omp declare target implicit"),
+                               NULL_TREE, attributes);
       else
        attributes = tree_cons (get_identifier ("omp declare target"),
                                NULL_TREE, attributes);
@@ -5212,7 +5213,27 @@ finish_decl (tree decl, location_t init_loc, tree init,
        diagnose_uninitialized_cst_member (decl, type);
     }
 
-       invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
+  if (flag_openmp
+      && VAR_P (decl)
+      && lookup_attribute ("omp declare target implicit",
+                          DECL_ATTRIBUTES (decl)))
+    {
+      DECL_ATTRIBUTES (decl)
+       = remove_attribute ("omp declare target implicit",
+                           DECL_ATTRIBUTES (decl));
+      if (!lang_hooks.types.omp_mappable_type (TREE_TYPE (decl)))
+       error ("%q+D in declare target directive does not have mappable type",
+              decl);
+      else if (!lookup_attribute ("omp declare target",
+                                 DECL_ATTRIBUTES (decl))
+              && !lookup_attribute ("omp declare target link",
+                                    DECL_ATTRIBUTES (decl)))
+       DECL_ATTRIBUTES (decl)
+         = tree_cons (get_identifier ("omp declare target"),
+                      NULL_TREE, DECL_ATTRIBUTES (decl));
+    }
+
+  invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
 }
 
 /* Given a parsed parameter declaration, decode it into a PARM_DECL.
index 480e34c..d276e63 100644 (file)
@@ -473,7 +473,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
          && (op1 = get_base_address (op0)) != NULL_TREE
          && INDIRECT_REF_P (op1)
          && TREE_CONSTANT (TREE_OPERAND (op1, 0)))
-       ret = fold_convert_loc (loc, TREE_TYPE (expr), fold_offsetof_1 (op0));
+       ret = fold_offsetof (op0, TREE_TYPE (expr));
       else if (op0 != orig_op0 || in_init)
        ret = in_init
          ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0)
index 4772086..ece6b92 100644 (file)
@@ -2143,10 +2143,12 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
              tree d = start_decl (declarator, specs, false,
                                   chainon (postfix_attrs,
                                            all_prefix_attrs));
-             if (d && TREE_CODE (d) == FUNCTION_DECL)
-               if (declarator->kind == cdk_function)
-                 if (DECL_ARGUMENTS (d) == NULL_TREE)
-                   DECL_ARGUMENTS (d) = declarator->u.arg_info->parms;
+             if (d
+                 && TREE_CODE (d) == FUNCTION_DECL
+                 && declarator->kind == cdk_function
+                 && DECL_ARGUMENTS (d) == NULL_TREE
+                 && DECL_INITIAL (d) == NULL_TREE)
+               DECL_ARGUMENTS (d) = declarator->u.arg_info->parms;
              if (omp_declare_simd_clauses.exists ())
                {
                  tree parms = NULL_TREE;
@@ -6261,61 +6263,104 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
 }
 
 /* Parse an asm statement, a GNU extension.  This is a full-blown asm
-   statement with inputs, outputs, clobbers, and volatile tag
-   allowed.
+   statement with inputs, outputs, clobbers, and volatile, inline, and goto
+   tags allowed.
+
+   asm-qualifier:
+     volatile
+     inline
+     goto
+
+   asm-qualifier-list:
+     asm-qualifier-list asm-qualifier
+     asm-qualifier
 
    asm-statement:
-     asm type-qualifier[opt] ( asm-argument ) ;
-     asm type-qualifier[opt] goto ( asm-goto-argument ) ;
+     asm asm-qualifier-list[opt] ( asm-argument ) ;
 
    asm-argument:
      asm-string-literal
      asm-string-literal : asm-operands[opt]
      asm-string-literal : asm-operands[opt] : asm-operands[opt]
-     asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers[opt]
-
-   asm-goto-argument:
+     asm-string-literal : asm-operands[opt] : asm-operands[opt] \
+       : asm-clobbers[opt]
      asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
        : asm-goto-operands
 
-   Qualifiers other than volatile are accepted in the syntax but
-   warned for.  */
+   The form with asm-goto-operands is valid if and only if the
+   asm-qualifier-list contains goto, and is the only allowed form in that case.
+   Duplicate asm-qualifiers are not allowed.  */
 
 static tree
 c_parser_asm_statement (c_parser *parser)
 {
-  tree quals, str, outputs, inputs, clobbers, labels, ret;
-  bool simple, is_goto;
+  tree str, outputs, inputs, clobbers, labels, ret;
+  bool simple;
   location_t asm_loc = c_parser_peek_token (parser)->location;
   int section, nsections;
 
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
   c_parser_consume_token (parser);
-  if (c_parser_next_token_is_keyword (parser, RID_VOLATILE))
-    {
-      quals = c_parser_peek_token (parser)->value;
-      c_parser_consume_token (parser);
-    }
-  else if (c_parser_next_token_is_keyword (parser, RID_CONST)
-          || c_parser_next_token_is_keyword (parser, RID_RESTRICT))
-    {
-      warning_at (c_parser_peek_token (parser)->location,
-                 0,
-                 "%E qualifier ignored on asm",
-                 c_parser_peek_token (parser)->value);
-      quals = NULL_TREE;
-      c_parser_consume_token (parser);
-    }
-  else
-    quals = NULL_TREE;
 
-  is_goto = false;
-  if (c_parser_next_token_is_keyword (parser, RID_GOTO))
+  /* Handle the asm-qualifier-list.  */
+  location_t volatile_loc = UNKNOWN_LOCATION;
+  location_t inline_loc = UNKNOWN_LOCATION;
+  location_t goto_loc = UNKNOWN_LOCATION;
+  for (;;)
     {
-      c_parser_consume_token (parser);
-      is_goto = true;
+      c_token *token = c_parser_peek_token (parser);
+      location_t loc = token->location;
+      switch (token->keyword)
+       {
+       case RID_VOLATILE:
+         if (volatile_loc)
+           {
+             error_at (loc, "duplicate asm qualifier %qE", token->value);
+             inform (volatile_loc, "first seen here");
+           }
+         else
+           volatile_loc = loc;
+         c_parser_consume_token (parser);
+         continue;
+
+       case RID_INLINE:
+         if (inline_loc)
+           {
+             error_at (loc, "duplicate asm qualifier %qE", token->value);
+             inform (inline_loc, "first seen here");
+           }
+         else
+           inline_loc = loc;
+         c_parser_consume_token (parser);
+         continue;
+
+       case RID_GOTO:
+         if (goto_loc)
+           {
+             error_at (loc, "duplicate asm qualifier %qE", token->value);
+             inform (goto_loc, "first seen here");
+           }
+         else
+           goto_loc = loc;
+         c_parser_consume_token (parser);
+         continue;
+
+       case RID_CONST:
+       case RID_RESTRICT:
+         warning_at (loc, 0, "%qE is not an asm qualifier", token->value);
+         c_parser_consume_token (parser);
+         continue;
+
+       default:
+         break;
+       }
+      break;
     }
 
+  bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
+  bool is_inline = (inline_loc != UNKNOWN_LOCATION);
+  bool is_goto = (goto_loc != UNKNOWN_LOCATION);
+
   /* ??? Follow the C++ parser rather than using the
      lex_untranslated_string kludge.  */
   parser->lex_untranslated_string = true;
@@ -6390,8 +6435,9 @@ c_parser_asm_statement (c_parser *parser)
   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
     c_parser_skip_to_end_of_block_or_statement (parser);
 
-  ret = build_asm_stmt (quals, build_asm_expr (asm_loc, str, outputs, inputs,
-                                              clobbers, labels, simple));
+  ret = build_asm_stmt (is_volatile,
+                       build_asm_expr (asm_loc, str, outputs, inputs,
+                                       clobbers, labels, simple, is_inline));
 
  error:
   parser->lex_untranslated_string = false;
index ae1a1e6..aa66aa2 100644 (file)
@@ -677,8 +677,9 @@ extern tree build_compound_literal (location_t, tree, tree, bool,
 extern void check_compound_literal_type (location_t, struct c_type_name *);
 extern tree c_start_case (location_t, location_t, tree, bool);
 extern void c_finish_case (tree, tree);
-extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool);
-extern tree build_asm_stmt (tree, tree);
+extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool,
+                           bool);
+extern tree build_asm_stmt (bool, tree);
 extern int c_types_compatible_p (tree, tree);
 extern tree c_begin_compound_stmt (bool);
 extern tree c_end_compound_stmt (location_t, tree, bool);
index ffd0644..7b90b5c 100644 (file)
@@ -3840,7 +3840,12 @@ pointer_diff (location_t loc, tree op0, tree op1, tree *instrument_expr)
     op0 = build_binary_op (loc, MINUS_EXPR, convert (inttype, op0),
                           convert (inttype, op1), false);
   else
-    op0 = build2_loc (loc, POINTER_DIFF_EXPR, inttype, op0, op1);
+    {
+      /* Cast away qualifiers.  */
+      op0 = convert (c_common_type (TREE_TYPE (op0), TREE_TYPE (op0)), op0);
+      op1 = convert (c_common_type (TREE_TYPE (op1), TREE_TYPE (op1)), op1);
+      op0 = build2_loc (loc, POINTER_DIFF_EXPR, inttype, op0, op1);
+    }
 
   /* This generates an error if op1 is pointer to incomplete type.  */
   if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1))))
@@ -4676,7 +4681,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
       if (val && INDIRECT_REF_P (val)
           && TREE_CONSTANT (TREE_OPERAND (val, 0)))
        {
-         ret = fold_convert_loc (location, argtype, fold_offsetof_1 (arg));
+         ret = fold_offsetof (arg, argtype);
          goto return_build_unary_op;
        }
 
@@ -9311,6 +9316,65 @@ output_init_element (location_t loc, tree value, tree origtype,
     output_pending_init_elements (0, braced_init_obstack);
 }
 
+/* For two FIELD_DECLs in the same chain, return -1 if field1
+   comes before field2, 1 if field1 comes after field2 and
+   0 if field1 == field2.  */
+
+static int
+init_field_decl_cmp (tree field1, tree field2)
+{
+  if (field1 == field2)
+    return 0;
+
+  tree bitpos1 = bit_position (field1);
+  tree bitpos2 = bit_position (field2);
+  if (tree_int_cst_equal (bitpos1, bitpos2))
+    {
+      /* If one of the fields has non-zero bitsize, then that
+        field must be the last one in a sequence of zero
+        sized fields, fields after it will have bigger
+        bit_position.  */
+      if (TREE_TYPE (field1) != error_mark_node
+         && COMPLETE_TYPE_P (TREE_TYPE (field1))
+         && integer_nonzerop (TREE_TYPE (field1)))
+       return 1;
+      if (TREE_TYPE (field2) != error_mark_node
+         && COMPLETE_TYPE_P (TREE_TYPE (field2))
+         && integer_nonzerop (TREE_TYPE (field2)))
+       return -1;
+      /* Otherwise, fallback to DECL_CHAIN walk to find out
+        which field comes earlier.  Walk chains of both
+        fields, so that if field1 and field2 are close to each
+        other in either order, it is found soon even for large
+        sequences of zero sized fields.  */
+      tree f1 = field1, f2 = field2;
+      while (1)
+       {
+         f1 = DECL_CHAIN (f1);
+         f2 = DECL_CHAIN (f2);
+         if (f1 == NULL_TREE)
+           {
+             gcc_assert (f2);
+             return 1;
+           }
+         if (f2 == NULL_TREE)
+           return -1;
+         if (f1 == field2)
+           return -1;
+         if (f2 == field1)
+           return 1;
+         if (!tree_int_cst_equal (bit_position (f1), bitpos1))
+           return 1;
+         if (!tree_int_cst_equal (bit_position (f2), bitpos1))
+           return -1;
+       }
+    }
+  else if (tree_int_cst_lt (bitpos1, bitpos2))
+    return -1;
+  else
+    return 1;
+}
+
 /* Output any pending elements which have become next.
    As we output elements, constructor_unfilled_{fields,index}
    advances, which may cause other elements to become next;
@@ -9382,25 +9446,18 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack)
        }
       else if (RECORD_OR_UNION_TYPE_P (constructor_type))
        {
-         tree ctor_unfilled_bitpos, elt_bitpos;
-
          /* If the current record is complete we are done.  */
          if (constructor_unfilled_fields == NULL_TREE)
            break;
 
-         ctor_unfilled_bitpos = bit_position (constructor_unfilled_fields);
-         elt_bitpos = bit_position (elt->purpose);
-         /* We can't compare fields here because there might be empty
-            fields in between.  */
-         if (tree_int_cst_equal (elt_bitpos, ctor_unfilled_bitpos))
-           {
-             constructor_unfilled_fields = elt->purpose;
-             output_init_element (input_location, elt->value, elt->origtype,
-                                  true, TREE_TYPE (elt->purpose),
-                                  elt->purpose, false, false,
-                                  braced_init_obstack);
-           }
-         else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos))
+         int cmp = init_field_decl_cmp (constructor_unfilled_fields,
+                                        elt->purpose);
+         if (cmp == 0)
+           output_init_element (input_location, elt->value, elt->origtype,
+                                true, TREE_TYPE (elt->purpose),
+                                elt->purpose, false, false,
+                                braced_init_obstack);
+         else if (cmp < 0)
            {
              /* Advance to the next smaller node.  */
              if (elt->left)
@@ -9426,8 +9483,8 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack)
                    elt = elt->parent;
                  elt = elt->parent;
                  if (elt
-                     && (tree_int_cst_lt (ctor_unfilled_bitpos,
-                                          bit_position (elt->purpose))))
+                     && init_field_decl_cmp (constructor_unfilled_fields,
+                                             elt->purpose) < 0)
                    {
                      next = elt->purpose;
                      break;
@@ -9922,9 +9979,9 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
    (guaranteed to be 'volatile' or null) and ARGS (represented using
    an ASM_EXPR node).  */
 tree
-build_asm_stmt (tree cv_qualifier, tree args)
+build_asm_stmt (bool is_volatile, tree args)
 {
-  if (!ASM_VOLATILE_P (args) && cv_qualifier)
+  if (is_volatile)
     ASM_VOLATILE_P (args) = 1;
   return add_stmt (args);
 }
@@ -9933,10 +9990,12 @@ build_asm_stmt (tree cv_qualifier, tree args)
    some INPUTS, and some CLOBBERS.  The latter three may be NULL.
    SIMPLE indicates whether there was anything at all after the
    string in the asm expression -- asm("blah") and asm("blah" : )
-   are subtly different.  We use a ASM_EXPR node to represent this.  */
+   are subtly different.  We use a ASM_EXPR node to represent this.
+   LOC is the location of the asm, and IS_INLINE says whether this
+   is asm inline.  */
 tree
 build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
-               tree clobbers, tree labels, bool simple)
+               tree clobbers, tree labels, bool simple, bool is_inline)
 {
   tree tail;
   tree args;
@@ -10054,6 +10113,7 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
      as volatile.  */
   ASM_INPUT_P (args) = simple;
   ASM_VOLATILE_P (args) = (noutputs == 0);
+  ASM_INLINE_P (args) = is_inline;
 
   return args;
 }
index 9eb0467..e619f68 100644 (file)
@@ -50,11 +50,13 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-chkp.h"
 #include "tree-vrp.h"
 #include "tree-ssanames.h"
+#include "tree-ssa-strlen.h"
 #include "rtl-chkp.h"
 #include "intl.h"
 #include "stringpool.h"
 #include "attribs.h"
 #include "builtins.h"
+#include "gimple-fold.h"
 
 /* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits.  */
 #define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
@@ -1230,65 +1232,81 @@ static GTY(()) tree alloc_object_size_limit;
 static tree
 alloc_max_size (void)
 {
-  if (!alloc_object_size_limit)
-    {
-      alloc_object_size_limit = max_object_size ();
+  if (alloc_object_size_limit)
+    return alloc_object_size_limit;
 
-      if (warn_alloc_size_limit)
-       {
-         char *end = NULL;
-         errno = 0;
-         unsigned HOST_WIDE_INT unit = 1;
-         unsigned HOST_WIDE_INT limit
-           = strtoull (warn_alloc_size_limit, &end, 10);
+  alloc_object_size_limit = max_object_size ();
 
-         if (!errno)
-           {
-             if (end && *end)
-               {
-                 /* Numeric option arguments are at most INT_MAX.  Make it
-                    possible to specify a larger value by accepting common
-                    suffixes.  */
-                 if (!strcmp (end, "kB"))
-                   unit = 1000;
-                 else if (!strcasecmp (end, "KiB") || strcmp (end, "KB"))
-                   unit = 1024;
-                 else if (!strcmp (end, "MB"))
-                   unit = HOST_WIDE_INT_UC (1000) * 1000;
-                 else if (!strcasecmp (end, "MiB"))
-                   unit = HOST_WIDE_INT_UC (1024) * 1024;
-                 else if (!strcasecmp (end, "GB"))
-                   unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000;
-                 else if (!strcasecmp (end, "GiB"))
-                   unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024;
-                 else if (!strcasecmp (end, "TB"))
-                   unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000;
-                 else if (!strcasecmp (end, "TiB"))
-                   unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024;
-                 else if (!strcasecmp (end, "PB"))
-                   unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000;
-                 else if (!strcasecmp (end, "PiB"))
-                   unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024;
-                 else if (!strcasecmp (end, "EB"))
-                   unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000
-                          * 1000;
-                 else if (!strcasecmp (end, "EiB"))
-                   unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024
-                          * 1024;
-                 else
-                   unit = 0;
-               }
+  if (!warn_alloc_size_limit)
+    return alloc_object_size_limit;
 
-             if (unit)
-               {
-                 widest_int w = wi::mul (limit, unit);
-                 if (w < wi::to_widest (alloc_object_size_limit))
-                   alloc_object_size_limit
-                     = wide_int_to_tree (ptrdiff_type_node, w);
-               }
-           }
+  const char *optname = "-Walloc-size-larger-than=";
+
+  char *end = NULL;
+  errno = 0;
+  unsigned HOST_WIDE_INT unit = 1;
+  unsigned HOST_WIDE_INT limit
+    = strtoull (warn_alloc_size_limit, &end, 10);
+
+  /* If the value is too large to be represented use the maximum
+     representable value that strtoull sets limit to (setting
+     errno to ERANGE).  */
+
+  if (end && *end)
+    {
+      /* Numeric option arguments are at most INT_MAX.  Make it
+        possible to specify a larger value by accepting common
+        suffixes.  */
+      if (!strcmp (end, "kB"))
+       unit = 1000;
+      else if (!strcasecmp (end, "KiB") || !strcmp (end, "KB"))
+       unit = 1024;
+      else if (!strcmp (end, "MB"))
+       unit = HOST_WIDE_INT_UC (1000) * 1000;
+      else if (!strcasecmp (end, "MiB"))
+       unit = HOST_WIDE_INT_UC (1024) * 1024;
+      else if (!strcasecmp (end, "GB"))
+       unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000;
+      else if (!strcasecmp (end, "GiB"))
+       unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024;
+      else if (!strcasecmp (end, "TB"))
+       unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000;
+      else if (!strcasecmp (end, "TiB"))
+       unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024;
+      else if (!strcasecmp (end, "PB"))
+       unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000;
+      else if (!strcasecmp (end, "PiB"))
+       unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024;
+      else if (!strcasecmp (end, "EB"))
+       unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000
+         * 1000;
+      else if (!strcasecmp (end, "EiB"))
+       unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024
+         * 1024;
+      else
+       {
+         /* This could mean an unknown suffix or a bad prefix, like
+            "+-1".  */
+         warning_at (UNKNOWN_LOCATION, 0,
+                     "invalid argument %qs to %qs",
+                     warn_alloc_size_limit, optname);
+
+         /* Ignore the limit extracted by strtoull.  */
+         unit = 0;
        }
     }
+
+  if (unit)
+    {
+      widest_int w = wi::mul (limit, unit);
+      if (w < wi::to_widest (alloc_object_size_limit))
+       alloc_object_size_limit
+         = wide_int_to_tree (ptrdiff_type_node, w);
+      else
+       alloc_object_size_limit = build_all_ones_cst (size_type_node);
+    }
+
+
   return alloc_object_size_limit;
 }
 
@@ -1586,8 +1604,12 @@ get_attr_nonstring_decl (tree expr, tree *ref)
   if (ref)
     *ref = decl;
 
-  if (TREE_CODE (decl) == COMPONENT_REF)
+  if (TREE_CODE (decl) == ARRAY_REF)
+    decl = TREE_OPERAND (decl, 0);
+  else if (TREE_CODE (decl) == COMPONENT_REF)
     decl = TREE_OPERAND (decl, 1);
+  else if (TREE_CODE (decl) == MEM_REF)
+    return get_attr_nonstring_decl (TREE_OPERAND (decl, 0), ref);
 
   if (DECL_P (decl)
       && lookup_attribute ("nonstring", DECL_ATTRIBUTES (decl)))
@@ -1605,6 +1627,9 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
   if (!fndecl || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
     return;
 
+  if (!warn_stringop_overflow)
+    return;
+
   bool with_bounds = CALL_WITH_BOUNDS_P (exp);
 
   unsigned nargs = call_expr_nargs (exp);
@@ -1612,15 +1637,42 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
   /* The bound argument to a bounded string function like strncpy.  */
   tree bound = NULL_TREE;
 
+  /* The range of lengths of a string argument to one of the comparison
+     functions.  If the length is less than the bound it is used instead.  */
+  tree lenrng[2] = { NULL_TREE, NULL_TREE };
+
   /* It's safe to call "bounded" string functions with a non-string
      argument since the functions provide an explicit bound for this
-     purpose.  */
-  switch (DECL_FUNCTION_CODE (fndecl))
+     purpose.  The exception is strncat where the bound may refer to
+     either the destination or the source.  */
+  int fncode = DECL_FUNCTION_CODE (fndecl);
+  switch (fncode)
     {
-    case BUILT_IN_STPNCPY:
-    case BUILT_IN_STPNCPY_CHK:
+    case BUILT_IN_STRCMP:
     case BUILT_IN_STRNCMP:
     case BUILT_IN_STRNCASECMP:
+      {
+       /* For these, if one argument refers to one or more of a set
+          of string constants or arrays of known size, determine
+          the range of their known or possible lengths and use it
+          conservatively as the bound for the unbounded function,
+          and to adjust the range of the bound of the bounded ones.  */
+       unsigned stride = with_bounds ? 2 : 1;
+       for (unsigned argno = 0;
+            argno < MIN (nargs, 2 * stride)
+            && !(lenrng[1] && TREE_CODE (lenrng[1]) == INTEGER_CST);
+            argno += stride)
+         {
+           tree arg = CALL_EXPR_ARG (exp, argno);
+           if (!get_attr_nonstring_decl (arg))
+             get_range_strlen (arg, lenrng);
+         }
+      }
+      /* Fall through.  */
+
+    case BUILT_IN_STRNCAT:
+    case BUILT_IN_STPNCPY:
+    case BUILT_IN_STPNCPY_CHK:
     case BUILT_IN_STRNCPY:
     case BUILT_IN_STRNCPY_CHK:
       {
@@ -1647,6 +1699,31 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
   if (bound)
     get_size_range (bound, bndrng);
 
+  if (lenrng[1] && TREE_CODE (lenrng[1]) == INTEGER_CST)
+    {
+      /* Add one for the nul.  */
+      lenrng[1] = const_binop (PLUS_EXPR, TREE_TYPE (lenrng[1]),
+                              lenrng[1], size_one_node);
+
+      if (!bndrng[0])
+       {
+         /* Conservatively use the upper bound of the lengths for
+            both the lower and the upper bound of the operation.  */
+         bndrng[0] = lenrng[1];
+         bndrng[1] = lenrng[1];
+         bound = void_type_node;
+       }
+      else
+       {
+         /* Replace the bound on the oparation with the upper bound
+            of the length of the string if the latter is smaller.  */
+         if (tree_int_cst_lt (lenrng[1], bndrng[0]))
+           bndrng[0] = lenrng[1];
+         else if (tree_int_cst_lt (lenrng[1], bndrng[1]))
+           bndrng[1] = lenrng[1];
+       }
+    }
+
   /* Iterate over the built-in function's formal arguments and check
      each const char* against the actual argument.  If the actual
      argument is declared attribute non-string issue a warning unless
@@ -1687,30 +1764,98 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
       if (!decl)
        continue;
 
-      tree type = TREE_TYPE (decl);
-
+      /* The maximum number of array elements accessed.  */
       offset_int wibnd = 0;
-      if (bndrng[0])
+
+      if (argno && fncode == BUILT_IN_STRNCAT)
+       {
+         /* See if the bound in strncat is derived from the length
+            of the strlen of the destination (as it's expected to be).
+            If so, reset BOUND and FNCODE to trigger a warning.  */
+         tree dstarg = CALL_EXPR_ARG (exp, 0);
+         if (is_strlen_related_p (dstarg, bound))
+           {
+             /* The bound applies to the destination, not to the source,
+                so reset these to trigger a warning without mentioning
+                the bound.  */
+             bound = NULL;
+             fncode = 0;
+           }
+         else if (bndrng[1])
+           /* Use the upper bound of the range for strncat.  */
+           wibnd = wi::to_offset (bndrng[1]);
+       }
+      else if (bndrng[0])
+       /* Use the lower bound of the range for functions other than
+          strncat.  */
        wibnd = wi::to_offset (bndrng[0]);
 
+      /* Determine the size of the argument array if it is one.  */
       offset_int asize = wibnd;
+      bool known_size = false;
+      tree type = TREE_TYPE (decl);
 
+      /* Determine the array size.  For arrays of unknown bound and
+        pointers reset BOUND to trigger the appropriate warning.  */
       if (TREE_CODE (type) == ARRAY_TYPE)
-       if (tree arrbnd = TYPE_DOMAIN (type))
-         {
-           if ((arrbnd = TYPE_MAX_VALUE (arrbnd)))
-             asize = wi::to_offset (arrbnd) + 1;
-         }
+       {
+         if (tree arrbnd = TYPE_DOMAIN (type))
+           {
+             if ((arrbnd = TYPE_MAX_VALUE (arrbnd)))
+               {
+                 asize = wi::to_offset (arrbnd) + 1;
+                 known_size = true;
+               }
+           }
+         else if (bound == void_type_node)
+           bound = NULL_TREE;
+       }
+      else if (bound == void_type_node)
+       bound = NULL_TREE;
 
       location_t loc = EXPR_LOCATION (exp);
 
+      /* In a call to strncat with a bound in a range whose lower but
+        not upper bound is less than the array size, reset ASIZE to
+        be the same as the bound and the other variable to trigger
+        the apprpriate warning below.  */
+      if (fncode == BUILT_IN_STRNCAT
+         && bndrng[0] != bndrng[1]
+         && wi::ltu_p (wi::to_offset (bndrng[0]), asize)
+         && (!known_size
+             || wi::ltu_p (asize, wibnd)))
+       {
+         asize = wibnd;
+         bound = NULL_TREE;
+         fncode = 0;
+       }
+
       bool warned = false;
 
       if (wi::ltu_p (asize, wibnd))
-       warned = warning_at (loc, OPT_Wstringop_overflow_,
-                            "%qD argument %i declared attribute %<nonstring%> "
-                            "is smaller than the specified bound %E",
-                            fndecl, argno + 1, bndrng[0]);
+       {
+         if (bndrng[0] == bndrng[1])
+           warned = warning_at (loc, OPT_Wstringop_overflow_,
+                                "%qD argument %i declared attribute "
+                                "%<nonstring%> is smaller than the specified "
+                                "bound %wu",
+                                fndecl, argno + 1, wibnd.to_uhwi ());
+         else if (wi::ltu_p (asize, wi::to_offset (bndrng[0])))
+           warned = warning_at (loc, OPT_Wstringop_overflow_,
+                                "%qD argument %i declared attribute "
+                                "%<nonstring%> is smaller than "
+                                "the specified bound [%E, %E]",
+                                fndecl, argno + 1, bndrng[0], bndrng[1]);
+         else
+           warned = warning_at (loc, OPT_Wstringop_overflow_,
+                                "%qD argument %i declared attribute "
+                                "%<nonstring%> may be smaller than "
+                                "the specified bound [%E, %E]",
+                                fndecl, argno + 1, bndrng[0], bndrng[1]);
+       }
+      else if (fncode == BUILT_IN_STRNCAT)
+       ; /* Avoid warning for calls to strncat() when the bound
+            is equal to the size of the non-string argument.  */
       else if (!bound)
        warned = warning_at (loc, OPT_Wstringop_overflow_,
                             "%qD argument %i declared attribute %<nonstring%>",
index 4a5dc29..4a3bfe1 100644 (file)
@@ -1592,10 +1592,13 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
   if (crtl->shrink_wrapped
       && single_succ_p (bb1)
       && single_succ (bb1) == EXIT_BLOCK_PTR_FOR_FN (cfun)
-      && !JUMP_P (BB_END (bb1))
+      && (!JUMP_P (BB_END (bb1))
+         /* Punt if the only successor is a fake edge to exit, the jump
+            must be some weird one.  */
+         || (single_succ_edge (bb1)->flags & EDGE_FAKE) != 0)
       && !(CALL_P (BB_END (bb1)) && SIBLING_CALL_P (BB_END (bb1))))
     return false;
-  
+
   /* If BB1 has only one successor, we may be looking at either an
      unconditional jump, or a fake edge to exit.  */
   if (single_succ_p (bb1)
index deab929..018cf25 100644 (file)
@@ -1157,6 +1157,20 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data)
              if (repr_decl == NULL_TREE)
                repr_decl = stack_vars[i].decl;
              data->asan_decl_vec.safe_push (repr_decl);
+
+             /* Make sure a representative is unpoison if another
+                variable in the partition is handled by
+                use-after-scope sanitization.  */
+             if (asan_handled_variables != NULL
+                 && !asan_handled_variables->contains (repr_decl))
+               {
+                 for (j = i; j != EOC; j = stack_vars[j].next)
+                   if (asan_handled_variables->contains (stack_vars[j].decl))
+                     break;
+                 if (j != EOC)
+                   asan_handled_variables->add (repr_decl);
+               }
+
              data->asan_alignb = MAX (data->asan_alignb, alignb);
              if (data->asan_base == NULL)
                data->asan_base = gen_reg_rtx (Pmode);
@@ -1259,10 +1273,10 @@ set_parm_rtl (tree parm, rtx x)
         allocate it, which means that in-frame portion is just a
         pointer.  ??? We've got a pseudo for sure here, do we
         actually dynamically allocate its spilling area if needed?
-        ??? Isn't it a problem when POINTER_SIZE also exceeds
-        MAX_SUPPORTED_STACK_ALIGNMENT, as on cris and lm32?  */
+        ??? Isn't it a problem when Pmode alignment also exceeds
+        MAX_SUPPORTED_STACK_ALIGNMENT, as can happen on cris and lm32?  */
       if (align > MAX_SUPPORTED_STACK_ALIGNMENT)
-       align = POINTER_SIZE;
+       align = GET_MODE_ALIGNMENT (Pmode);
 
       record_alignment_for_reg_var (align);
     }
@@ -1383,7 +1397,7 @@ expand_one_ssa_partition (tree var)
   /* If the variable alignment is very large we'll dynamicaly allocate
      it, which means that in-frame portion is just a pointer.  */
   if (align > MAX_SUPPORTED_STACK_ALIGNMENT)
-    align = POINTER_SIZE;
+    align = GET_MODE_ALIGNMENT (Pmode);
 
   record_alignment_for_reg_var (align);
 
@@ -1610,7 +1624,7 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
       /* If the variable alignment is very large we'll dynamicaly allocate
         it, which means that in-frame portion is just a pointer.  */
       if (align > MAX_SUPPORTED_STACK_ALIGNMENT)
-       align = POINTER_SIZE;
+       align = GET_MODE_ALIGNMENT (Pmode);
     }
 
   record_alignment_for_reg_var (align);
@@ -3044,14 +3058,14 @@ expand_asm_stmt (gasm *stmt)
 
       generating_concat_p = 0;
 
-      if ((TREE_CODE (val) == INDIRECT_REF
-          && allows_mem)
+      if ((TREE_CODE (val) == INDIRECT_REF && allows_mem)
          || (DECL_P (val)
              && (allows_mem || REG_P (DECL_RTL (val)))
              && ! (REG_P (DECL_RTL (val))
                    && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
          || ! allows_reg
-         || is_inout)
+         || is_inout
+         || TREE_ADDRESSABLE (type))
        {
          op = expand_expr (val, NULL_RTX, VOIDmode,
                            !allows_reg ? EXPAND_MEMORY : EXPAND_WRITE);
@@ -3060,7 +3074,7 @@ expand_asm_stmt (gasm *stmt)
 
          if (! allows_reg && !MEM_P (op))
            error ("output number %d not directly addressable", i);
-         if ((! allows_mem && MEM_P (op))
+         if ((! allows_mem && MEM_P (op) && GET_MODE (op) != BLKmode)
              || GET_CODE (op) == CONCAT)
            {
              rtx old_op = op;
@@ -6534,6 +6548,14 @@ pass_expand::execute (function *fun)
   find_many_sub_basic_blocks (blocks);
   purge_all_dead_edges ();
 
+  /* After initial rtl generation, call back to finish generating
+     exception support code.  We need to do this before cleaning up
+     the CFG as the code does not expect dead landing pads.  */
+  if (fun->eh->region_tree != NULL)
+    finish_eh_generation ();
+
+  /* Call expand_stack_alignment after finishing all
+     updates to crtl->preferred_stack_boundary.  */
   expand_stack_alignment ();
 
   /* Fixup REG_EQUIV notes in the prologue if there are tailcalls in this
@@ -6541,12 +6563,6 @@ pass_expand::execute (function *fun)
   if (crtl->tail_call_emit)
     fixup_tail_calls ();
 
-  /* After initial rtl generation, call back to finish generating
-     exception support code.  We need to do this before cleaning up
-     the CFG as the code does not expect dead landing pads.  */
-  if (fun->eh->region_tree != NULL)
-    finish_eh_generation ();
-
   /* BB subdivision may have created basic blocks that are are only reachable
      from unlikely bbs but not marked as such in the profile.  */
   if (optimize)
index de704ce..f6e4fec 100644 (file)
@@ -984,6 +984,31 @@ block_label (basic_block block)
   return as_a <rtx_code_label *> (BB_HEAD (block));
 }
 
+/* Remove all barriers from BB_FOOTER of a BB.  */
+
+static void
+remove_barriers_from_footer (basic_block bb)
+{
+  rtx_insn *insn = BB_FOOTER (bb);
+
+  /* Remove barriers but keep jumptables.  */
+  while (insn)
+    {
+      if (BARRIER_P (insn))
+       {
+         if (PREV_INSN (insn))
+           SET_NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
+         else
+           BB_FOOTER (bb) = NEXT_INSN (insn);
+         if (NEXT_INSN (insn))
+           SET_PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
+       }
+      if (LABEL_P (insn))
+       return;
+      insn = NEXT_INSN (insn);
+    }
+}
+
 /* Attempt to perform edge redirection by replacing possibly complex jump
    instruction by unconditional jump or removing jump completely.  This can
    apply only if all edges now point to the same block.  The parameters and
@@ -1047,26 +1072,8 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
       /* Selectively unlink whole insn chain.  */
       if (in_cfglayout)
        {
-         rtx_insn *insn = BB_FOOTER (src);
-
          delete_insn_chain (kill_from, BB_END (src), false);
-
-         /* Remove barriers but keep jumptables.  */
-         while (insn)
-           {
-             if (BARRIER_P (insn))
-               {
-                 if (PREV_INSN (insn))
-                   SET_NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
-                 else
-                   BB_FOOTER (src) = NEXT_INSN (insn);
-                 if (NEXT_INSN (insn))
-                   SET_PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
-               }
-             if (LABEL_P (insn))
-               break;
-             insn = NEXT_INSN (insn);
-           }
+         remove_barriers_from_footer (src);
        }
       else
        delete_insn_chain (kill_from, PREV_INSN (BB_HEAD (target)),
@@ -1264,11 +1271,13 @@ patch_jump_insn (rtx_insn *insn, rtx_insn *old_label, basic_block new_bb)
 
          /* If the substitution doesn't succeed, die.  This can happen
             if the back end emitted unrecognizable instructions or if
-            target is exit block on some arches.  */
+            target is exit block on some arches.  Or for crossing
+            jumps.  */
          if (!redirect_jump (as_a <rtx_jump_insn *> (insn),
                              block_label (new_bb), 0))
            {
-             gcc_assert (new_bb == EXIT_BLOCK_PTR_FOR_FN (cfun));
+             gcc_assert (new_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
+                         || CROSSING_JUMP_P (insn));
              return false;
            }
        }
@@ -3315,8 +3324,15 @@ fixup_abnormal_edges (void)
                         If it's placed after a trapping call (i.e. that
                         call is the last insn anyway), we have no fallthru
                         edge.  Simply delete this use and don't try to insert
-                        on the non-existent edge.  */
-                     if (GET_CODE (PATTERN (insn)) != USE)
+                        on the non-existent edge.
+                        Similarly, sometimes a call that can throw is
+                        followed in the source with __builtin_unreachable (),
+                        meaning that there is UB if the call returns rather
+                        than throws.  If there weren't any instructions
+                        following such calls before, supposedly even the ones
+                        we've deleted aren't significant and can be
+                        removed.  */
+                     if (e)
                        {
                          /* We're not deleting it, we're moving it.  */
                          insn->set_undeleted ();
@@ -4370,6 +4386,7 @@ cfg_layout_redirect_edge_and_branch (edge e, basic_block dest)
                 "Removing crossing jump while redirecting edge form %i to %i\n",
                 e->src->index, dest->index);
       delete_insn (BB_END (src));
+      remove_barriers_from_footer (src);
       e->flags |= EDGE_FALLTHRU;
     }
 
@@ -4436,6 +4453,9 @@ cfg_layout_redirect_edge_and_branch (edge e, basic_block dest)
   else
     ret = redirect_branch_edge (e, dest);
 
+  if (!ret)
+    return NULL;
+
   fixup_partition_crossing (ret);
   /* We don't want simplejumps in the insn stream during cfglayout.  */
   gcc_assert (!simplejump_p (BB_END (src)) || CROSSING_JUMP_P (BB_END (src)));
index 9a7d54d..9f3a292 100644 (file)
@@ -517,6 +517,9 @@ cgraph_node::create (tree decl)
        g->have_offload = true;
     }
 
+  if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
+    node->ifunc_resolver = true;
+
   node->register_symbol ();
 
   if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
@@ -575,6 +578,8 @@ cgraph_node::create_alias (tree alias, tree target)
   alias_node->alias = true;
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     alias_node->transparent_alias = alias_node->weakref = true;
+  if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
+    alias_node->ifunc_resolver = true;
   return alias_node;
 }
 
@@ -2299,7 +2304,7 @@ cgraph_node::get_availability (symtab_node *ref)
     avail = AVAIL_AVAILABLE;
   else if (transparent_alias)
     ultimate_alias_target (&avail, ref);
-  else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
+  else if (ifunc_resolver
           || lookup_attribute ("noipa", DECL_ATTRIBUTES (decl)))
     avail = AVAIL_INTERPOSABLE;
   else if (!externally_visible)
index ee7ebb4..afb2745 100644 (file)
@@ -530,6 +530,9 @@ public:
   /* Set when symbol can be streamed into bytecode for offloading.  */
   unsigned offloadable : 1;
 
+  /* Set when symbol is an IFUNC resolver.  */
+  unsigned ifunc_resolver : 1;
+
 
   /* Ordering of all symtab entries.  */
   int order;
@@ -2886,6 +2889,7 @@ cgraph_node::only_called_directly_or_aliased_p (void)
 {
   gcc_assert (!global.inlined_to);
   return (!force_output && !address_taken
+         && !ifunc_resolver
          && !used_from_other_partition
          && !DECL_VIRTUAL_P (decl)
          && !DECL_STATIC_CONSTRUCTOR (decl)
index e418ec0..212ee7b 100644 (file)
@@ -1307,7 +1307,7 @@ maybe_diag_incompatible_alias (tree alias, tree target)
   tree altype = TREE_TYPE (alias);
   tree targtype = TREE_TYPE (target);
 
-  bool ifunc = lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias));
+  bool ifunc = cgraph_node::get (alias)->ifunc_resolver;
   tree funcptr = altype;
 
   if (ifunc)
index f26bc59..a96af13 100644 (file)
@@ -201,6 +201,7 @@ static enum lto_mode_d lto_mode = LTO_MODE_NONE;
 bool helpflag;                 /* true if --help */
 
 static int shared_obj;                 /* true if -shared */
+static int static_obj;                 /* true if -static */
 
 static const char *c_file;             /* <xxx>.c for constructor/destructor list.  */
 static const char *o_file;             /* <xxx>.o for constructor/destructor list.  */
@@ -255,6 +256,7 @@ bool may_unlink_output_file = false;
 #ifdef COLLECT_EXPORT_LIST
 /* Lists to keep libraries to be scanned for global constructors/destructors.  */
 static struct head libs;                    /* list of libraries */
+static struct head static_libs;             /* list of statically linked libraries */
 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
@@ -320,9 +322,7 @@ static void write_c_file_glob (FILE *, const char *);
 static void scan_libraries (const char *);
 #endif
 #ifdef COLLECT_EXPORT_LIST
-#if 0
 static int is_in_list (const char *, struct id *);
-#endif
 static void write_aix_file (FILE *, struct id *);
 static char *resolve_lib_name (const char *);
 #endif
@@ -911,6 +911,9 @@ main (int argc, char **argv)
   int first_file;
   int num_c_args;
   char **old_argv;
+#ifdef COLLECT_EXPORT_LIST
+  bool is_static = false;
+#endif
   int i;
 
   for (i = 0; i < USE_LD_MAX; i++)
@@ -1241,6 +1244,8 @@ main (int argc, char **argv)
        *c_ptr++ = xstrdup (q);
       if (strcmp (q, "-shared") == 0)
        shared_obj = 1;
+      if (strcmp (q, "-static") == 0)
+       static_obj = 1;
       if (*q == '-' && q[1] == 'B')
        {
          *c_ptr++ = xstrdup (q);
@@ -1269,6 +1274,9 @@ main (int argc, char **argv)
   /* Parse arguments.  Remember output file spec, pass the rest to ld.  */
   /* After the first file, put in the c++ rt0.  */
 
+#ifdef COLLECT_EXPORT_LIST
+  is_static = static_obj;
+#endif
   first_file = 1;
   while ((arg = *++argv) != (char *) 0)
     {
@@ -1374,6 +1382,18 @@ main (int argc, char **argv)
 #endif
               break;
 
+#ifdef COLLECT_EXPORT_LIST
+           case 'b':
+             if (!strcmp (arg, "-bstatic"))
+               {
+                 is_static = true;
+               }
+             else if (!strcmp (arg, "-bdynamic") || !strcmp (arg, "-bshared"))
+               {
+                 is_static = false;
+               }
+             break;
+#endif
            case 'l':
              if (first_file)
                {
@@ -1390,6 +1410,8 @@ main (int argc, char **argv)
 
                /* Saving a full library name.  */
                add_to_list (&libs, s);
+               if (is_static)
+                   add_to_list (&static_libs, s);
              }
 #endif
              break;
@@ -1490,6 +1512,8 @@ main (int argc, char **argv)
            {
              /* Saving a full library name.  */
              add_to_list (&libs, arg);
+             if (is_static)
+               add_to_list (&static_libs, arg);
            }
 #endif
        }
@@ -1501,6 +1525,8 @@ main (int argc, char **argv)
     {
       fprintf (stderr, "List of libraries:\n");
       dump_list (stderr, "\t", libs.first);
+      fprintf (stderr, "List of statically linked libraries:\n");
+      dump_list (stderr, "\t", static_libs.first);
     }
 
   /* The AIX linker will discard static constructors in object files if
@@ -1525,9 +1551,11 @@ main (int argc, char **argv)
       this_filter &= ~SCAN_DWEH;
 #endif
 
+    /* Scan object files.  */
     while (export_object_lst < object)
       scan_prog_file (*export_object_lst++, PASS_OBJ, this_filter);
 
+    /* Scan libraries.  */
     for (; list; list = list->next)
       scan_prog_file (list->name, PASS_FIRST, this_filter);
 
@@ -1975,7 +2003,6 @@ write_list (FILE *stream, const char *prefix, struct id *list)
 
 #ifdef COLLECT_EXPORT_LIST
 /* This function is really used only on AIX, but may be useful.  */
-#if 0
 static int
 is_in_list (const char *prefix, struct id *list)
 {
@@ -1986,7 +2013,6 @@ is_in_list (const char *prefix, struct id *list)
     }
     return 0;
 }
-#endif
 #endif /* COLLECT_EXPORT_LIST */
 
 /* Added for debugging purpose.  */
@@ -2818,7 +2844,12 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
                        case SYM_AIXI:
                          if (! (filter & SCAN_CTOR))
                            break;
-                         if (is_shared && !aixlazy_flag)
+                         if (is_shared && !aixlazy_flag
+#ifdef COLLECT_EXPORT_LIST
+                             && ! static_obj
+                             && ! is_in_list (prog_name, static_libs.first)
+#endif
+                             )
                            add_to_list (&constructors, name);
                          break;
 
index 3ad050f..899b6f1 100644 (file)
@@ -981,14 +981,17 @@ combine_validate_cost (rtx_insn *i0, rtx_insn *i1, rtx_insn *i2, rtx_insn *i3,
 }
 
 
-/* Delete any insns that copy a register to itself.  */
+/* Delete any insns that copy a register to itself.
+   Return true if the CFG was changed.  */
 
-static void
+static bool
 delete_noop_moves (void)
 {
   rtx_insn *insn, *next;
   basic_block bb;
 
+  bool edges_deleted = false;
+
   FOR_EACH_BB_FN (bb, cfun)
     {
       for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); insn = next)
@@ -999,10 +1002,12 @@ delete_noop_moves (void)
              if (dump_file)
                fprintf (dump_file, "deleting noop move %d\n", INSN_UID (insn));
 
-             delete_insn_and_edges (insn);
+             edges_deleted |= delete_insn_and_edges (insn);
            }
        }
     }
+
+  return edges_deleted;
 }
 
 \f
@@ -1141,8 +1146,8 @@ insn_a_feeds_b (rtx_insn *a, rtx_insn *b)
 /* Main entry point for combiner.  F is the first insn of the function.
    NREGS is the first unused pseudo-reg number.
 
-   Return nonzero if the combiner has turned an indirect jump
-   instruction into a direct jump.  */
+   Return nonzero if the CFG was changed (e.g. if the combiner has
+   turned an indirect jump instruction into a direct jump).  */
 static int
 combine_instructions (rtx_insn *f, unsigned int nregs)
 {
@@ -1527,7 +1532,7 @@ retry:
   default_rtl_profile ();
   clear_bb_flags ();
   new_direct_jump_p |= purge_all_dead_edges ();
-  delete_noop_moves ();
+  new_direct_jump_p |= delete_noop_moves ();
 
   /* Clean up.  */
   obstack_free (&insn_link_obstack, NULL);
@@ -4007,7 +4012,10 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
      other insns to combine, but the destination of that SET is still live.
 
      Also do this if we started with two insns and (at least) one of the
-     resulting sets is a noop; this noop will be deleted later.  */
+     resulting sets is a noop; this noop will be deleted later.
+
+     Also do this if we started with two insns neither of which was a simple
+     move.  */
 
   else if (insn_code_number < 0 && asm_noperands (newpat) < 0
           && GET_CODE (newpat) == PARALLEL
@@ -4035,13 +4043,15 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
         one which uses any regs/memory set in between i2 and i3 can't
         be first.  The PARALLEL might also have been pre-existing in i3,
         so we need to make sure that we won't wrongly hoist a SET to i2
-        that would conflict with a death note present in there.  */
+        that would conflict with a death note present in there, or would
+        have its dest modified between i2 and i3.  */
       if (!modified_between_p (SET_SRC (set1), i2, i3)
          && !(REG_P (SET_DEST (set1))
               && find_reg_note (i2, REG_DEAD, SET_DEST (set1)))
          && !(GET_CODE (SET_DEST (set1)) == SUBREG
               && find_reg_note (i2, REG_DEAD,
                                 SUBREG_REG (SET_DEST (set1))))
+         && !modified_between_p (SET_DEST (set1), i2, i3)
          && (!HAVE_cc0 || !reg_referenced_p (cc0_rtx, set0))
          /* If I3 is a jump, ensure that set0 is a jump so that
             we do not create invalid RTL.  */
@@ -4057,6 +4067,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
               && !(GET_CODE (SET_DEST (set0)) == SUBREG
                    && find_reg_note (i2, REG_DEAD,
                                      SUBREG_REG (SET_DEST (set0))))
+              && !modified_between_p (SET_DEST (set0), i2, i3)
               && (!HAVE_cc0 || !reg_referenced_p (cc0_rtx, set1))
               /* If I3 is a jump, ensure that set1 is a jump so that
                  we do not create invalid RTL.  */
@@ -5904,8 +5915,9 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int in_dest,
            && known_eq (subreg_lowpart_offset (int_mode, int_op0_mode),
                         SUBREG_BYTE (x))
            && HWI_COMPUTABLE_MODE_P (int_op0_mode)
-           && (nonzero_bits (SUBREG_REG (x), int_op0_mode)
-               & GET_MODE_MASK (int_mode)) == 0)
+           && ((nonzero_bits (SUBREG_REG (x), int_op0_mode)
+                & GET_MODE_MASK (int_mode)) == 0)
+           && !side_effects_p (SUBREG_REG (x)))
          return CONST0_RTX (int_mode);
       }
 
@@ -6455,7 +6467,7 @@ simplify_if_then_else (rtx x)
                          pc_rtx, pc_rtx, 0, 0, 0);
       if (reg_mentioned_p (from, false_rtx))
        false_rtx = subst (known_cond (copy_rtx (false_rtx), false_code,
-                                  from, false_val),
+                                      from, false_val),
                           pc_rtx, pc_rtx, 0, 0, 0);
 
       SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx);
@@ -7595,6 +7607,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
              /* We can't do this if we are widening INNER_MODE (it
                 may not be aligned, for one thing).  */
              && !paradoxical_subreg_p (tmode, inner_mode)
+             && known_le (pos + len, GET_MODE_PRECISION (is_mode))
              && (inner_mode == tmode
                  || (! mode_dependent_address_p (XEXP (inner, 0),
                                                  MEM_ADDR_SPACE (inner))
@@ -7737,6 +7750,10 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
       && partial_subreg_p (extraction_mode, mode))
     extraction_mode = mode;
 
+  /* Punt if len is too large for extraction_mode.  */
+  if (maybe_gt (len, GET_MODE_PRECISION (extraction_mode)))
+    return NULL_RTX;
+
   if (!MEM_P (inner))
     wanted_inner_mode = wanted_inner_reg_mode;
   else
@@ -9294,6 +9311,7 @@ if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse)
 
          if (COMPARISON_P (cond0)
              && COMPARISON_P (cond1)
+             && SCALAR_INT_MODE_P (mode)
              && ((GET_CODE (cond0) == reversed_comparison_code (cond1, NULL)
                   && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0))
                   && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1)))
@@ -9474,12 +9492,12 @@ known_cond (rtx x, enum rtx_code cond, rtx reg, rtx val)
          if (COMPARISON_P (x))
            {
              if (comparison_dominates_p (cond, code))
-               return const_true_rtx;
+               return VECTOR_MODE_P (GET_MODE (x)) ? x : const_true_rtx;
 
              code = reversed_comparison_code (x, NULL);
              if (code != UNKNOWN
                  && comparison_dominates_p (cond, code))
-               return const0_rtx;
+               return CONST0_RTX (GET_MODE (x));
              else
                return x;
            }
@@ -9522,7 +9540,7 @@ known_cond (rtx x, enum rtx_code cond, rtx reg, rtx val)
          /* We must simplify subreg here, before we lose track of the
             original inner_mode.  */
          new_rtx = simplify_subreg (GET_MODE (x), r,
-                                inner_mode, SUBREG_BYTE (x));
+                                    inner_mode, SUBREG_BYTE (x));
          if (new_rtx)
            return new_rtx;
          else
@@ -9547,7 +9565,7 @@ known_cond (rtx x, enum rtx_code cond, rtx reg, rtx val)
          /* We must simplify the zero_extend here, before we lose
             track of the original inner_mode.  */
          new_rtx = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
-                                         r, inner_mode);
+                                             r, inner_mode);
          if (new_rtx)
            return new_rtx;
          else
@@ -10165,7 +10183,8 @@ reg_nonzero_bits_for_combine (const_rtx x, scalar_int_mode xmode,
   rsp = &reg_stat[REGNO (x)];
   if (rsp->last_set_value != 0
       && (rsp->last_set_mode == mode
-         || (GET_MODE_CLASS (rsp->last_set_mode) == MODE_INT
+         || (REGNO (x) >= FIRST_PSEUDO_REGISTER
+             && GET_MODE_CLASS (rsp->last_set_mode) == MODE_INT
              && GET_MODE_CLASS (mode) == MODE_INT))
       && ((rsp->last_set_label >= label_tick_ebb_start
           && rsp->last_set_label < label_tick)
@@ -13288,6 +13307,7 @@ record_dead_and_set_regs_1 (rtx dest, const_rtx setter, void *data)
               && subreg_lowpart_p (SET_DEST (setter)))
        record_value_for_reg (dest, record_dead_insn,
                              WORD_REGISTER_OPERATIONS
+                             && word_register_operation_p (SET_SRC (setter))
                              && paradoxical_subreg_p (SET_DEST (setter))
                              ? SET_SRC (setter)
                              : gen_lowpart (GET_MODE (dest),
index d6ef859..b52ef0b 100644 (file)
@@ -645,8 +645,8 @@ Common Var(warn_null_dereference) Warning
 Warn if dereferencing a NULL pointer may lead to erroneous or undefined behavior.
 
 Wunsafe-loop-optimizations
-Common Var(warn_unsafe_loop_optimizations) Warning
-Warn if the loop cannot be optimized due to nontrivial assumptions.
+Common Ignore Warning
+Does nothing. Preserved for backward compatibility.
 
 Wmissing-noreturn
 Common Warning Alias(Wsuggest-attribute=noreturn)
@@ -937,7 +937,11 @@ Driver Undocumented
 ;
 ; 12: Corrects the calling convention for classes with only deleted copy/move
 ;     constructors and changes passing/returning of empty records.
-;     Default in G++ 8.
+;     Default in G++ 8.1.
+;
+; 13: Fixes the accidental change in 12 to the calling convention for classes
+;     with deleted copy constructor and trivial move constructor.
+;     Default in G++ 8.2.
 ;
 ; Additional positive integers will be assigned as new versions of
 ; the ABI become the default version of the ABI.
index 2629ae6..3d96132 100644 (file)
@@ -59,7 +59,7 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA_FXSR_SET OPTION_MASK_ISA_FXSR
 #define OPTION_MASK_ISA_XSAVE_SET OPTION_MASK_ISA_XSAVE
 #define OPTION_MASK_ISA_XSAVEOPT_SET \
-  (OPTION_MASK_ISA_XSAVEOPT | OPTION_MASK_ISA_XSAVE)
+  (OPTION_MASK_ISA_XSAVEOPT | OPTION_MASK_ISA_XSAVE_SET)
 #define OPTION_MASK_ISA_AVX512F_SET \
   (OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_AVX2_SET)
 #define OPTION_MASK_ISA_AVX512CD_SET \
@@ -95,9 +95,9 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA_PREFETCHWT1_SET OPTION_MASK_ISA_PREFETCHWT1
 #define OPTION_MASK_ISA_CLFLUSHOPT_SET OPTION_MASK_ISA_CLFLUSHOPT
 #define OPTION_MASK_ISA_XSAVES_SET \
-  (OPTION_MASK_ISA_XSAVES | OPTION_MASK_ISA_XSAVE)
+  (OPTION_MASK_ISA_XSAVES | OPTION_MASK_ISA_XSAVE_SET)
 #define OPTION_MASK_ISA_XSAVEC_SET \
-  (OPTION_MASK_ISA_XSAVEC | OPTION_MASK_ISA_XSAVE)
+  (OPTION_MASK_ISA_XSAVEC | OPTION_MASK_ISA_XSAVE_SET)
 #define OPTION_MASK_ISA_CLWB_SET OPTION_MASK_ISA_CLWB
 
 /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same
@@ -183,7 +183,8 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA_FMA_UNSET OPTION_MASK_ISA_FMA
 #define OPTION_MASK_ISA_FXSR_UNSET OPTION_MASK_ISA_FXSR
 #define OPTION_MASK_ISA_XSAVE_UNSET \
-  (OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_XSAVEOPT_UNSET)
+  (OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_XSAVEOPT_UNSET \
+   | OPTION_MASK_ISA_XSAVES_UNSET | OPTION_MASK_ISA_XSAVEC_UNSET)
 #define OPTION_MASK_ISA_XSAVEOPT_UNSET OPTION_MASK_ISA_XSAVEOPT
 #define OPTION_MASK_ISA_AVX2_UNSET \
   (OPTION_MASK_ISA_AVX2 | OPTION_MASK_ISA_AVX512F_UNSET)
index 54f03ee..3a7414a 100644 (file)
@@ -107,7 +107,7 @@ _mm512_bitshuffle_epi64_mask (__m512i __A, __m512i __B)
 
 extern __inline __mmask64
 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm512_mask_bitshuffle_epi64_mask (__mmask8 __M, __m512i __A, __m512i __B)
+_mm512_mask_bitshuffle_epi64_mask (__mmask64 __M, __m512i __A, __m512i __B)
 {
   return (__mmask64) __builtin_ia32_vpshufbitqmb512_mask ((__v64qi) __A,
                                                 (__v64qi) __B,
index bd389fa..24ad5f1 100644 (file)
@@ -3043,7 +3043,7 @@ _mm512_cmp_epi16_mask (__m512i __X, __m512i __Y, const int __P)
 
 extern __inline __mmask64
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm512_mask_cmp_epi8_mask (__mmask32 __U, __m512i __X, __m512i __Y,
+_mm512_mask_cmp_epi8_mask (__mmask64 __U, __m512i __X, __m512i __Y,
                           const int __P)
 {
   return (__mmask64) __builtin_ia32_cmpb512_mask ((__v64qi) __X,
@@ -3081,7 +3081,7 @@ _mm512_cmp_epu16_mask (__m512i __X, __m512i __Y, const int __P)
 
 extern __inline __mmask64
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm512_mask_cmp_epu8_mask (__mmask32 __U, __m512i __X, __m512i __Y,
+_mm512_mask_cmp_epu8_mask (__mmask64 __U, __m512i __X, __m512i __Y,
                           const int __P)
 {
   return (__mmask64) __builtin_ia32_ucmpb512_mask ((__v64qi) __X,
index ba65aca..74184ff 100644 (file)
@@ -3762,7 +3762,7 @@ _mm512_maskz_fnmsub_round_ps (__mmask16 __U, __m512 __A, __m512 __B,
     (__m512d)__builtin_ia32_vfmaddsubpd512_mask(A, B, C, -1, R)
 
 #define _mm512_mask_fmaddsub_round_pd(A, U, B, C, R)    \
-    (__m512d)__builtin_ia32_vfmaddpd512_mask(A, B, C, U, R)
+    (__m512d)__builtin_ia32_vfmaddsubpd512_mask(A, B, C, U, R)
 
 #define _mm512_mask3_fmaddsub_round_pd(A, B, C, U, R)   \
     (__m512d)__builtin_ia32_vfmaddsubpd512_mask3(A, B, C, U, R)
@@ -7306,7 +7306,7 @@ _mm512_xor_epi64 (__m512i __A, __m512i __B)
 
 extern __inline __m512i
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm512_mask_xor_epi64 (__m512i __W, __mmask16 __U, __m512i __A, __m512i __B)
+_mm512_mask_xor_epi64 (__m512i __W, __mmask8 __U, __m512i __A, __m512i __B)
 {
   return (__m512i) __builtin_ia32_pxorq512_mask ((__v8di) __A,
                                                 (__v8di) __B,
@@ -7316,7 +7316,7 @@ _mm512_mask_xor_epi64 (__m512i __W, __mmask16 __U, __m512i __A, __m512i __B)
 
 extern __inline __m512i
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm512_maskz_xor_epi64 (__mmask16 __U, __m512i __A, __m512i __B)
+_mm512_maskz_xor_epi64 (__mmask8 __U, __m512i __A, __m512i __B)
 {
   return (__m512i) __builtin_ia32_pxorq512_mask ((__v8di) __A,
                                                 (__v8di) __B,
@@ -7727,7 +7727,7 @@ _mm512_mask_abs_ps (__m512 __W, __mmask16 __U, __m512 __A)
 
 extern __inline __m512d
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm512_abs_pd (__m512 __A)
+_mm512_abs_pd (__m512d __A)
 {
   return (__m512d) _mm512_and_epi64 ((__m512i) __A,
                                     _mm512_set1_epi64 (0x7fffffffffffffffLL));
@@ -7735,7 +7735,7 @@ _mm512_abs_pd (__m512 __A)
 
 extern __inline __m512d
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm512_mask_abs_pd (__m512d __W, __mmask8 __U, __m512 __A)
+_mm512_mask_abs_pd (__m512d __W, __mmask8 __U, __m512d __A)
 {
   return (__m512d)
         _mm512_mask_and_epi64 ((__m512i) __W, __U, (__m512i) __A,
@@ -9544,7 +9544,7 @@ _mm512_cmpneq_epu32_mask (__m512i __X, __m512i __Y)
 
 extern __inline __mmask8
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm512_mask_cmpneq_epi64_mask (__mmask16 __M, __m512i __X, __m512i __Y)
+_mm512_mask_cmpneq_epi64_mask (__mmask8 __M, __m512i __X, __m512i __Y)
 {
   return (__mmask8) __builtin_ia32_cmpq512_mask ((__v8di) __X,
                                                    (__v8di) __Y, 4,
@@ -10806,22 +10806,22 @@ _mm512_mask_insertf32x4 (__m512 __A, __mmask16 __B, __m512 __C,
 #define _mm512_maskz_insertf32x4(A, X, Y, C)                            \
   ((__m512) __builtin_ia32_insertf32x4_mask ((__v16sf)(__m512) (X),     \
     (__v4sf)(__m128) (Y), (int) (C), (__v16sf)_mm512_setzero_ps(),      \
-    (__mmask8)(A)))
+    (__mmask16)(A)))
 
 #define _mm512_maskz_inserti32x4(A, X, Y, C)                            \
   ((__m512i) __builtin_ia32_inserti32x4_mask ((__v16si)(__m512i) (X),   \
     (__v4si)(__m128i) (Y), (int) (C), (__v16si)_mm512_setzero_si512 (),     \
-    (__mmask8)(A)))
+    (__mmask16)(A)))
 
 #define _mm512_mask_insertf32x4(A, B, X, Y, C)                          \
   ((__m512) __builtin_ia32_insertf32x4_mask ((__v16sf)(__m512) (X),     \
     (__v4sf)(__m128) (Y), (int) (C), (__v16sf)(__m512) (A),             \
-                                            (__mmask8)(B)))
+                                            (__mmask16)(B)))
 
 #define _mm512_mask_inserti32x4(A, B, X, Y, C)                          \
   ((__m512i) __builtin_ia32_inserti32x4_mask ((__v16si)(__m512i) (X),   \
     (__v4si)(__m128i) (Y), (int) (C), (__v16si)(__m512i) (A),           \
-                                             (__mmask8)(B)))
+                                             (__mmask16)(B)))
 #endif
 
 extern __inline __m512i
index b6a3cfd..b089d33 100644 (file)
@@ -541,7 +541,7 @@ _mm_shldi_epi64 (__m128i __A, __m128i __B, int __C)
        (__v4si)(__m128i)(B),(int)(C))
 #define _mm_mask_shrdi_epi32(A, B, C, D, E) \
   ((__m128i) __builtin_ia32_vpshrd_v4si_mask ((__v4si)(__m128i)(C), \
-       (__v4si)(__m128i)(D), (int)(E), (__v4si)(__m128i)(A),(__mmask16)(B))
+       (__v4si)(__m128i)(D), (int)(E), (__v4si)(__m128i)(A),(__mmask8)(B))
 #define _mm_maskz_shrdi_epi32(A, B, C, D) \
   ((__m128i) __builtin_ia32_vpshrd_v4si_mask ((__v4si)(__m128i)(B), \
        (__v4si)(__m128i)(C),(int)(D), \
@@ -601,7 +601,7 @@ _mm_shldi_epi64 (__m128i __A, __m128i __B, int __C)
        (__v4si)(__m128i)(B),(int)(C))
 #define _mm_mask_shldi_epi32(A, B, C, D, E) \
   ((__m128i) __builtin_ia32_vpshld_v4si_mask ((__v4si)(__m128i)(C), \
-       (__v4si)(__m128i)(D), (int)(E), (__v4si)(__m128i)(A),(__mmask16)(B))
+       (__v4si)(__m128i)(D), (int)(E), (__v4si)(__m128i)(A),(__mmask8)(B))
 #define _mm_maskz_shldi_epi32(A, B, C, D) \
   ((__m128i) __builtin_ia32_vpshld_v4si_mask ((__v4si)(__m128i)(B), \
        (__v4si)(__m128i)(C),(int)(D), \
index c14a86a..02afce1 100644 (file)
@@ -1467,7 +1467,7 @@ _mm256_cmp_epi16_mask (__m256i __X, __m256i __Y, const int __P)
 
 extern __inline __mmask16
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_mask_cmp_epi8_mask (__mmask8 __U, __m128i __X, __m128i __Y,
+_mm_mask_cmp_epi8_mask (__mmask16 __U, __m128i __X, __m128i __Y,
                        const int __P)
 {
   return (__mmask16) __builtin_ia32_cmpb128_mask ((__v16qi) __X,
@@ -1486,7 +1486,7 @@ _mm_cmp_epi8_mask (__m128i __X, __m128i __Y, const int __P)
 
 extern __inline __mmask32
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmp_epi8_mask (__mmask16 __U, __m256i __X, __m256i __Y,
+_mm256_mask_cmp_epi8_mask (__mmask32 __U, __m256i __X, __m256i __Y,
                           const int __P)
 {
   return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X,
@@ -1494,7 +1494,7 @@ _mm256_mask_cmp_epi8_mask (__mmask16 __U, __m256i __X, __m256i __Y,
                                                  (__mmask32) __U);
 }
 
-extern __inline __mmask16
+extern __inline __mmask32
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
 _mm256_cmp_epi8_mask (__m256i __X, __m256i __Y, const int __P)
 {
@@ -1543,7 +1543,7 @@ _mm256_cmp_epu16_mask (__m256i __X, __m256i __Y, const int __P)
 
 extern __inline __mmask16
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_mask_cmp_epu8_mask (__mmask8 __U, __m128i __X, __m128i __Y,
+_mm_mask_cmp_epu8_mask (__mmask16 __U, __m128i __X, __m128i __Y,
                        const int __P)
 {
   return (__mmask16) __builtin_ia32_ucmpb128_mask ((__v16qi) __X,
@@ -1562,7 +1562,7 @@ _mm_cmp_epu8_mask (__m128i __X, __m128i __Y, const int __P)
 
 extern __inline __mmask32
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmp_epu8_mask (__mmask16 __U, __m256i __X, __m256i __Y,
+_mm256_mask_cmp_epu8_mask (__mmask32 __U, __m256i __X, __m256i __Y,
                           const int __P)
 {
   return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X,
@@ -1570,7 +1570,7 @@ _mm256_mask_cmp_epu8_mask (__mmask16 __U, __m256i __X, __m256i __Y,
                                                   (__mmask32) __U);
 }
 
-extern __inline __mmask16
+extern __inline __mmask32
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
 _mm256_cmp_epu8_mask (__m256i __X, __m256i __Y, const int __P)
 {
@@ -1998,7 +1998,7 @@ _mm_maskz_slli_epi16 (__mmask8 __U, __m128i __A, int __B)
 #define _mm_mask_cmp_epi16_mask(M, X, Y, P)                            \
   ((__mmask8) __builtin_ia32_cmpw128_mask ((__v8hi)(__m128i)(X),       \
                                            (__v8hi)(__m128i)(Y), (int)(P),\
-                                           (__mmask16)(M)))
+                                           (__mmask8)(M)))
 
 #define _mm_mask_cmp_epi8_mask(M, X, Y, P)                             \
   ((__mmask16) __builtin_ia32_cmpb128_mask ((__v16qi)(__m128i)(X),     \
@@ -2430,7 +2430,7 @@ _mm_maskz_mullo_epi16 (__mmask8 __U, __m128i __A, __m128i __B)
 
 extern __inline __m256i
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cvtepi8_epi16 (__m256i __W, __mmask32 __U, __m128i __A)
+_mm256_mask_cvtepi8_epi16 (__m256i __W, __mmask16 __U, __m128i __A)
 {
   return (__m256i) __builtin_ia32_pmovsxbw256_mask ((__v16qi) __A,
                                                    (__v16hi) __W,
@@ -2449,7 +2449,7 @@ _mm256_maskz_cvtepi8_epi16 (__mmask16 __U, __m128i __A)
 
 extern __inline __m128i
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_mask_cvtepi8_epi16 (__m128i __W, __mmask32 __U, __m128i __A)
+_mm_mask_cvtepi8_epi16 (__m128i __W, __mmask8 __U, __m128i __A)
 {
   return (__m128i) __builtin_ia32_pmovsxbw128_mask ((__v16qi) __A,
                                                    (__v8hi) __W,
@@ -2468,7 +2468,7 @@ _mm_maskz_cvtepi8_epi16 (__mmask8 __U, __m128i __A)
 
 extern __inline __m256i
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cvtepu8_epi16 (__m256i __W, __mmask32 __U, __m128i __A)
+_mm256_mask_cvtepu8_epi16 (__m256i __W, __mmask16 __U, __m128i __A)
 {
   return (__m256i) __builtin_ia32_pmovzxbw256_mask ((__v16qi) __A,
                                                    (__v16hi) __W,
@@ -2487,7 +2487,7 @@ _mm256_maskz_cvtepu8_epi16 (__mmask16 __U, __m128i __A)
 
 extern __inline __m128i
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_mask_cvtepu8_epi16 (__m128i __W, __mmask32 __U, __m128i __A)
+_mm_mask_cvtepu8_epi16 (__m128i __W, __mmask8 __U, __m128i __A)
 {
   return (__m128i) __builtin_ia32_pmovzxbw128_mask ((__v16qi) __A,
                                                    (__v8hi) __W,
@@ -4541,148 +4541,148 @@ _mm_mask_cmple_epi16_mask (__mmask8 __M, __m128i __X, __m128i __Y)
                                                 (__mmask8) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask32
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmpneq_epu8_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmpneq_epu8_mask (__mmask32 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_ucmpb256_mask ((__v32qi) __X,
-                                                 (__v32qi) __Y, 4,
-                                                 (__mmask8) __M);
+  return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X,
+                                                  (__v32qi) __Y, 4,
+                                                  (__mmask32) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask32
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmplt_epu8_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmplt_epu8_mask (__mmask32 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_ucmpb256_mask ((__v32qi) __X,
-                                                 (__v32qi) __Y, 1,
-                                                 (__mmask8) __M);
+  return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X,
+                                                  (__v32qi) __Y, 1,
+                                                  (__mmask32) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask32
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmpge_epu8_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmpge_epu8_mask (__mmask32 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_ucmpb256_mask ((__v32qi) __X,
-                                                 (__v32qi) __Y, 5,
-                                                 (__mmask8) __M);
+  return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X,
+                                                  (__v32qi) __Y, 5,
+                                                  (__mmask32) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask32
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmple_epu8_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmple_epu8_mask (__mmask32 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_ucmpb256_mask ((__v32qi) __X,
-                                                 (__v32qi) __Y, 2,
-                                                 (__mmask8) __M);
+  return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X,
+                                                  (__v32qi) __Y, 2,
+                                                  (__mmask32) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask16
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmpneq_epu16_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmpneq_epu16_mask (__mmask16 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_ucmpw256_mask ((__v16hi) __X,
-                                                 (__v16hi) __Y, 4,
-                                                 (__mmask8) __M);
+  return (__mmask16) __builtin_ia32_ucmpw256_mask ((__v16hi) __X,
+                                                  (__v16hi) __Y, 4,
+                                                  (__mmask16) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask16
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmplt_epu16_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmplt_epu16_mask (__mmask16 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_ucmpw256_mask ((__v16hi) __X,
-                                                 (__v16hi) __Y, 1,
-                                                 (__mmask8) __M);
+  return (__mmask16) __builtin_ia32_ucmpw256_mask ((__v16hi) __X,
+                                                  (__v16hi) __Y, 1,
+                                                  (__mmask16) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask16
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmpge_epu16_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmpge_epu16_mask (__mmask16 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_ucmpw256_mask ((__v16hi) __X,
-                                                 (__v16hi) __Y, 5,
-                                                 (__mmask8) __M);
+  return (__mmask16) __builtin_ia32_ucmpw256_mask ((__v16hi) __X,
+                                                  (__v16hi) __Y, 5,
+                                                  (__mmask16) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask16
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmple_epu16_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmple_epu16_mask (__mmask16 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_ucmpw256_mask ((__v16hi) __X,
-                                                 (__v16hi) __Y, 2,
-                                                 (__mmask8) __M);
+  return (__mmask16) __builtin_ia32_ucmpw256_mask ((__v16hi) __X,
+                                                  (__v16hi) __Y, 2,
+                                                  (__mmask16) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask32
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmpneq_epi8_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmpneq_epi8_mask (__mmask32 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_cmpb256_mask ((__v32qi) __X,
-                                                (__v32qi) __Y, 4,
-                                                (__mmask8) __M);
+  return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X,
+                                                 (__v32qi) __Y, 4,
+                                                 (__mmask32) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask32
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmplt_epi8_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmplt_epi8_mask (__mmask32 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_cmpb256_mask ((__v32qi) __X,
-                                                (__v32qi) __Y, 1,
-                                                (__mmask8) __M);
+  return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X,
+                                                 (__v32qi) __Y, 1,
+                                                 (__mmask32) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask32
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmpge_epi8_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmpge_epi8_mask (__mmask32 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_cmpb256_mask ((__v32qi) __X,
-                                                (__v32qi) __Y, 5,
-                                                (__mmask8) __M);
+  return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X,
+                                                 (__v32qi) __Y, 5,
+                                                 (__mmask32) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask32
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmple_epi8_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmple_epi8_mask (__mmask32 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_cmpb256_mask ((__v32qi) __X,
-                                                (__v32qi) __Y, 2,
-                                                (__mmask8) __M);
+  return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X,
+                                                 (__v32qi) __Y, 2,
+                                                 (__mmask32) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask16
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmpneq_epi16_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmpneq_epi16_mask (__mmask16 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_cmpw256_mask ((__v16hi) __X,
-                                                (__v16hi) __Y, 4,
-                                                (__mmask8) __M);
+  return (__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi) __X,
+                                                 (__v16hi) __Y, 4,
+                                                 (__mmask16) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask16
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmplt_epi16_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmplt_epi16_mask (__mmask16 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_cmpw256_mask ((__v16hi) __X,
-                                                (__v16hi) __Y, 1,
-                                                (__mmask8) __M);
+  return (__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi) __X,
+                                                 (__v16hi) __Y, 1,
+                                                 (__mmask16) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask16
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmpge_epi16_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmpge_epi16_mask (__mmask16 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_cmpw256_mask ((__v16hi) __X,
-                                                (__v16hi) __Y, 5,
-                                                (__mmask8) __M);
+  return (__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi) __X,
+                                                 (__v16hi) __Y, 5,
+                                                 (__mmask16) __M);
 }
 
-extern __inline __mmask8
+extern __inline __mmask16
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_cmple_epi16_mask (__mmask8 __M, __m256i __X, __m256i __Y)
+_mm256_mask_cmple_epi16_mask (__mmask16 __M, __m256i __X, __m256i __Y)
 {
-  return (__mmask8) __builtin_ia32_cmpw256_mask ((__v16hi) __X,
-                                                (__v16hi) __Y, 2,
-                                                (__mmask8) __M);
+  return (__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi) __X,
+                                                 (__v16hi) __Y, 2,
+                                                 (__mmask16) __M);
 }
 
 #ifdef __DISABLE_AVX512VLBW__
index 4dfe12f..68b5537 100644 (file)
@@ -466,7 +466,7 @@ _mm256_maskz_add_pd (__mmask8 __U, __m256d __A, __m256d __B)
 
 extern __inline __m128
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_mask_add_ps (__m128 __W, __mmask16 __U, __m128 __A, __m128 __B)
+_mm_mask_add_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B)
 {
   return (__m128) __builtin_ia32_addps128_mask ((__v4sf) __A,
                                                (__v4sf) __B,
@@ -476,7 +476,7 @@ _mm_mask_add_ps (__m128 __W, __mmask16 __U, __m128 __A, __m128 __B)
 
 extern __inline __m128
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_maskz_add_ps (__mmask16 __U, __m128 __A, __m128 __B)
+_mm_maskz_add_ps (__mmask8 __U, __m128 __A, __m128 __B)
 {
   return (__m128) __builtin_ia32_addps128_mask ((__v4sf) __A,
                                                (__v4sf) __B,
@@ -487,7 +487,7 @@ _mm_maskz_add_ps (__mmask16 __U, __m128 __A, __m128 __B)
 
 extern __inline __m256
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_add_ps (__m256 __W, __mmask16 __U, __m256 __A, __m256 __B)
+_mm256_mask_add_ps (__m256 __W, __mmask8 __U, __m256 __A, __m256 __B)
 {
   return (__m256) __builtin_ia32_addps256_mask ((__v8sf) __A,
                                                (__v8sf) __B,
@@ -497,7 +497,7 @@ _mm256_mask_add_ps (__m256 __W, __mmask16 __U, __m256 __A, __m256 __B)
 
 extern __inline __m256
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_maskz_add_ps (__mmask16 __U, __m256 __A, __m256 __B)
+_mm256_maskz_add_ps (__mmask8 __U, __m256 __A, __m256 __B)
 {
   return (__m256) __builtin_ia32_addps256_mask ((__v8sf) __A,
                                                (__v8sf) __B,
@@ -551,7 +551,7 @@ _mm256_maskz_sub_pd (__mmask8 __U, __m256d __A, __m256d __B)
 
 extern __inline __m128
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_mask_sub_ps (__m128 __W, __mmask16 __U, __m128 __A, __m128 __B)
+_mm_mask_sub_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B)
 {
   return (__m128) __builtin_ia32_subps128_mask ((__v4sf) __A,
                                                (__v4sf) __B,
@@ -561,7 +561,7 @@ _mm_mask_sub_ps (__m128 __W, __mmask16 __U, __m128 __A, __m128 __B)
 
 extern __inline __m128
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_maskz_sub_ps (__mmask16 __U, __m128 __A, __m128 __B)
+_mm_maskz_sub_ps (__mmask8 __U, __m128 __A, __m128 __B)
 {
   return (__m128) __builtin_ia32_subps128_mask ((__v4sf) __A,
                                                (__v4sf) __B,
@@ -572,7 +572,7 @@ _mm_maskz_sub_ps (__mmask16 __U, __m128 __A, __m128 __B)
 
 extern __inline __m256
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_mask_sub_ps (__m256 __W, __mmask16 __U, __m256 __A, __m256 __B)
+_mm256_mask_sub_ps (__m256 __W, __mmask8 __U, __m256 __A, __m256 __B)
 {
   return (__m256) __builtin_ia32_subps256_mask ((__v8sf) __A,
                                                (__v8sf) __B,
@@ -582,7 +582,7 @@ _mm256_mask_sub_ps (__m256 __W, __mmask16 __U, __m256 __A, __m256 __B)
 
 extern __inline __m256
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_maskz_sub_ps (__mmask16 __U, __m256 __A, __m256 __B)
+_mm256_maskz_sub_ps (__mmask8 __U, __m256 __A, __m256 __B)
 {
   return (__m256) __builtin_ia32_subps256_mask ((__v8sf) __A,
                                                (__v8sf) __B,
@@ -1320,7 +1320,7 @@ _mm256_mask_cvtepi32_ps (__m256 __W, __mmask8 __U, __m256i __A)
 
 extern __inline __m256
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm256_maskz_cvtepi32_ps (__mmask16 __U, __m256i __A)
+_mm256_maskz_cvtepi32_ps (__mmask8 __U, __m256i __A)
 {
   return (__m256) __builtin_ia32_cvtdq2ps256_mask ((__v8si) __A,
                                                   (__v8sf)
@@ -1339,7 +1339,7 @@ _mm_mask_cvtepi32_ps (__m128 __W, __mmask8 __U, __m128i __A)
 
 extern __inline __m128
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
-_mm_maskz_cvtepi32_ps (__mmask16 __U, __m128i __A)
+_mm_maskz_cvtepi32_ps (__mmask8 __U, __m128i __A)
 {
   return (__m128) __builtin_ia32_cvtdq2ps128_mask ((__v4si) __A,
                                                   (__v4sf)
index b940a39..040470f 100644 (file)
@@ -45,6 +45,7 @@ typedef unsigned int __v4su __attribute__ ((__vector_size__ (16)));
 typedef short __v8hi __attribute__ ((__vector_size__ (16)));
 typedef unsigned short __v8hu __attribute__ ((__vector_size__ (16)));
 typedef char __v16qi __attribute__ ((__vector_size__ (16)));
+typedef signed char __v16qs __attribute__ ((__vector_size__ (16)));
 typedef unsigned char __v16qu __attribute__ ((__vector_size__ (16)));
 
 /* The Intel API is flexible enough that we must allow aliasing with other
@@ -1295,7 +1296,7 @@ _mm_xor_si128 (__m128i __A, __m128i __B)
 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
 _mm_cmpeq_epi8 (__m128i __A, __m128i __B)
 {
-  return (__m128i) ((__v16qi)__A == (__v16qi)__B);
+  return (__m128i) ((__v16qs)__A == (__v16qs)__B);
 }
 
 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
@@ -1313,7 +1314,7 @@ _mm_cmpeq_epi32 (__m128i __A, __m128i __B)
 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
 _mm_cmplt_epi8 (__m128i __A, __m128i __B)
 {
-  return (__m128i) ((__v16qi)__A < (__v16qi)__B);
+  return (__m128i) ((__v16qs)__A < (__v16qs)__B);
 }
 
 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
@@ -1331,7 +1332,7 @@ _mm_cmplt_epi32 (__m128i __A, __m128i __B)
 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
 _mm_cmpgt_epi8 (__m128i __A, __m128i __B)
 {
-  return (__m128i) ((__v16qi)__A > (__v16qi)__B);
+  return (__m128i) ((__v16qs)__A > (__v16qs)__B);
 }
 
 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
index 1b9c63a..c14f7ef 100644 (file)
@@ -90,6 +90,7 @@ BDESC_END (PCMPISTR, SPECIAL_ARGS)
 BDESC_FIRST (special_args, SPECIAL_ARGS,
        0, CODE_FOR_nothing, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, UNKNOWN, (int) UINT64_FTYPE_VOID)
 BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, UNKNOWN, (int) UINT64_FTYPE_PUNSIGNED)
+BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT)
 BDESC (0, CODE_FOR_pause, "__builtin_ia32_pause", IX86_BUILTIN_PAUSE, UNKNOWN, (int) VOID_FTYPE_VOID)
 
 /* 80387 (for use internally for atomic compound assignment).  */
@@ -427,7 +428,6 @@ BDESC_END (SPECIAL_ARGS, ARGS)
 BDESC_FIRST (args, ARGS,
        0, CODE_FOR_bsr, "__builtin_ia32_bsrsi", IX86_BUILTIN_BSRSI, UNKNOWN, (int) INT_FTYPE_INT)
 BDESC (OPTION_MASK_ISA_64BIT, CODE_FOR_bsr_rex64, "__builtin_ia32_bsrdi", IX86_BUILTIN_BSRDI, UNKNOWN, (int) INT64_FTYPE_INT64)
-BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT)
 BDESC (0, CODE_FOR_rotlqi3, "__builtin_ia32_rolqi", IX86_BUILTIN_ROLQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT)
 BDESC (0, CODE_FOR_rotlhi3, "__builtin_ia32_rolhi", IX86_BUILTIN_ROLHI, UNKNOWN, (int) UINT16_FTYPE_UINT16_INT)
 BDESC (0, CODE_FOR_rotrqi3, "__builtin_ia32_rorqi", IX86_BUILTIN_RORQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT)
index 6a2141e..7732f88 100644 (file)
@@ -91,6 +91,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-prop.h"
 #include "ipa-fnsummary.h"
 #include "wide-int-bitmask.h"
+#include "debug.h"
+#include "dwarf2out.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -139,7 +141,6 @@ const struct processor_costs *ix86_cost = NULL;
 #define m_NEHALEM (HOST_WIDE_INT_1U<<PROCESSOR_NEHALEM)
 #define m_SANDYBRIDGE (HOST_WIDE_INT_1U<<PROCESSOR_SANDYBRIDGE)
 #define m_HASWELL (HOST_WIDE_INT_1U<<PROCESSOR_HASWELL)
-#define m_CORE_ALL (m_CORE2 | m_NEHALEM  | m_SANDYBRIDGE | m_HASWELL)
 #define m_BONNELL (HOST_WIDE_INT_1U<<PROCESSOR_BONNELL)
 #define m_SILVERMONT (HOST_WIDE_INT_1U<<PROCESSOR_SILVERMONT)
 #define m_KNL (HOST_WIDE_INT_1U<<PROCESSOR_KNL)
@@ -149,6 +150,10 @@ const struct processor_costs *ix86_cost = NULL;
 #define m_CANNONLAKE (HOST_WIDE_INT_1U<<PROCESSOR_CANNONLAKE)
 #define m_ICELAKE_CLIENT (HOST_WIDE_INT_1U<<PROCESSOR_ICELAKE_CLIENT)
 #define m_ICELAKE_SERVER (HOST_WIDE_INT_1U<<PROCESSOR_ICELAKE_SERVER)
+#define m_CORE_AVX512 (m_SKYLAKE_AVX512 | m_CANNONLAKE \
+                      | m_ICELAKE_CLIENT | m_ICELAKE_SERVER)
+#define m_CORE_AVX2 (m_HASWELL | m_SKYLAKE | m_CORE_AVX512)
+#define m_CORE_ALL (m_CORE2 | m_NEHALEM  | m_SANDYBRIDGE | m_CORE_AVX2)
 #define m_INTEL (HOST_WIDE_INT_1U<<PROCESSOR_INTEL)
 
 #define m_GEODE (HOST_WIDE_INT_1U<<PROCESSOR_GEODE)
@@ -2603,11 +2608,17 @@ rest_of_insert_endbranch (void)
                         TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
       && !cgraph_node::get (cfun->decl)->only_called_directly_p ())
     {
-      cet_eb = gen_nop_endbr ();
+      /* Queue ENDBR insertion to x86_function_profiler.  */
+      if (crtl->profile && flag_fentry)
+       cfun->machine->endbr_queued_at_entrance = true;
+      else
+       {
+         cet_eb = gen_nop_endbr ();
 
-      bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
-      insn = BB_HEAD (bb);
-      emit_insn_before (cet_eb, insn);
+         bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
+         insn = BB_HEAD (bb);
+         emit_insn_before (cet_eb, insn);
+       }
     }
 
   bb = 0;
@@ -4845,8 +4856,14 @@ ix86_option_override_internal (bool main_args_p,
 
   /* Handle stack protector */
   if (!opts_set->x_ix86_stack_protector_guard)
-    opts->x_ix86_stack_protector_guard
-      = TARGET_HAS_BIONIC ? SSP_GLOBAL : SSP_TLS;
+    {
+#ifdef TARGET_THREAD_SSP_OFFSET
+      if (!TARGET_HAS_BIONIC)
+       opts->x_ix86_stack_protector_guard = SSP_TLS;
+      else
+#endif
+       opts->x_ix86_stack_protector_guard = SSP_GLOBAL;
+    }
 
 #ifdef TARGET_THREAD_SSP_OFFSET
   ix86_stack_protector_guard_offset = TARGET_THREAD_SSP_OFFSET;
@@ -8190,7 +8207,7 @@ construct_container (machine_mode mode, machine_mode orig_mode,
       case X86_64_SSEDF_CLASS:
        if (mode != BLKmode)
          return gen_reg_or_parallel (mode, orig_mode,
-                                     SSE_REGNO (sse_regno));
+                                     GET_SSE_REGNO (sse_regno));
        break;
       case X86_64_X87_CLASS:
       case X86_64_COMPLEX_X87_CLASS:
@@ -8206,7 +8223,7 @@ construct_container (machine_mode mode, machine_mode orig_mode,
       && regclass[1] == X86_64_SSEUP_CLASS
       && mode != BLKmode)
     return gen_reg_or_parallel (mode, orig_mode,
-                               SSE_REGNO (sse_regno));
+                               GET_SSE_REGNO (sse_regno));
   if (n == 4
       && regclass[0] == X86_64_SSE_CLASS
       && regclass[1] == X86_64_SSEUP_CLASS
@@ -8214,7 +8231,7 @@ construct_container (machine_mode mode, machine_mode orig_mode,
       && regclass[3] == X86_64_SSEUP_CLASS
       && mode != BLKmode)
     return gen_reg_or_parallel (mode, orig_mode,
-                               SSE_REGNO (sse_regno));
+                               GET_SSE_REGNO (sse_regno));
   if (n == 8
       && regclass[0] == X86_64_SSE_CLASS
       && regclass[1] == X86_64_SSEUP_CLASS
@@ -8226,7 +8243,7 @@ construct_container (machine_mode mode, machine_mode orig_mode,
       && regclass[7] == X86_64_SSEUP_CLASS
       && mode != BLKmode)
     return gen_reg_or_parallel (mode, orig_mode,
-                               SSE_REGNO (sse_regno));
+                               GET_SSE_REGNO (sse_regno));
   if (n == 2
       && regclass[0] == X86_64_X87_CLASS
       && regclass[1] == X86_64_X87UP_CLASS)
@@ -8235,9 +8252,22 @@ construct_container (machine_mode mode, machine_mode orig_mode,
   if (n == 2
       && regclass[0] == X86_64_INTEGER_CLASS
       && regclass[1] == X86_64_INTEGER_CLASS
-      && (mode == CDImode || mode == TImode)
+      && (mode == CDImode || mode == TImode || mode == BLKmode)
       && intreg[0] + 1 == intreg[1])
-    return gen_rtx_REG (mode, intreg[0]);
+    {
+      if (mode == BLKmode)
+       {
+         /* Use TImode for BLKmode values in 2 integer registers.  */
+         exp[0] = gen_rtx_EXPR_LIST (VOIDmode,
+                                     gen_rtx_REG (TImode, intreg[0]),
+                                     GEN_INT (0));
+         ret = gen_rtx_PARALLEL (mode, rtvec_alloc (1));
+         XVECEXP (ret, 0, 0) = exp[0];
+         return ret;
+       }
+      else
+       return gen_rtx_REG (mode, intreg[0]);
+    }
 
   /* Otherwise figure out the entries of the PARALLEL.  */
   for (i = 0; i < n; i++)
@@ -8273,7 +8303,7 @@ construct_container (machine_mode mode, machine_mode orig_mode,
            exp [nexps++]
              = gen_rtx_EXPR_LIST (VOIDmode,
                                   gen_rtx_REG (SFmode,
-                                               SSE_REGNO (sse_regno)),
+                                               GET_SSE_REGNO (sse_regno)),
                                   GEN_INT (i*8));
            sse_regno++;
            break;
@@ -8281,7 +8311,7 @@ construct_container (machine_mode mode, machine_mode orig_mode,
            exp [nexps++]
              = gen_rtx_EXPR_LIST (VOIDmode,
                                   gen_rtx_REG (DFmode,
-                                               SSE_REGNO (sse_regno)),
+                                               GET_SSE_REGNO (sse_regno)),
                                   GEN_INT (i*8));
            sse_regno++;
            break;
@@ -8327,7 +8357,7 @@ construct_container (machine_mode mode, machine_mode orig_mode,
            exp [nexps++]
              = gen_rtx_EXPR_LIST (VOIDmode,
                                   gen_rtx_REG (tmpmode,
-                                               SSE_REGNO (sse_regno)),
+                                               GET_SSE_REGNO (sse_regno)),
                                   GEN_INT (pos*8));
            sse_regno++;
            break;
@@ -9763,7 +9793,7 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
          set_mem_alias_set (mem, set);
          set_mem_align (mem, GET_MODE_ALIGNMENT (smode));
 
-         emit_move_insn (mem, gen_rtx_REG (smode, SSE_REGNO (i)));
+         emit_move_insn (mem, gen_rtx_REG (smode, GET_SSE_REGNO (i)));
        }
 
       emit_label (label);
@@ -10992,6 +11022,23 @@ output_indirect_thunk (enum indirect_thunk_prefix need_prefix,
 
   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
 
+  /* The above call insn pushed a word to stack.  Adjust CFI info.  */
+  if (flag_asynchronous_unwind_tables && dwarf2out_do_frame ())
+    {
+      if (! dwarf2out_do_cfi_asm ())
+       {
+         dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
+         xcfi->dw_cfi_opc = DW_CFA_advance_loc4;
+         xcfi->dw_cfi_oprnd1.dw_cfi_addr = ggc_strdup (indirectlabel2);
+         vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
+       }
+      dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
+      xcfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
+      xcfi->dw_cfi_oprnd1.dw_cfi_offset = 2 * UNITS_PER_WORD;
+      vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
+      dwarf2out_emit_cfi (xcfi);
+    }
+
   if (regno != INVALID_REGNUM)
     {
       /* MOV.  */
@@ -11675,10 +11722,16 @@ ix86_compute_frame_layout (void)
   /* 64-bit MS ABI seem to require stack alignment to be always 16,
      except for function prologues, leaf functions and when the defult
      incoming stack boundary is overriden at command line or via
-     force_align_arg_pointer attribute.  */
-  if ((TARGET_64BIT_MS_ABI && crtl->preferred_stack_boundary < 128)
+     force_align_arg_pointer attribute.
+
+     Darwin's ABI specifies 128b alignment for both 32 and  64 bit variants
+     at call sites, including profile function calls.
+ */
+  if (((TARGET_64BIT_MS_ABI || TARGET_MACHO)
+        && crtl->preferred_stack_boundary < 128)
       && (!crtl->is_leaf || cfun->calls_alloca != 0
          || ix86_current_function_calls_tls_descriptor
+         || (TARGET_MACHO && crtl->profile)
          || ix86_incoming_stack_boundary < 128))
     {
       crtl->preferred_stack_boundary = 128;
@@ -13328,7 +13381,7 @@ ix86_finalize_stack_frame_flags (void)
      is used, but in the end nothing that needed the stack alignment had
      been spilled nor stack access, clear frame_pointer_needed and say we
      don't need stack realignment.  */
-  if ((stack_realign || !flag_omit_frame_pointer)
+  if ((stack_realign || (!flag_omit_frame_pointer && optimize))
       && frame_pointer_needed
       && crtl->is_leaf
       && crtl->sp_is_unchanging
@@ -13435,12 +13488,14 @@ ix86_finalize_stack_frame_flags (void)
          recompute_frame_layout_p = true;
        }
     }
-  else if (crtl->max_used_stack_slot_alignment
-          > crtl->preferred_stack_boundary)
+  else if (crtl->max_used_stack_slot_alignment >= 128)
     {
-      /* We don't need to realign stack.  But we still need to keep
-        stack frame properly aligned to satisfy the largest alignment
-        of stack slots.  */
+      /* We don't need to realign stack.  max_used_stack_alignment is
+        used to decide how stack frame should be aligned.  This is
+        independent of any psABIs nor 32-bit vs 64-bit.  It is always
+        safe to compute max_used_stack_alignment.  We compute it only
+        if 128-bit aligned load/store may be generated on misaligned
+        stack slot which will lead to segfault.   */
       if (ix86_find_max_used_stack_alignment (stack_alignment, true))
        cfun->machine->max_used_stack_alignment
          = stack_alignment / BITS_PER_UNIT;
@@ -14033,8 +14088,9 @@ ix86_expand_prologue (void)
        }
       m->fs.sp_offset += allocate;
 
-      /* Use stack_pointer_rtx for relative addressing so that code
-        works for realigned stack, too.  */
+      /* Use stack_pointer_rtx for relative addressing so that code works for
+        realigned stack.  But this means that we need a blockage to prevent
+        stores based on the frame pointer from being scheduled before.  */
       if (r10_live && eax_live)
         {
          t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
@@ -14043,6 +14099,7 @@ ix86_expand_prologue (void)
          t = plus_constant (Pmode, t, UNITS_PER_WORD);
          emit_move_insn (gen_rtx_REG (word_mode, AX_REG),
                          gen_frame_mem (word_mode, t));
+         emit_insn (gen_memory_blockage ());
        }
       else if (eax_live || r10_live)
        {
@@ -14050,6 +14107,7 @@ ix86_expand_prologue (void)
          emit_move_insn (gen_rtx_REG (word_mode,
                                       (eax_live ? AX_REG : R10_REG)),
                          gen_frame_mem (word_mode, t));
+         emit_insn (gen_memory_blockage ());
        }
     }
   gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset);
@@ -24011,7 +24069,7 @@ ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code code, rtx cmp_op0,
   return true;
 }
 
-/* Expand an sse vector comparison.  Return the register with the result.  */
+/* Expand an SSE comparison.  Return the register with the result.  */
 
 static rtx
 ix86_expand_sse_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1,
@@ -24036,9 +24094,12 @@ ix86_expand_sse_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1,
   else
     cmp_mode = cmp_ops_mode;
 
-
   cmp_op0 = force_reg (cmp_ops_mode, cmp_op0);
-  if (!nonimmediate_operand (cmp_op1, cmp_ops_mode))
+
+  int (*op1_predicate)(rtx, machine_mode)
+    = VECTOR_MODE_P (cmp_ops_mode) ? vector_operand : nonimmediate_operand;
+
+  if (!op1_predicate (cmp_op1, cmp_ops_mode))
     cmp_op1 = force_reg (cmp_ops_mode, cmp_op1);
 
   if (optimize
@@ -24158,7 +24219,7 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false)
       rtx (*gen) (rtx, rtx, rtx, rtx) = NULL;
       rtx d = dest;
 
-      if (!nonimmediate_operand (op_true, mode))
+      if (!vector_operand (op_true, mode))
        op_true = force_reg (mode, op_true);
 
       op_false = force_reg (mode, op_false);
@@ -29982,6 +30043,10 @@ ix86_warn_parameter_passing_abi (cumulative_args_t cum_v, tree type)
   if (!TYPE_EMPTY_P (type))
     return;
 
+  /* Don't warn if the function isn't visible outside of the TU.  */
+  if (cum->decl && !TREE_PUBLIC (cum->decl))
+    return;
+
   const_tree ctx = get_ultimate_context (cum->decl);
   if (ctx != NULL_TREE
       && !TRANSLATION_UNIT_WARN_EMPTY_P (ctx))
@@ -37042,7 +37107,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
 
     case IX86_BUILTIN_RDPID:
 
-      op0 = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
+      op0 = gen_reg_rtx (word_mode);
 
       if (TARGET_64BIT)
        {
@@ -37051,18 +37116,16 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
        }
       else
        insn = gen_rdpid (op0);
+
       emit_insn (insn);
 
-      if (target == 0)
-       {
-         /* mode is VOIDmode if __builtin_rdpid has been called
-            without lhs.  */
-         if (mode == VOIDmode)
-           return target;
-         target = gen_reg_rtx (mode);
-       }
+      if (target == 0
+         || !register_operand (target, SImode))
+       target = gen_reg_rtx (SImode);
+
       emit_move_insn (target, op0);
       return target;
+
     case IX86_BUILTIN_RDPMC:
     case IX86_BUILTIN_RDTSC:
     case IX86_BUILTIN_RDTSCP:
@@ -37121,14 +37184,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
          emit_move_insn (gen_rtx_MEM (SImode, op4), op2);
        }
 
-      if (target == 0)
-       {
-         /* mode is VOIDmode if __builtin_rd* has been called
-            without lhs.  */
-         if (mode == VOIDmode)
-           return target;
-         target = gen_reg_rtx (mode);
-       }
+      if (target == 0
+         || !register_operand (target, DImode))
+        target = gen_reg_rtx (DImode);
 
       if (TARGET_64BIT)
        {
@@ -37217,25 +37275,23 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
       if (!REG_P (op0))
        op0 = copy_to_mode_reg (SImode, op0);
 
+      op1 = force_reg (DImode, op1);
+
       if (TARGET_64BIT)
        {
          op2 = expand_simple_binop (DImode, LSHIFTRT, op1, GEN_INT (32),
                                     NULL, 1, OPTAB_DIRECT);
 
+         icode = CODE_FOR_xsetbv_rex64;
+
          op2 = gen_lowpart (SImode, op2);
          op1 = gen_lowpart (SImode, op1);
-         if (!REG_P (op1))
-           op1 = copy_to_mode_reg (SImode, op1);
-         if (!REG_P (op2))
-           op2 = copy_to_mode_reg (SImode, op2);
-         icode = CODE_FOR_xsetbv_rex64;
          pat = GEN_FCN (icode) (op0, op1, op2);
        }
       else
        {
-         if (!REG_P (op1))
-           op1 = copy_to_mode_reg (DImode, op1);
          icode = CODE_FOR_xsetbv;
+
          pat = GEN_FCN (icode) (op0, op1);
        }
       if (pat)
@@ -37387,6 +37443,16 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
           unsigned char lsb_index = INTVAL (op1) & 0xFF;
           op1 = GEN_INT (length);
           op2 = GEN_INT (lsb_index);
+
+         mode1 = insn_data[icode].operand[1].mode;
+         if (!insn_data[icode].operand[1].predicate (op0, mode1))
+           op0 = copy_to_mode_reg (mode1, op0);
+
+         mode0 = insn_data[icode].operand[0].mode;
+         if (target == 0
+             || !register_operand (target, mode0))
+           target = gen_reg_rtx (mode0);
+
           pat = GEN_FCN (icode) (target, op0, op1, op2);
           if (pat)
             emit_insn (pat);
@@ -41978,6 +42044,10 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
 {
   const char *mcount_name = (flag_fentry ? MCOUNT_NAME_BEFORE_PROLOGUE
                                         : MCOUNT_NAME);
+
+  if (cfun->machine->endbr_queued_at_entrance)
+    fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32");
+
   if (TARGET_64BIT)
     {
 #ifndef NO_PROFILE_COUNTERS
@@ -50684,7 +50754,9 @@ ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
       case E_DFmode:
       /* case E_SCmode: */
       /* case E_DCmode: */
-       break;
+       if (!AGGREGATE_TYPE_P (ret_type))
+         break;
+       /* FALLTHRU */
       default:
        warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
                    "unsupported return type %qT for simd", ret_type);
@@ -50693,25 +50765,34 @@ ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
 
   tree t;
   int i;
+  tree type_arg_types = TYPE_ARG_TYPES (TREE_TYPE (node->decl));
+  bool decl_arg_p = (node->definition || type_arg_types == NULL_TREE);
 
-  for (t = DECL_ARGUMENTS (node->decl), i = 0; t; t = DECL_CHAIN (t), i++)
-    /* FIXME: Shouldn't we allow such arguments if they are uniform?  */
-    switch (TYPE_MODE (TREE_TYPE (t)))
-      {
-      case E_QImode:
-      case E_HImode:
-      case E_SImode:
-      case E_DImode:
-      case E_SFmode:
-      case E_DFmode:
-      /* case E_SCmode: */
-      /* case E_DCmode: */
-       break;
-      default:
-       warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
-                   "unsupported argument type %qT for simd", TREE_TYPE (t));
-       return 0;
-      }
+  for (t = (decl_arg_p ? DECL_ARGUMENTS (node->decl) : type_arg_types), i = 0;
+       t && t != void_list_node; t = TREE_CHAIN (t), i++)
+    {
+      tree arg_type = decl_arg_p ? TREE_TYPE (t) : TREE_VALUE (t);
+      switch (TYPE_MODE (arg_type))
+       {
+       case E_QImode:
+       case E_HImode:
+       case E_SImode:
+       case E_DImode:
+       case E_SFmode:
+       case E_DFmode:
+       /* case E_SCmode: */
+       /* case E_DCmode: */
+         if (!AGGREGATE_TYPE_P (arg_type))
+           break;
+         /* FALLTHRU */
+       default:
+         if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
+           break;
+         warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+                     "unsupported argument type %qT for simd", arg_type);
+         return 0;
+       }
+    }
 
   if (!TREE_PUBLIC (node->decl))
     {
@@ -51286,9 +51367,7 @@ ix86_expand_divmod_libfunc (rtx libfunc, machine_mode mode,
   rtx rem = assign_386_stack_local (mode, SLOT_TEMP);
 
   rtx quot = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
-                                     mode,
-                                     op0, GET_MODE (op0),
-                                     op1, GET_MODE (op1),
+                                     mode, op0, mode, op1, mode,
                                      XEXP (rem, 0), Pmode);
   *quot_p = quot;
   *rem_p = rem;
index 795ad2a..bcefa0e 100644 (file)
@@ -790,8 +790,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 #define PARM_BOUNDARY BITS_PER_WORD
 
 /* Boundary (in *bits*) on which stack pointer should be aligned.  */
-#define STACK_BOUNDARY \
- (TARGET_64BIT && ix86_abi == MS_ABI ? 128 : BITS_PER_WORD)
+#define STACK_BOUNDARY (TARGET_64BIT_MS_ABI ? 128 : BITS_PER_WORD)
 
 /* Stack boundary of the main function guaranteed by OS.  */
 #define MAIN_STACK_BOUNDARY (TARGET_64BIT ? 128 : 32)
@@ -1536,10 +1535,10 @@ enum reg_class
 #define FIRST_FLOAT_REG FIRST_STACK_REG
 #define STACK_TOP_P(X) (REG_P (X) && REGNO (X) == FIRST_FLOAT_REG)
 
-#define SSE_REGNO(N) \
-  ((N) < 8 ? FIRST_SSE_REG + (N) \
-         : (N) <= LAST_REX_SSE_REG ? (FIRST_REX_SSE_REG + (N) - 8) \
-                                   : (FIRST_EXT_REX_SSE_REG + (N) - 16))
+#define GET_SSE_REGNO(N)                       \
+  ((N) < 8 ? FIRST_SSE_REG + (N)               \
+   : (N) < 16 ? FIRST_REX_SSE_REG + (N) - 8    \
+   : FIRST_EXT_REX_SSE_REG + (N) - 16)
 
 /* The class value for index registers, and the one for base regs.  */
 
@@ -2635,6 +2634,9 @@ struct GTY(()) machine_function {
   /* Nonzero if the function places outgoing arguments on stack.  */
   BOOL_BITFIELD outgoing_args_on_stack : 1;
 
+  /* If true, ENDBR is queued at function entrance.  */
+  BOOL_BITFIELD endbr_queued_at_entrance : 1;
+
   /* The largest alignment, in bytes, of stack slot actually used.  */
   unsigned int max_used_stack_alignment;
 
index ad9ccf9..7691160 100644 (file)
   "(peep2_reg_dead_p (3, operands[1])
     || operands_match_p (operands[1], operands[3]))
    && ! reg_overlap_mentioned_p (operands[3], operands[0])
+   && ! reg_overlap_mentioned_p (operands[3], operands[4])
    && ! reg_set_p (operands[3], operands[4])
    && peep2_regno_dead_p (0, FLAGS_REG)"
   [(parallel [(set (match_dup 5) (match_dup 0))
     || operands_match_p (operands[2], operands[4]))
    && ! reg_overlap_mentioned_p (operands[4], operands[0])
    && ! reg_overlap_mentioned_p (operands[4], operands[1])
+   && ! reg_overlap_mentioned_p (operands[4], operands[5])
    && ! reg_set_p (operands[4], operands[5])
    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
    && peep2_regno_dead_p (0, FLAGS_REG)"
   "(peep2_reg_dead_p (3, operands[1])
     || operands_match_p (operands[1], operands[3]))
    && ! reg_overlap_mentioned_p (operands[3], operands[0])
+   && ! reg_overlap_mentioned_p (operands[3], operands[4])
    && ! reg_set_p (operands[3], operands[4])
    && peep2_regno_dead_p (0, FLAGS_REG)"
   [(parallel [(set (match_dup 5) (match_dup 0))
     || operands_match_p (operands[2], operands[4]))
    && ! reg_overlap_mentioned_p (operands[4], operands[0])
    && ! reg_overlap_mentioned_p (operands[4], operands[1])
+   && ! reg_overlap_mentioned_p (operands[4], operands[5])
    && ! reg_set_p (operands[4], operands[5])
    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
    && peep2_regno_dead_p (0, FLAGS_REG)"
      stack address we wish to restore.  */
   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
-  tmp = gen_rtx_MEM (Pmode, tmp);
+  /* Return address is always in word_mode.  */
+  tmp = gen_rtx_MEM (word_mode, tmp);
+  if (GET_MODE (ra) != word_mode)
+    ra = convert_to_mode (word_mode, ra, 1);
   emit_move_insn (tmp, ra);
 
   emit_jump_insn (gen_eh_return_internal ());
 
 (define_insn "sse4_1_round<mode>2"
   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
-       (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
+       (unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm")
                       (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
                      UNSPEC_ROUND))]
   "TARGET_SSE4_1"
                                 FIST_ROUNDING))
              (clobber (reg:CC FLAGS_REG))])]
   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
-   && !flag_trapping_math"
+   && (TARGET_SSE4_1 || !flag_trapping_math)"
 {
-  if (TARGET_64BIT && optimize_insn_for_size_p ())
-    FAIL;
+  if (TARGET_SSE4_1)
+    {
+      rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
 
-  if (ROUND_<ROUNDING> == ROUND_FLOOR)
+      emit_insn (gen_sse4_1_round<mode>2
+                (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
+                                            | ROUND_NO_EXC)));
+      emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
+                (operands[0], tmp));
+    }
+  else if (ROUND_<ROUNDING> == ROUND_FLOOR)
     ix86_expand_lfloorceil (operands[0], operands[1], true);
   else if (ROUND_<ROUNDING> == ROUND_CEIL)
     ix86_expand_lfloorceil (operands[0], operands[1], false);
                       const0_rtx);
 })
 
+;; Likewise for cmpelim optimized pattern.
+(define_peephole2
+  [(set (match_operand:SWI 0 "register_operand")
+       (match_operand:SWI 1 "memory_operand"))
+   (parallel [(set (reg FLAGS_REG)
+                  (compare (match_operator:SWI 3 "plusminuslogic_operator"
+                             [(match_dup 0)
+                              (match_operand:SWI 2 "<nonmemory_operand>")])
+                           (const_int 0)))
+             (set (match_dup 0) (match_dup 3))])
+   (set (match_dup 1) (match_dup 0))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && peep2_reg_dead_p (3, operands[0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])
+   && ix86_match_ccmode (peep2_next_insn (1),
+                        (GET_CODE (operands[3]) == PLUS
+                         || GET_CODE (operands[3]) == MINUS)
+                        ? CCGOCmode : CCNOmode)"
+  [(parallel [(set (match_dup 4) (match_dup 6))
+             (set (match_dup 1) (match_dup 5))])]
+{
+  operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
+  operands[5]
+    = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
+                     copy_rtx (operands[1]), operands[2]);
+  operands[6]
+    = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
+                      const0_rtx);
+})
+
 ;; Likewise for instances where we have a lea pattern.
 (define_peephole2
   [(set (match_operand:SWI 0 "register_operand")
    (set (match_dup 1) (match_dup 0))
    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
-   && GET_CODE (operands[2]) != MINUS
+   && COMMUTATIVE_ARITH_P (operands[2])
    && peep2_reg_dead_p (3, operands[0])
    && !reg_overlap_mentioned_p (operands[0], operands[1])
    && ix86_match_ccmode (peep2_next_insn (2),
                       const0_rtx);
 })
 
+;; Likewise for cmpelim optimized pattern.
+(define_peephole2
+  [(parallel [(set (reg FLAGS_REG)
+                  (compare (match_operator:SWI 2 "plusminuslogic_operator"
+                             [(match_operand:SWI 0 "register_operand")
+                              (match_operand:SWI 1 "memory_operand")])
+                           (const_int 0)))
+             (set (match_dup 0) (match_dup 2))])
+   (set (match_dup 1) (match_dup 0))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && COMMUTATIVE_ARITH_P (operands[2])
+   && peep2_reg_dead_p (2, operands[0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && ix86_match_ccmode (peep2_next_insn (0),
+                        GET_CODE (operands[2]) == PLUS
+                        ? CCGOCmode : CCNOmode)"
+  [(parallel [(set (match_dup 3) (match_dup 5))
+             (set (match_dup 1) (match_dup 4))])]
+{
+  operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
+  operands[4]
+    = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
+                     copy_rtx (operands[1]), operands[0]);
+  operands[5]
+    = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
+                      const0_rtx);
+})
+
 (define_peephole2
   [(set (match_operand:SWI12 0 "register_operand")
        (match_operand:SWI12 1 "memory_operand"))
 (define_expand "stack_protect_set"
   [(match_operand 0 "memory_operand")
    (match_operand 1 "memory_operand")]
-  "TARGET_SSP_TLS_GUARD"
+  ""
 {
   rtx (*insn)(rtx, rtx);
 
                    UNSPEC_SP_SET))
    (set (match_scratch:PTR 2 "=&r") (const_int 0))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_SSP_TLS_GUARD"
+  ""
   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
   [(set_attr "type" "multi")])
 
   [(match_operand 0 "memory_operand")
    (match_operand 1 "memory_operand")
    (match_operand 2)]
-  "TARGET_SSP_TLS_GUARD"
+  ""
 {
   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
 
                     (match_operand:PTR 2 "memory_operand" "m")]
                    UNSPEC_SP_TEST))
    (clobber (match_scratch:PTR 3 "=&r"))]
-  "TARGET_SSP_TLS_GUARD"
+  ""
   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
   [(set_attr "type" "multi")])
 
index f6cdc86..211f7ee 100644 (file)
          rtx op1 = XEXP (XEXP (op, 0), 0);
          rtx op2 = XEXP (XEXP (op, 0), 1);
 
-         if (ix86_cmodel == CM_LARGE)
+         if (ix86_cmodel == CM_LARGE && GET_CODE (op1) != UNSPEC)
            return false;
          if (!CONST_INT_P (op2))
            return false;
       if (GET_CODE (elt) != SET
          || GET_CODE (SET_DEST (elt)) != REG
          || GET_MODE (SET_DEST (elt)) != V8SImode
-         || REGNO (SET_DEST (elt)) != SSE_REGNO (i)
+         || REGNO (SET_DEST (elt)) != GET_SSE_REGNO (i)
          || SET_SRC (elt) != CONST0_RTX (V8SImode))
        return false;
     }
index 640971d..d5cab80 100644 (file)
@@ -21,6 +21,9 @@
   ;; SSE
   UNSPEC_MOVNT
 
+  ;; SSE2
+  UNSPEC_MOVDI_TO_SSE
+
   ;; SSE3
   UNSPEC_LDDQU
 
 ;; from there.
 
 (define_insn_and_split "movdi_to_sse"
-  [(parallel
-    [(set (match_operand:V4SI 0 "register_operand" "=?x,x")
-         (subreg:V4SI (match_operand:DI 1 "nonimmediate_operand" "r,m") 0))
-     (clobber (match_scratch:V4SI 2 "=&x,X"))])]
+  [(set (match_operand:V4SI 0 "register_operand" "=?x,x")
+       (unspec:V4SI [(match_operand:DI 1 "nonimmediate_operand" "r,m")]
+                    UNSPEC_MOVDI_TO_SSE))
+     (clobber (match_scratch:V4SI 2 "=&x,X"))]
   "!TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
   "#"
   "&& reload_completed"
                                             operands[2]));
    }
  else if (memory_operand (operands[1], DImode))
-   {
-     rtx tmp = gen_reg_rtx (V2DImode);
-     emit_insn (gen_vec_concatv2di (tmp, operands[1], const0_rtx));
-     emit_move_insn (operands[0], gen_lowpart (V4SImode, tmp));
-   }
+   emit_insn (gen_vec_concatv2di (gen_lowpart (V2DImode, operands[0]),
+                                 operands[1], const0_rtx));
  else
    gcc_unreachable ();
  DONE;
          (match_operand:VF_128 1 "register_operand" "v")
          (const_int 1)))]
   "TARGET_AVX512F && TARGET_64BIT"
-  "vcvtusi2<ssescalarmodesuffix>\t{%2, <round_op3>%1, %0|%0, %1<round_op3>, %2}"
+  "vcvtusi2<ssescalarmodesuffix>{q}\t{%2, <round_op3>%1, %0|%0, %1<round_op3>, %2}"
   [(set_attr "type" "sseicvt")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<ssescalarmode>")])
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (define_insn "sse2_cvtpi2pd"
-  [(set (match_operand:V2DF 0 "register_operand" "=x,x")
-       (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "y,m")))]
+  [(set (match_operand:V2DF 0 "register_operand" "=v,x")
+       (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "vBm,?!y")))]
   "TARGET_SSE2"
-  "cvtpi2pd\t{%1, %0|%0, %1}"
+  "@
+   %vcvtdq2pd\t{%1, %0|%0, %1}
+   cvtpi2pd\t{%1, %0|%0, %1}"
   [(set_attr "type" "ssecvt")
-   (set_attr "unit" "mmx,*")
-   (set_attr "prefix_data16" "1,*")
+   (set_attr "unit" "*,mmx")
+   (set_attr "prefix_data16" "*,1")
+   (set_attr "prefix" "maybe_vex,*")
    (set_attr "mode" "V2DF")])
 
 (define_insn "sse2_cvtpd2pi"
-  [(set (match_operand:V2SI 0 "register_operand" "=y")
-       (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
+  [(set (match_operand:V2SI 0 "register_operand" "=v,?!y")
+       (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "vBm,xm")]
                     UNSPEC_FIX_NOTRUNC))]
   "TARGET_SSE2"
-  "cvtpd2pi\t{%1, %0|%0, %1}"
+  "@
+   * return TARGET_AVX ? \"vcvtpd2dq{x}\t{%1, %0|%0, %1}\" : \"cvtpd2dq\t{%1, %0|%0, %1}\";
+   cvtpd2pi\t{%1, %0|%0, %1}"
   [(set_attr "type" "ssecvt")
-   (set_attr "unit" "mmx")
+   (set_attr "unit" "*,mmx")
+   (set_attr "amdfam10_decode" "double")
+   (set_attr "athlon_decode" "vector")
    (set_attr "bdver1_decode" "double")
-   (set_attr "btver2_decode" "direct")
-   (set_attr "prefix_data16" "1")
-   (set_attr "mode" "DI")])
+   (set_attr "prefix_data16" "*,1")
+   (set_attr "prefix" "maybe_vex,*")
+   (set_attr "mode" "TI")])
 
 (define_insn "sse2_cvttpd2pi"
-  [(set (match_operand:V2SI 0 "register_operand" "=y")
-       (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V2SI 0 "register_operand" "=v,?!y")
+       (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "vBm,xm")))]
   "TARGET_SSE2"
-  "cvttpd2pi\t{%1, %0|%0, %1}"
+  "@
+   * return TARGET_AVX ? \"vcvttpd2dq{x}\t{%1, %0|%0, %1}\" : \"cvttpd2dq\t{%1, %0|%0, %1}\";
+   cvttpd2pi\t{%1, %0|%0, %1}"
   [(set_attr "type" "ssecvt")
-   (set_attr "unit" "mmx")
+   (set_attr "unit" "*,mmx")
+   (set_attr "amdfam10_decode" "double")
+   (set_attr "athlon_decode" "vector")
    (set_attr "bdver1_decode" "double")
-   (set_attr "prefix_data16" "1")
+   (set_attr "prefix_data16" "*,1")
+   (set_attr "prefix" "maybe_vex,*")
    (set_attr "mode" "TI")])
 
 (define_insn "sse2_cvtsi2sd"
          (vec_concat:<ssedoublemode>
            (match_operand:VI8F_256 1 "register_operand" "v")
            (match_operand:VI8F_256 2 "nonimmediate_operand" "vm"))
-         (parallel [(match_operand 3  "const_0_to_3_operand")
-                    (match_operand 4  "const_0_to_3_operand")
-                    (match_operand 5  "const_4_to_7_operand")
-                    (match_operand 6  "const_4_to_7_operand")])))]
+         (parallel [(match_operand 3 "const_0_to_3_operand")
+                    (match_operand 4 "const_0_to_3_operand")
+                    (match_operand 5 "const_4_to_7_operand")
+                    (match_operand 6 "const_4_to_7_operand")])))]
   "TARGET_AVX512VL
-   && (INTVAL (operands[3]) == (INTVAL (operands[4]) - 1)
-       && INTVAL (operands[5]) == (INTVAL (operands[6]) - 1))"
+   && (INTVAL (operands[3]) & 1) == 0
+   && INTVAL (operands[3]) == INTVAL (operands[4]) - 1
+   && (INTVAL (operands[5]) & 1) == 0
+   && INTVAL (operands[5]) == INTVAL (operands[6]) - 1"
 {
   int mask;
   mask = INTVAL (operands[3]) / 2;
          (vec_concat:<ssedoublemode>
            (match_operand:V8FI 1 "register_operand" "v")
            (match_operand:V8FI 2 "nonimmediate_operand" "vm"))
-         (parallel [(match_operand 3  "const_0_to_7_operand")
-                    (match_operand 4  "const_0_to_7_operand")
-                    (match_operand 5  "const_0_to_7_operand")
-                    (match_operand 6  "const_0_to_7_operand")
-                    (match_operand 7  "const_8_to_15_operand")
-                    (match_operand 8  "const_8_to_15_operand")
-                    (match_operand 9  "const_8_to_15_operand")
-                    (match_operand 10  "const_8_to_15_operand")])))]
+         (parallel [(match_operand 3 "const_0_to_7_operand")
+                    (match_operand 4 "const_0_to_7_operand")
+                    (match_operand 5 "const_0_to_7_operand")
+                    (match_operand 6 "const_0_to_7_operand")
+                    (match_operand 7 "const_8_to_15_operand")
+                    (match_operand 8 "const_8_to_15_operand")
+                    (match_operand 9 "const_8_to_15_operand")
+                    (match_operand 10 "const_8_to_15_operand")])))]
   "TARGET_AVX512F
-   && (INTVAL (operands[3]) == (INTVAL (operands[4]) - 1)
-       && INTVAL (operands[5]) == (INTVAL (operands[6]) - 1)
-       && INTVAL (operands[7]) == (INTVAL (operands[8]) - 1)
-       && INTVAL (operands[9]) == (INTVAL (operands[10]) - 1))"
+   && (INTVAL (operands[3]) & 1) == 0
+   && INTVAL (operands[3]) == INTVAL (operands[4]) - 1
+   && (INTVAL (operands[5]) & 1) == 0
+   && INTVAL (operands[5]) == INTVAL (operands[6]) - 1
+   && (INTVAL (operands[7]) & 1) == 0
+   && INTVAL (operands[7]) == INTVAL (operands[8]) - 1
+   && (INTVAL (operands[9]) & 1) == 0
+   && INTVAL (operands[9]) == INTVAL (operands[10]) - 1"
 {
   int mask;
   mask = INTVAL (operands[3]) / 2;
          (vec_concat:<ssedoublemode>
            (match_operand:VI4F_256 1 "register_operand" "v")
            (match_operand:VI4F_256 2 "nonimmediate_operand" "vm"))
-         (parallel [(match_operand 3  "const_0_to_7_operand")
-                    (match_operand 4  "const_0_to_7_operand")
-                    (match_operand 5  "const_0_to_7_operand")
-                    (match_operand 6  "const_0_to_7_operand")
-                    (match_operand 7  "const_8_to_15_operand")
-                    (match_operand 8  "const_8_to_15_operand")
-                    (match_operand 9  "const_8_to_15_operand")
+         (parallel [(match_operand 3 "const_0_to_7_operand")
+                    (match_operand 4 "const_0_to_7_operand")
+                    (match_operand 5 "const_0_to_7_operand")
+                    (match_operand 6 "const_0_to_7_operand")
+                    (match_operand 7 "const_8_to_15_operand")
+                    (match_operand 8 "const_8_to_15_operand")
+                    (match_operand 9 "const_8_to_15_operand")
                     (match_operand 10 "const_8_to_15_operand")])))]
   "TARGET_AVX512VL
-   && (INTVAL (operands[3]) == (INTVAL (operands[4]) - 1)
-       && INTVAL (operands[3]) == (INTVAL (operands[5]) - 2)
-       && INTVAL (operands[3]) == (INTVAL (operands[6]) - 3)
-       && INTVAL (operands[7]) == (INTVAL (operands[8]) - 1)
-       && INTVAL (operands[7]) == (INTVAL (operands[9]) - 2)
-       && INTVAL (operands[7]) == (INTVAL (operands[10]) - 3))"
+   && (INTVAL (operands[3]) & 3) == 0
+   && INTVAL (operands[3]) == INTVAL (operands[4]) - 1
+   && INTVAL (operands[3]) == INTVAL (operands[5]) - 2
+   && INTVAL (operands[3]) == INTVAL (operands[6]) - 3
+   && (INTVAL (operands[7]) & 3) == 0
+   && INTVAL (operands[7]) == INTVAL (operands[8]) - 1
+   && INTVAL (operands[7]) == INTVAL (operands[9]) - 2
+   && INTVAL (operands[7]) == INTVAL (operands[10]) - 3"
 {
   int mask;
   mask = INTVAL (operands[3]) / 4;
          (vec_concat:<ssedoublemode>
            (match_operand:V16FI 1 "register_operand" "v")
            (match_operand:V16FI 2 "nonimmediate_operand" "vm"))
-         (parallel [(match_operand 3  "const_0_to_15_operand")
-                    (match_operand 4  "const_0_to_15_operand")
-                    (match_operand 5  "const_0_to_15_operand")
-                    (match_operand 6  "const_0_to_15_operand")
-                    (match_operand 7  "const_0_to_15_operand")
-                    (match_operand 8  "const_0_to_15_operand")
-                    (match_operand 9  "const_0_to_15_operand")
-                    (match_operand 10  "const_0_to_15_operand")
-                    (match_operand 11  "const_16_to_31_operand")
-                    (match_operand 12  "const_16_to_31_operand")
-                    (match_operand 13  "const_16_to_31_operand")
-                    (match_operand 14  "const_16_to_31_operand")
-                    (match_operand 15  "const_16_to_31_operand")
-                    (match_operand 16  "const_16_to_31_operand")
-                    (match_operand 17  "const_16_to_31_operand")
-                    (match_operand 18  "const_16_to_31_operand")])))]
+         (parallel [(match_operand 3 "const_0_to_15_operand")
+                    (match_operand 4 "const_0_to_15_operand")
+                    (match_operand 5 "const_0_to_15_operand")
+                    (match_operand 6 "const_0_to_15_operand")
+                    (match_operand 7 "const_0_to_15_operand")
+                    (match_operand 8 "const_0_to_15_operand")
+                    (match_operand 9 "const_0_to_15_operand")
+                    (match_operand 10 "const_0_to_15_operand")
+                    (match_operand 11 "const_16_to_31_operand")
+                    (match_operand 12 "const_16_to_31_operand")
+                    (match_operand 13 "const_16_to_31_operand")
+                    (match_operand 14 "const_16_to_31_operand")
+                    (match_operand 15 "const_16_to_31_operand")
+                    (match_operand 16 "const_16_to_31_operand")
+                    (match_operand 17 "const_16_to_31_operand")
+                    (match_operand 18 "const_16_to_31_operand")])))]
   "TARGET_AVX512F
-   && (INTVAL (operands[3]) == (INTVAL (operands[4]) - 1)
-       && INTVAL (operands[3]) == (INTVAL (operands[5]) - 2)
-       && INTVAL (operands[3]) == (INTVAL (operands[6]) - 3)
-       && INTVAL (operands[7]) == (INTVAL (operands[8]) - 1)
-       && INTVAL (operands[7]) == (INTVAL (operands[9]) - 2)
-       && INTVAL (operands[7]) == (INTVAL (operands[10]) - 3)
-       && INTVAL (operands[11]) == (INTVAL (operands[12]) - 1)
-       && INTVAL (operands[11]) == (INTVAL (operands[13]) - 2)
-       && INTVAL (operands[11]) == (INTVAL (operands[14]) - 3)
-       && INTVAL (operands[15]) == (INTVAL (operands[16]) - 1)
-       && INTVAL (operands[15]) == (INTVAL (operands[17]) - 2)
-       && INTVAL (operands[15]) == (INTVAL (operands[18]) - 3))"
+   && (INTVAL (operands[3]) & 3) == 0
+   && INTVAL (operands[3]) == INTVAL (operands[4]) - 1
+   && INTVAL (operands[3]) == INTVAL (operands[5]) - 2
+   && INTVAL (operands[3]) == INTVAL (operands[6]) - 3
+   && (INTVAL (operands[7]) & 3) == 0
+   && INTVAL (operands[7]) == INTVAL (operands[8]) - 1
+   && INTVAL (operands[7]) == INTVAL (operands[9]) - 2
+   && INTVAL (operands[7]) == INTVAL (operands[10]) - 3
+   && (INTVAL (operands[11]) & 3) == 0
+   && INTVAL (operands[11]) == INTVAL (operands[12]) - 1
+   && INTVAL (operands[11]) == INTVAL (operands[13]) - 2
+   && INTVAL (operands[11]) == INTVAL (operands[14]) - 3
+   && (INTVAL (operands[15]) & 3) == 0
+   && INTVAL (operands[15]) == INTVAL (operands[16]) - 1
+   && INTVAL (operands[15]) == INTVAL (operands[17]) - 2
+   && INTVAL (operands[15]) == INTVAL (operands[18]) - 3"
 {
   int mask;
   mask = INTVAL (operands[3]) / 4;
   switch (INTVAL (operands[4]))
     {
     case 3:
-      return "vgatherpf0<ssemodesuffix>ps\t{%5%{%0%}|%5%{%0%}}";
+      /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+        gas changed what it requires incompatibly.  */
+      return "vgatherpf0<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
     case 2:
-      return "vgatherpf1<ssemodesuffix>ps\t{%5%{%0%}|%5%{%0%}}";
+      return "vgatherpf1<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
     default:
       gcc_unreachable ();
     }
   switch (INTVAL (operands[4]))
     {
     case 3:
-      return "vgatherpf0<ssemodesuffix>pd\t{%5%{%0%}|%5%{%0%}}";
+      /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+        gas changed what it requires incompatibly.  */
+      return "vgatherpf0<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
     case 2:
-      return "vgatherpf1<ssemodesuffix>pd\t{%5%{%0%}|%5%{%0%}}";
+      return "vgatherpf1<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
     default:
       gcc_unreachable ();
     }
     {
     case 3:
     case 7:
-      return "vscatterpf0<ssemodesuffix>ps\t{%5%{%0%}|%5%{%0%}}";
+      /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+        gas changed what it requires incompatibly.  */
+      return "vscatterpf0<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
     case 2:
     case 6:
-      return "vscatterpf1<ssemodesuffix>ps\t{%5%{%0%}|%5%{%0%}}";
+      return "vscatterpf1<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
     default:
       gcc_unreachable ();
     }
     {
     case 3:
     case 7:
-      return "vscatterpf0<ssemodesuffix>pd\t{%5%{%0%}|%5%{%0%}}";
+      /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+        gas changed what it requires incompatibly.  */
+      return "vscatterpf0<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
     case 2:
     case 6:
-      return "vscatterpf1<ssemodesuffix>pd\t{%5%{%0%}|%5%{%0%}}";
+      return "vscatterpf1<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
     default:
       gcc_unreachable ();
     }
 
   for (regno = 0; regno < nregs; regno++)
     XVECEXP (operands[0], 0, regno + 1)
-      = gen_rtx_SET (gen_rtx_REG (V8SImode, SSE_REGNO (regno)),
+      = gen_rtx_SET (gen_rtx_REG (V8SImode, GET_SSE_REGNO (regno)),
                     CONST0_RTX (V8SImode));
 })
 
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
 
-;; Memory operand override for -masm=intel of the v*gatherq* patterns.
-(define_mode_attr gatherq_mode
-  [(V4SI "q") (V2DI "x") (V4SF "q") (V2DF "x")
-   (V8SI "x") (V4DI "t") (V8SF "x") (V4DF "t")
-   (V16SI "t") (V8DI "g") (V16SF "t") (V8DF "g")])
-
 (define_expand "<avx512>_gathersi<mode>"
   [(parallel [(set (match_operand:VI48F 0 "register_operand")
                   (unspec:VI48F
          UNSPEC_GATHER))
    (clobber (match_scratch:<avx512fmaskmode> 2 "=&Yk"))]
   "TARGET_AVX512F"
-  "v<sseintprefix>gatherd<ssemodesuffix>\t{%6, %0%{%2%}|%0%{%2%}, %<xtg_mode>6}"
+;; %X6 so that we don't emit any *WORD PTR for -masm=intel, as
+;; gas changed what it requires incompatibly.
+  "v<sseintprefix>gatherd<ssemodesuffix>\t{%6, %0%{%2%}|%0%{%2%}, %X6}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
          UNSPEC_GATHER))
    (clobber (match_scratch:<avx512fmaskmode> 1 "=&Yk"))]
   "TARGET_AVX512F"
-  "v<sseintprefix>gatherd<ssemodesuffix>\t{%5, %0%{%1%}|%0%{%1%}, %<xtg_mode>5}"
+;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+;; gas changed what it requires incompatibly.
+  "v<sseintprefix>gatherd<ssemodesuffix>\t{%5, %0%{%1%}|%0%{%1%}, %X5}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
          UNSPEC_GATHER))
    (clobber (match_scratch:QI 2 "=&Yk"))]
   "TARGET_AVX512F"
-{
-  return "v<sseintprefix>gatherq<ssemodesuffix>\t{%6, %1%{%2%}|%1%{%2%}, %<gatherq_mode>6}";
-}
+;; %X6 so that we don't emit any *WORD PTR for -masm=intel, as
+;; gas changed what it requires incompatibly.
+  "v<sseintprefix>gatherq<ssemodesuffix>\t{%6, %1%{%2%}|%1%{%2%}, %X6}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
    (clobber (match_scratch:QI 1 "=&Yk"))]
   "TARGET_AVX512F"
 {
+  /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+     gas changed what it requires incompatibly.  */
   if (<MODE>mode != <VEC_GATHER_SRCDI>mode)
     {
       if (<MODE_SIZE> != 64)
-       return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %x0%{%1%}|%x0%{%1%}, %<gatherq_mode>5}";
+       return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %x0%{%1%}|%x0%{%1%}, %X5}";
       else
-       return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %t0%{%1%}|%t0%{%1%}, %t5}";
+       return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %t0%{%1%}|%t0%{%1%}, %X5}";
     }
-  return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %0%{%1%}|%0%{%1%}, %<gatherq_mode>5}";
+  return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %0%{%1%}|%0%{%1%}, %X5}";
 }
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
          UNSPEC_SCATTER))
    (clobber (match_scratch:<avx512fmaskmode> 1 "=&Yk"))]
   "TARGET_AVX512F"
-  "v<sseintprefix>scatterd<ssemodesuffix>\t{%3, %5%{%1%}|%5%{%1%}, %3}"
+;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+;; gas changed what it requires incompatibly.
+  "v<sseintprefix>scatterd<ssemodesuffix>\t{%3, %5%{%1%}|%X5%{%1%}, %3}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
          UNSPEC_SCATTER))
    (clobber (match_scratch:QI 1 "=&Yk"))]
   "TARGET_AVX512F"
-{
-  if (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)) == 8)
-    return "v<sseintprefix>scatterq<ssemodesuffix>\t{%3, %5%{%1%}|%5%{%1%}, %3}";
-  return "v<sseintprefix>scatterq<ssemodesuffix>\t{%3, %5%{%1%}|%t5%{%1%}, %3}";
-}
+;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+;; gas changed what it requires incompatibly.
+  "v<sseintprefix>scatterq<ssemodesuffix>\t{%3, %5%{%1%}|%X5%{%1%}, %3}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
index c70c503..3fafa42 100644 (file)
@@ -78,9 +78,9 @@ _mm_clmulepi64_epi128 (__m128i __A, __m128i __B, const int __C)
 #pragma GCC pop_options
 #endif /* __DISABLE_VPCLMULQDQVL__ */
 
-#if !defined(__VPCLMULQDQ__) || !defined(__AVX512VL__)
+#if !defined(__VPCLMULQDQ__) || !defined(__AVX__)
 #pragma GCC push_options
-#pragma GCC target("vpclmulqdq,avx512vl")
+#pragma GCC target("vpclmulqdq,avx")
 #define __DISABLE_VPCLMULQDQ__
 #endif /* __VPCLMULQDQ__ */
 
@@ -103,6 +103,4 @@ _mm256_clmulepi64_epi128 (__m256i __A, __m256i __B, const int __C)
 #pragma GCC pop_options
 #endif /* __DISABLE_VPCLMULQDQ__ */
 
-
 #endif /* _VPCLMULQDQINTRIN_H_INCLUDED */
-
index 5649fdc..c99e45c 100644 (file)
@@ -48,9 +48,9 @@ DEF_TUNE (X86_TUNE_SCHEDULE, "schedule",
    over partial stores.  For example preffer MOVZBL or MOVQ to load 8bit
    value over movb.  */
 DEF_TUNE (X86_TUNE_PARTIAL_REG_DEPENDENCY, "partial_reg_dependency",
-          m_P4_NOCONA | m_CORE2 | m_NEHALEM  | m_SANDYBRIDGE
+          m_P4_NOCONA | m_CORE2 | m_NEHALEM  | m_SANDYBRIDGE | m_CORE_AVX2
          | m_BONNELL | m_SILVERMONT | m_INTEL
-         | m_KNL | m_KNM | m_AMD_MULTIPLE | m_SKYLAKE_AVX512 | m_GENERIC)
+         | m_KNL | m_KNM | m_AMD_MULTIPLE | m_GENERIC)
 
 /* X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY: This knob promotes all store
    destinations to be 128bit to allow register renaming on 128bit SSE units,
@@ -84,8 +84,8 @@ DEF_TUNE (X86_TUNE_PARTIAL_FLAG_REG_STALL, "partial_flag_reg_stall",
    partial dependencies.  */
 DEF_TUNE (X86_TUNE_MOVX, "movx",
           m_PPRO | m_P4_NOCONA | m_CORE2 | m_NEHALEM  | m_SANDYBRIDGE
-         | m_BONNELL | m_SILVERMONT | m_KNL | m_KNM | m_INTEL
-         | m_GEODE | m_AMD_MULTIPLE | m_SKYLAKE_AVX512 | m_GENERIC)
+         | m_BONNELL | m_SILVERMONT | m_KNL | m_KNM | m_INTEL | m_CORE_AVX2
+         | m_GEODE | m_AMD_MULTIPLE | m_GENERIC)
 
 /* X86_TUNE_MEMORY_MISMATCH_STALL: Avoid partial stores that are followed by
    full sized loads.  */
@@ -101,19 +101,19 @@ DEF_TUNE (X86_TUNE_FUSE_CMP_AND_BRANCH_32, "fuse_cmp_and_branch_32",
 /* X86_TUNE_FUSE_CMP_AND_BRANCH_64: Fuse compare with a subsequent
    conditional jump instruction for TARGET_64BIT.  */
 DEF_TUNE (X86_TUNE_FUSE_CMP_AND_BRANCH_64, "fuse_cmp_and_branch_64",
-         m_NEHALEM | m_SANDYBRIDGE | m_HASWELL | m_BDVER | m_ZNVER1 | m_GENERIC)
+         m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_BDVER | m_ZNVER1 | m_GENERIC)
 
 /* X86_TUNE_FUSE_CMP_AND_BRANCH_SOFLAGS: Fuse compare with a
    subsequent conditional jump instruction when the condition jump
    check sign flag (SF) or overflow flag (OF).  */
 DEF_TUNE (X86_TUNE_FUSE_CMP_AND_BRANCH_SOFLAGS, "fuse_cmp_and_branch_soflags",
-         m_NEHALEM | m_SANDYBRIDGE | m_HASWELL | m_BDVER | m_ZNVER1 | m_GENERIC)
+         m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_BDVER | m_ZNVER1 | m_GENERIC)
 
 /* X86_TUNE_FUSE_ALU_AND_BRANCH: Fuse alu with a subsequent conditional
    jump instruction when the alu instruction produces the CCFLAG consumed by
    the conditional jump instruction. */
 DEF_TUNE (X86_TUNE_FUSE_ALU_AND_BRANCH, "fuse_alu_and_branch",
-          m_SANDYBRIDGE | m_HASWELL | m_GENERIC)
+          m_SANDYBRIDGE | m_CORE_AVX2 | m_GENERIC)
 
 
 /*****************************************************************************/
@@ -286,7 +286,7 @@ DEF_TUNE (X86_TUNE_USE_BT, "use_bt",
 /* X86_TUNE_AVOID_FALSE_DEP_FOR_BMI: Avoid false dependency
    for bit-manipulation instructions.  */
 DEF_TUNE (X86_TUNE_AVOID_FALSE_DEP_FOR_BMI, "avoid_false_dep_for_bmi",
-         m_SANDYBRIDGE | m_HASWELL | m_GENERIC)
+         m_SANDYBRIDGE | m_CORE_AVX2 | m_GENERIC)
 
 /* X86_TUNE_ADJUST_UNROLL: This enables adjusting the unroll factor based
    on hardware capabilities. Bdver3 hardware has a loop buffer which makes
@@ -335,15 +335,15 @@ DEF_TUNE (X86_TUNE_GENERAL_REGS_SSE_SPILL, "general_regs_sse_spill",
 /* X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL: Use movups for misaligned loads instead
    of a sequence loading registers by parts.  */
 DEF_TUNE (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL, "sse_unaligned_load_optimal",
-         m_NEHALEM | m_SANDYBRIDGE | m_HASWELL | m_SILVERMONT | m_KNL | m_KNM
-         | m_INTEL | m_SKYLAKE_AVX512 | m_AMDFAM10 | m_BDVER | m_BTVER
+         m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_SILVERMONT | m_KNL | m_KNM
+         | m_INTEL | m_AMDFAM10 | m_BDVER | m_BTVER
          | m_ZNVER1 | m_GENERIC)
 
 /* X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL: Use movups for misaligned stores instead
    of a sequence loading registers by parts.  */
 DEF_TUNE (X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL, "sse_unaligned_store_optimal",
-         m_NEHALEM | m_SANDYBRIDGE | m_HASWELL | m_SILVERMONT | m_KNL | m_KNM
-         | m_INTEL | m_SKYLAKE_AVX512 | m_BDVER | m_ZNVER1 | m_GENERIC)
+         m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_SILVERMONT | m_KNL | m_KNM
+         | m_INTEL | m_BDVER | m_ZNVER1 | m_GENERIC)
 
 /* Use packed single precision instructions where posisble.  I.e. movups instead
    of movupd.  */
@@ -429,7 +429,7 @@ DEF_TUNE (X86_TUNE_AVX128_OPTIMAL, "avx128_optimal", m_BDVER | m_BTVER2
 
 /* X86_TUNE_AVX256_OPTIMAL: Use 256-bit AVX instructions instead of 512-bit AVX
    instructions in the auto-vectorizer.  */
-DEF_TUNE (X86_TUNE_AVX256_OPTIMAL, "avx256_optimal", m_SKYLAKE_AVX512)
+DEF_TUNE (X86_TUNE_AVX256_OPTIMAL, "avx256_optimal", m_CORE_AVX512)
 
 /*****************************************************************************/
 /* Historical relics: tuning flags that helps a specific old CPU designs     */
index 705936e..3f6c80b 100644 (file)
@@ -59,7 +59,7 @@ extern __inline long long
 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
 _xgetbv (unsigned int __A)
 {
-  __builtin_ia32_xgetbv (__A);
+  return __builtin_ia32_xgetbv (__A);
 }
 
 #ifdef __x86_64__
index 32ef298..592d3dc 100644 (file)
@@ -368,7 +368,7 @@ get_coverage_counts (unsigned counter, unsigned expected,
   else
     {
       gcc_assert (coverage_node_map_initialized_p ());
-      elt.ident = cgraph_node::get (cfun->decl)->profile_id;
+      elt.ident = cgraph_node::get (current_function_decl)->profile_id;
     }
   elt.ctr = counter;
   entry = counts_hash->find (&elt);
@@ -663,7 +663,8 @@ coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
   gcov_write_unsigned (cfg_checksum);
   gcov_write_string (IDENTIFIER_POINTER
                     (DECL_ASSEMBLER_NAME (current_function_decl)));
-  gcov_write_unsigned (DECL_ARTIFICIAL (current_function_decl));
+  gcov_write_unsigned (DECL_ARTIFICIAL (current_function_decl)
+                      && !DECL_LAMBDA_FUNCTION (current_function_decl));
   gcov_write_filename (xloc.file);
   gcov_write_unsigned (xloc.line);
   gcov_write_unsigned (xloc.column);
@@ -671,7 +672,11 @@ coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
   expanded_location endloc = expand_location (cfun->function_end_locus);
 
   /* Function can start in a single file and end in another one.  */
-  gcov_write_unsigned (endloc.file == xloc.file ? endloc.line : xloc.line);
+  /* Work-around for PR gcov-profile/88045.  */
+  int end_line = endloc.file == xloc.file ? endloc.line : xloc.line;
+  if (xloc.line > end_line)
+    end_line = xloc.line;
+  gcov_write_unsigned (end_line);
   gcov_write_length (offset);
 
   return !gcov_is_error ();
index fb6d71d..f16f289 100644 (file)
@@ -1396,6 +1396,13 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
             || (fcode == REAL_TYPE && !(flags & LOOKUP_NO_NON_INTEGRAL)))
           || SCOPED_ENUM_P (from))
        return NULL;
+
+      /* If we're parsing an enum with no fixed underlying type, we're
+        dealing with an incomplete type, which renders the conversion
+        ill-formed.  */
+      if (!COMPLETE_TYPE_P (from))
+       return NULL;
+
       conv = build_conv (ck_std, to, conv);
 
       /* Give this a better rank if it's a promotion.  */
@@ -6783,7 +6790,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
            return expr;
          }
 
-       expr = mark_rvalue_use (expr);
+       /* We don't know here whether EXPR is being used as an lvalue or
+          rvalue, but we know it's read.  */
+       mark_exp_read (expr);
 
        /* Pass LOOKUP_NO_CONVERSION so rvalue/base handling knows not to allow
           any more UDCs.  */
@@ -6872,7 +6881,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        elttype = cp_build_qualified_type
          (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST);
        array = build_array_of_n_type (elttype, len);
-       array = finish_compound_literal (array, new_ctor, complain);
+       array = finish_compound_literal (array, new_ctor, complain, fcl_c99);
        /* Take the address explicitly rather than via decay_conversion
           to avoid the error about taking the address of a temporary.  */
        array = cp_build_addr_expr (array, complain);
@@ -10824,14 +10833,12 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type)
       tree name = mangle_ref_init_variable (decl);
       DECL_NAME (var) = name;
       SET_DECL_ASSEMBLER_NAME (var, name);
-
-      var = pushdecl (var);
     }
   else
     /* Create a new cleanup level if necessary.  */
     maybe_push_cleanup_level (type);
 
-  return var;
+  return pushdecl (var);
 }
 
 /* EXPR is the initializer for a variable DECL of reference or
@@ -11035,7 +11042,9 @@ extend_ref_init_temps_1 (tree decl, tree init, vec<tree, va_gc> **cleanups)
   if (TREE_CODE (sub) != ADDR_EXPR)
     return init;
   /* Deal with binding to a subobject.  */
-  for (p = &TREE_OPERAND (sub, 0); TREE_CODE (*p) == COMPONENT_REF; )
+  for (p = &TREE_OPERAND (sub, 0);
+       (TREE_CODE (*p) == COMPONENT_REF
+       || TREE_CODE (*p) == ARRAY_REF); )
     p = &TREE_OPERAND (*p, 0);
   if (TREE_CODE (*p) == TARGET_EXPR)
     {
index 0427d12..834ba17 100644 (file)
@@ -278,6 +278,9 @@ build_base_path (enum tree_code code,
   probe = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
   if (want_pointer)
     probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe));
+  if (dependent_type_p (probe))
+    if (tree open = currently_open_class (probe))
+      probe = open;
 
   if (code == PLUS_EXPR
       && !SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe))
@@ -417,7 +420,7 @@ build_base_path (enum tree_code code,
     {
       expr = cp_build_fold_indirect_ref (expr);
       expr = build_simple_base_path (expr, binfo);
-      if (rvalue)
+      if (rvalue && lvalue_p (expr))
        expr = move (expr);
       if (want_pointer)
        expr = build_address (expr);
@@ -1138,9 +1141,6 @@ add_method (tree type, tree method, bool via_using)
        }
     }
 
-  /* A class should never have more than one destructor.  */
-  gcc_assert (!current_fns || !DECL_DESTRUCTOR_P (method));
-
   current_fns = ovl_insert (method, current_fns, via_using);
 
   if (!COMPLETE_TYPE_P (type) && !DECL_CONV_FN_P (method)
@@ -1954,6 +1954,7 @@ fixup_attribute_variants (tree t)
   unsigned align = TYPE_ALIGN (t);
   bool user_align = TYPE_USER_ALIGN (t);
   bool may_alias = lookup_attribute ("may_alias", attrs);
+  bool packed = TYPE_PACKED (t);
 
   if (may_alias)
     fixup_may_alias (t);
@@ -1971,6 +1972,7 @@ fixup_attribute_variants (tree t)
       else
        TYPE_USER_ALIGN (variants) = user_align;
       SET_TYPE_ALIGN (variants, valign);
+      TYPE_PACKED (variants) = packed;
       if (may_alias)
        fixup_may_alias (variants);
     }
@@ -2025,6 +2027,7 @@ maybe_warn_about_overly_private_class (tree t)
 {
   int has_member_fn = 0;
   int has_nonprivate_method = 0;
+  bool nonprivate_ctor = false;
 
   if (!warn_ctor_dtor_privacy
       /* If the class has friends, those entities might create and
@@ -2055,7 +2058,11 @@ maybe_warn_about_overly_private_class (tree t)
      non-private statics, we can't ever call any of the private member
      functions.)  */
   for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
-    if (!DECL_DECLARES_FUNCTION_P (fn))
+    if (TREE_CODE (fn) == USING_DECL
+       && DECL_NAME (fn) == ctor_identifier
+       && !TREE_PRIVATE (fn))
+      nonprivate_ctor = true;
+    else if (!DECL_DECLARES_FUNCTION_P (fn))
       /* Not a function.  */;
     else if (DECL_ARTIFICIAL (fn))
       /* We're not interested in compiler-generated methods; they don't
@@ -2117,7 +2124,6 @@ maybe_warn_about_overly_private_class (tree t)
       /* Implicitly generated constructors are always public.  */
       && !CLASSTYPE_LAZY_DEFAULT_CTOR (t))
     {
-      bool nonprivate_ctor = false;
       tree copy_or_move = NULL_TREE;
 
       /* If a non-template class does not define a copy
@@ -5171,6 +5177,19 @@ classtype_has_move_assign_or_move_ctor_p (tree t, bool user_p)
   return false;
 }
 
+/* True iff T has a move constructor that is not deleted.  */
+
+bool
+classtype_has_non_deleted_move_ctor (tree t)
+{
+  if (CLASSTYPE_LAZY_MOVE_CTOR (t))
+    lazily_declare_fn (sfk_move_constructor, t);
+  for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
+    if (move_fn_p (*iter) && !DECL_DELETED_FN (*iter))
+      return true;
+  return false;
+}
+
 /* Nonzero if we need to build up a constructor call when initializing an
    object of this class, either because it has a user-declared constructor
    or because it doesn't have a default constructor (so we need to give an
@@ -6226,6 +6245,7 @@ layout_class_type (tree t, tree *virtuals_p)
                                  bitsize_int (BITS_PER_UNIT)));
       SET_TYPE_ALIGN (base_t, rli->record_align);
       TYPE_USER_ALIGN (base_t) = TYPE_USER_ALIGN (t);
+      TYPE_TYPELESS_STORAGE (base_t) = TYPE_TYPELESS_STORAGE (t);
 
       /* Copy the non-static data members of T. This will include its
         direct non-virtual bases & vtable.  */
@@ -7014,6 +7034,20 @@ finish_struct (tree t, tree attributes)
        else if (DECL_DECLARES_FUNCTION_P (x))
          DECL_IN_AGGR_P (x) = false;
 
+      /* Also add a USING_DECL for operator=.  We know there'll be (at
+        least) one, but we don't know the signature(s).  We want name
+        lookup not to fail or recurse into bases.  This isn't added
+        to the template decl list so we drop this at instantiation
+        time.  */
+      tree ass_op = build_lang_decl (USING_DECL, assign_op_identifier,
+                                    NULL_TREE);
+      DECL_CONTEXT (ass_op) = t;
+      USING_DECL_SCOPE (ass_op) = t;
+      DECL_DEPENDENT_P (ass_op) = true;
+      DECL_ARTIFICIAL (ass_op) = true;
+      DECL_CHAIN (ass_op) = TYPE_FIELDS (t);
+      TYPE_FIELDS (t) = ass_op;
+
       TYPE_SIZE (t) = bitsize_zero_node;
       TYPE_SIZE_UNIT (t) = size_zero_node;
       /* COMPLETE_TYPE_P is now true.  */
@@ -7427,8 +7461,8 @@ pop_class_stack (void)
     --current_class_stack[current_class_depth - 1].hidden;
 }
 
-/* Returns 1 if the class type currently being defined is either T or
-   a nested type of T.  Returns the type from the current_class_stack,
+/* If the class type currently being defined is either T or
+   a nested type of T, returns the type from the current_class_stack,
    which might be equivalent to but not equal to T in case of
    constrained partial specializations.  */
 
index b4bcc6a..f161984 100644 (file)
@@ -1252,6 +1252,8 @@ adjust_temp_type (tree type, tree temp)
   /* Avoid wrapping an aggregate value in a NOP_EXPR.  */
   if (TREE_CODE (temp) == CONSTRUCTOR)
     return build_constructor (type, CONSTRUCTOR_ELTS (temp));
+  if (TREE_CODE (temp) == EMPTY_CLASS_EXPR)
+    return build0 (EMPTY_CLASS_EXPR, type);
   gcc_assert (scalarish_type_p (type));
   return cp_fold_convert (type, temp);
 }
@@ -2066,6 +2068,7 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
     {
       if (!ctx->quiet)
        error ("arithmetic involving a null pointer in %qE", lhs);
+      *non_constant_p = true;
       return t;
     }
   else if (code == POINTER_PLUS_EXPR)
@@ -2506,9 +2509,13 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
                                             lval,
                                             non_constant_p, overflow_p);
   if (INDIRECT_REF_P (whole)
-      && integer_zerop (TREE_OPERAND (whole, 0))
-      && !ctx->quiet)
-    error ("dereferencing a null pointer in %qE", orig_whole);
+      && integer_zerop (TREE_OPERAND (whole, 0)))
+    {
+      if (!ctx->quiet)
+       error ("dereferencing a null pointer in %qE", orig_whole);
+      *non_constant_p = true;
+      return t;
+    }
 
   if (TREE_CODE (whole) == PTRMEM_CST)
     whole = cplus_expand_constant (whole);
@@ -2989,6 +2996,9 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
        {
          /* Initializing an element using value or default initialization
             we just pre-built above.  */
+         if (init == void_node)
+           /* Trivial default-init, don't do anything to the CONSTRUCTOR.  */
+           return ctx->ctor;
          eltinit = cxx_eval_constant_expression (&new_ctx, init, lval,
                                                  non_constant_p, overflow_p);
          reuse = i == 0;
@@ -3926,6 +3936,16 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
   for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
     {
       tree stmt = tsi_stmt (i);
+      /* We've found a continue, so skip everything until we reach
+        the label its jumping to.  */
+      if (continues (jump_target))
+       {
+         if (label_matches (ctx, jump_target, stmt))
+           /* Found it.  */
+           *jump_target = NULL_TREE;
+         else
+           continue;
+       }
       if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
        continue;
       r = cxx_eval_constant_expression (ctx, stmt, false,
@@ -3993,13 +4013,13 @@ cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
                      bool *non_constant_p, bool *overflow_p,
                      tree *jump_target)
 {
-  tree cond = TREE_OPERAND (t, 0);
+  tree cond = SWITCH_COND (t);
   cond = cxx_eval_constant_expression (ctx, cond, false,
                                       non_constant_p, overflow_p);
   VERIFY_CONSTANT (cond);
   *jump_target = cond;
 
-  tree body = TREE_OPERAND (t, 1);
+  tree body = SWITCH_BODY (t);
   constexpr_ctx new_ctx = *ctx;
   constexpr_switch_state css = css_default_not_seen;
   new_ctx.css_state = &css;
@@ -4528,6 +4548,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case COND_EXPR:
       if (jump_target && *jump_target)
        {
+         tree orig_jump = *jump_target;
          /* When jumping to a label, the label might be either in the
             then or else blocks, so process then block first in skipping
             mode first, and if we are still in the skipping mode at its end,
@@ -4535,7 +4556,19 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
          r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
                                            lval, non_constant_p, overflow_p,
                                            jump_target);
-         if (*jump_target)
+         /* It's possible that we found the label in the then block.  But
+            it could have been followed by another jumping statement, e.g.
+            say we're looking for case 1:
+             if (cond)
+               {
+                 // skipped statements
+                 case 1:; // clears up *jump_target
+                 return 1; // and sets it to a RETURN_EXPR
+               }
+             else { ... }
+            in which case we need not go looking to the else block.
+            (goto is not allowed in a constexpr function.)  */
+         if (*jump_target == orig_jump)
            r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
                                              lval, non_constant_p, overflow_p,
                                              jump_target);
@@ -4551,7 +4584,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       break;
 
     case CONSTRUCTOR:
-      if (TREE_CONSTANT (t))
+      if (TREE_CONSTANT (t) && reduced_constant_expression_p (t))
        {
          /* Don't re-process a constant CONSTRUCTOR, but do fold it to
             VECTOR_CST if applicable.  */
@@ -5107,12 +5140,12 @@ clear_cv_and_fold_caches (void)
 /* Like maybe_constant_value but first fully instantiate the argument.
 
    Note: this is equivalent to instantiate_non_dependent_expr_sfinae
-   (t, tf_none) followed by maybe_constant_value but is more efficient,
+   (t, complain) followed by maybe_constant_value but is more efficient,
    because calls instantiation_dependent_expression_p and
    potential_constant_expression at most once.  */
 
 tree
-fold_non_dependent_expr (tree t)
+fold_non_dependent_expr (tree t, tsubst_flags_t complain /* = tf_none */)
 {
   if (t == NULL_TREE)
     return NULL_TREE;
@@ -5129,7 +5162,7 @@ fold_non_dependent_expr (tree t)
       if (is_nondependent_constant_expression (t))
        {
          processing_template_decl_sentinel s;
-         t = instantiate_non_dependent_expr_internal (t, tf_none);
+         t = instantiate_non_dependent_expr_internal (t, complain);
 
          if (type_unknown_p (t)
              || BRACE_ENCLOSED_INITIALIZER_P (t))
index 7449065..93bf3c3 100644 (file)
@@ -1085,6 +1085,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
       if (h)
        {
          *stmt_p = h->to;
+         TREE_USED (h->to) |= TREE_USED (stmt);
          *walk_subtrees = 0;
          return NULL;
        }
@@ -1463,6 +1464,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
     case OMP_FOR:
     case OMP_SIMD:
     case OMP_DISTRIBUTE:
+    case OACC_LOOP:
       genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
       break;
 
@@ -1621,6 +1623,13 @@ cp_maybe_instrument_return (tree fndecl)
        case STATEMENT_LIST:
          {
            tree_stmt_iterator i = tsi_last (t);
+           while (!tsi_end_p (i))
+             {
+               tree p = tsi_stmt (i);
+               if (TREE_CODE (p) != DEBUG_BEGIN_STMT)
+                 break;
+               tsi_prev (&i);
+             }
            if (!tsi_end_p (i))
              {
                t = tsi_stmt (i);
@@ -1957,7 +1966,7 @@ cxx_omp_const_qual_no_mutable (tree decl)
 /* True if OpenMP sharing attribute of DECL is predetermined.  */
 
 enum omp_clause_default_kind
-cxx_omp_predetermined_sharing (tree decl)
+cxx_omp_predetermined_sharing_1 (tree decl)
 {
   /* Static data members are predetermined shared.  */
   if (TREE_STATIC (decl))
@@ -1975,6 +1984,32 @@ cxx_omp_predetermined_sharing (tree decl)
   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
 }
 
+/* Likewise, but also include the artificial vars.  We don't want to
+   disallow the artificial vars being mentioned in explicit clauses,
+   as we use artificial vars e.g. for loop constructs with random
+   access iterators other than pointers, but during gimplification
+   we want to treat them as predetermined.  */
+
+enum omp_clause_default_kind
+cxx_omp_predetermined_sharing (tree decl)
+{
+  enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl);
+  if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
+    return ret;
+
+  /* Predetermine artificial variables holding integral values, those
+     are usually result of gimplify_one_sizepos or SAVE_EXPR
+     gimplification.  */
+  if (VAR_P (decl)
+      && DECL_ARTIFICIAL (decl)
+      && INTEGRAL_TYPE_P (TREE_TYPE (decl))
+      && !(DECL_LANG_SPECIFIC (decl)
+          && DECL_OMP_PRIVATIZED_MEMBER (decl)))
+    return OMP_CLAUSE_DEFAULT_SHARED;
+
+  return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
+}
+
 /* Finalize an implicitly determined clause.  */
 
 void
@@ -2231,8 +2266,9 @@ cp_fold (tree x)
            {
              val = TREE_OPERAND (val, 0);
              STRIP_NOPS (val);
+             val = maybe_constant_value (val);
              if (TREE_CODE (val) == INTEGER_CST)
-               return fold_convert (TREE_TYPE (x), fold_offsetof_1 (op0));
+               return fold_offsetof (op0, TREE_TYPE (x));
            }
        }
       goto finish_unary;
index 72e4080..0f24b4f 100644 (file)
@@ -6180,6 +6180,7 @@ extern bool trivial_default_constructor_is_constexpr (tree);
 extern bool type_has_constexpr_default_constructor (tree);
 extern bool type_has_virtual_destructor                (tree);
 extern bool classtype_has_move_assign_or_move_ctor_p (tree, bool user_declared);
+extern bool classtype_has_non_deleted_move_ctor (tree);
 extern bool type_build_ctor_call               (tree);
 extern bool type_build_dtor_call               (tree);
 extern void explain_non_literal_class          (tree);
@@ -6644,7 +6645,7 @@ extern bool template_parameter_pack_p           (const_tree);
 extern bool function_parameter_pack_p          (const_tree);
 extern bool function_parameter_expanded_from_pack_p (tree, tree);
 extern tree make_pack_expansion                 (tree, tsubst_flags_t = tf_warning_or_error);
-extern bool check_for_bare_parameter_packs      (tree);
+extern bool check_for_bare_parameter_packs      (tree, location_t = UNKNOWN_LOCATION);
 extern tree build_template_info                        (tree, tree);
 extern tree get_template_info                  (const_tree);
 extern vec<qualified_typedef_usage_t, va_gc> *get_types_needing_access_check (tree);
@@ -6827,9 +6828,9 @@ extern bool perform_or_defer_access_check (tree, tree, tree,
 
 struct deferring_access_check_sentinel
 {
-  deferring_access_check_sentinel ()
+  deferring_access_check_sentinel (enum deferring_kind kind = dk_deferred)
   {
-    push_deferring_access_checks (dk_deferred);
+    push_deferring_access_checks (kind);
   }
   ~deferring_access_check_sentinel ()
   {
@@ -6896,7 +6897,7 @@ extern tree begin_compound_stmt                   (unsigned int);
 
 extern void finish_compound_stmt               (tree);
 extern tree finish_asm_stmt                    (int, tree, tree, tree, tree,
-                                                tree);
+                                                tree, bool);
 extern tree finish_label_stmt                  (tree);
 extern void finish_label_decl                  (tree);
 extern cp_expr finish_parenthesized_expr       (cp_expr);
@@ -7035,6 +7036,7 @@ extern tree finish_builtin_launder                (location_t, tree,
                                                 tsubst_flags_t);
 extern void start_lambda_scope                 (tree);
 extern void record_lambda_scope                        (tree);
+extern void record_null_lambda_scope           (tree);
 extern void finish_lambda_scope                        (void);
 extern tree start_lambda_function              (tree fn, tree lambda_expr);
 extern void finish_lambda_function             (tree body);
@@ -7096,6 +7098,7 @@ extern tree get_target_expr_sfinae                (tree, tsubst_flags_t);
 extern tree build_cplus_array_type             (tree, tree);
 extern tree build_array_of_n_type              (tree, int);
 extern bool array_of_runtime_bound_p           (tree);
+extern bool vla_type_p                         (tree);
 extern tree build_array_copy                   (tree);
 extern tree build_vec_init_expr                        (tree, tree, tsubst_flags_t);
 extern void diagnose_non_constexpr_vec_init    (tree);
@@ -7409,6 +7412,7 @@ extern int cp_gimplify_expr                       (tree *, gimple_seq *,
                                                 gimple_seq *);
 extern void cp_genericize                      (tree);
 extern bool cxx_omp_const_qual_no_mutable      (tree);
+extern enum omp_clause_default_kind cxx_omp_predetermined_sharing_1 (tree);
 extern enum omp_clause_default_kind cxx_omp_predetermined_sharing (tree);
 extern tree cxx_omp_clause_default_ctor                (tree, tree, tree);
 extern tree cxx_omp_clause_copy_ctor           (tree, tree, tree);
@@ -7542,7 +7546,7 @@ extern tree cxx_constant_value                    (tree, tree = NULL_TREE);
 extern tree cxx_constant_init                  (tree, tree = NULL_TREE);
 extern tree maybe_constant_value               (tree, tree = NULL_TREE);
 extern tree maybe_constant_init                        (tree, tree = NULL_TREE);
-extern tree fold_non_dependent_expr            (tree);
+extern tree fold_non_dependent_expr            (tree, tsubst_flags_t = tf_none);
 extern tree fold_simple                                (tree);
 extern bool is_sub_constant_expr                (tree);
 extern bool reduced_constant_expression_p       (tree);
index 0f045e2..d0059a3 100644 (file)
@@ -1938,7 +1938,8 @@ can_convert_qual (tree type, tree expr)
 
 /* Attempt to perform qualification conversions on EXPR to convert it
    to TYPE.  Return the resulting expression, or error_mark_node if
-   the conversion was impossible.  */
+   the conversion was impossible.  Since this is only used by
+   convert_nontype_argument, we fold the conversion.  */
 
 tree
 perform_qualification_conversions (tree type, tree expr)
@@ -1950,7 +1951,7 @@ perform_qualification_conversions (tree type, tree expr)
   if (same_type_p (type, expr_type))
     return expr;
   else if (can_convert_qual (type, expr))
-    return build_nop (type, expr);
+    return cp_fold_convert (type, expr);
   else
     return error_mark_node;
 }
index 55e2343..f6af3f9 100644 (file)
@@ -6134,20 +6134,29 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
     {
       if (TREE_CODE (init) == CONSTRUCTOR)
        {
-         if (TREE_TYPE (init) && TYPE_PTRMEMFUNC_P (TREE_TYPE (init)))
-           /* There is no need to reshape pointer-to-member function
-              initializers, as they are always constructed correctly
-              by the front end.  */
-           ;
-         else if (COMPOUND_LITERAL_P (init))
+         tree init_type = TREE_TYPE (init);
+         if (init_type && TYPE_PTRMEMFUNC_P (init_type))
+           /* There is no need to call reshape_init for pointer-to-member
+              function initializers, as they are always constructed correctly
+              by the front end.  Here we have e.g. {.__pfn=0B, .__delta=0},
+              which is missing outermost braces.  We should warn below, and
+              one of the routines below will wrap it in additional { }.  */;
          /* For a nested compound literal, there is no need to reshape since
-            brace elision is not allowed. Even if we decided to allow it,
-            we should add a call to reshape_init in finish_compound_literal,
-            before calling digest_init, so changing this code would still
-            not be necessary.  */
-           gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (init));
+            we called reshape_init in finish_compound_literal, before calling
+            digest_init.  */
+         else if (COMPOUND_LITERAL_P (init)
+                  /* Similarly, a CONSTRUCTOR of the target's type is a
+                     previously digested initializer.  */
+                  || same_type_ignoring_top_level_qualifiers_p (type,
+                                                                init_type))
+           {
+             ++d->cur;
+             gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (init));
+             return init;
+           }
          else
            {
+             /* Something that hasn't been reshaped yet.  */
              ++d->cur;
              gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
              return reshape_init (type, init, complain);
@@ -7305,6 +7314,27 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
   if (was_readonly)
     TREE_READONLY (decl) = 1;
 
+  if (flag_openmp
+      && VAR_P (decl)
+      && lookup_attribute ("omp declare target implicit",
+                          DECL_ATTRIBUTES (decl)))
+    {
+      DECL_ATTRIBUTES (decl)
+       = remove_attribute ("omp declare target implicit",
+                           DECL_ATTRIBUTES (decl));
+      complete_type (TREE_TYPE (decl));
+      if (!cp_omp_mappable_type (TREE_TYPE (decl)))
+       error ("%q+D in declare target directive does not have mappable type",
+              decl);
+      else if (!lookup_attribute ("omp declare target",
+                                 DECL_ATTRIBUTES (decl))
+              && !lookup_attribute ("omp declare target link",
+                                    DECL_ATTRIBUTES (decl)))
+       DECL_ATTRIBUTES (decl)
+         = tree_cons (get_identifier ("omp declare target"),
+                      NULL_TREE, DECL_ATTRIBUTES (decl));
+    }
+
   invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
 }
 
@@ -10255,6 +10285,9 @@ grokdeclarator (const cp_declarator *declarator,
              break;
            if (qualifying_scope)
              {
+               if (check_for_bare_parameter_packs (qualifying_scope,
+                                                   id_declarator->id_loc))
+                 return error_mark_node;
                if (at_function_scope_p ())
                  {
                    /* [dcl.meaning] 
@@ -15533,6 +15566,18 @@ begin_destructor_body (void)
            tree stmt = cp_build_modify_expr (input_location, vtbl_ptr,
                                              NOP_EXPR, vtbl,
                                              tf_warning_or_error);
+           /* If the vptr is shared with some virtual nearly empty base,
+              don't clear it if not in charge, the dtor of the virtual
+              nearly empty base will do that later.  */
+           if (CLASSTYPE_VBASECLASSES (current_class_type)
+               && CLASSTYPE_PRIMARY_BINFO (current_class_type)
+               && BINFO_VIRTUAL_P
+                         (CLASSTYPE_PRIMARY_BINFO (current_class_type)))
+             {
+               stmt = convert_to_void (stmt, ICV_STATEMENT,
+                                       tf_warning_or_error);
+               stmt = build_if_in_charge (stmt);
+             }
            finish_decl_cleanup (NULL_TREE, stmt);
          }
        else
index b0bf824..6a67c4e 100644 (file)
@@ -1514,11 +1514,11 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
          && DECL_CLASS_SCOPE_P (*decl))
        error ("%q+D static data member inside of declare target directive",
               *decl);
-      else if (!processing_template_decl
-              && VAR_P (*decl)
-              && !cp_omp_mappable_type (TREE_TYPE (*decl)))
-       error ("%q+D in declare target directive does not have mappable type",
-              *decl);
+      else if (VAR_P (*decl)
+              && (processing_template_decl
+                  || !cp_omp_mappable_type (TREE_TYPE (*decl))))
+       attributes = tree_cons (get_identifier ("omp declare target implicit"),
+                               NULL_TREE, attributes);
       else
        attributes = tree_cons (get_identifier ("omp declare target"),
                                NULL_TREE, attributes);
@@ -1939,10 +1939,13 @@ vague_linkage_p (tree decl)
 {
   if (!TREE_PUBLIC (decl))
     {
-      /* maybe_thunk_body clears TREE_PUBLIC on the maybe-in-charge 'tor
-        variants, check one of the "clones" for the real linkage.  */
+      /* maybe_thunk_body clears TREE_PUBLIC and DECL_ABSTRACT_P on the
+        maybe-in-charge 'tor variants; in that case we need to check one of
+        the "clones" for the real linkage.  But only in that case; before
+        maybe_clone_body we haven't yet copied the linkage to the clones.  */
       if ((DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)
           || DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl))
+         && !DECL_ABSTRACT_P (decl)
          && DECL_CHAIN (decl)
          && DECL_CLONED_FUNCTION_P (DECL_CHAIN (decl)))
        return vague_linkage_p (DECL_CHAIN (decl));
@@ -2422,21 +2425,8 @@ determine_visibility (tree decl)
            }
 
          /* Local classes in templates have CLASSTYPE_USE_TEMPLATE set,
-            but have no TEMPLATE_INFO.  Their containing template
-            function does, and the local class could be constrained
-            by that.  */
-         if (DECL_LANG_SPECIFIC (fn) && DECL_USE_TEMPLATE (fn))
-           template_decl = fn;
-         else if (template_decl)
-           {
-             /* FN must be a regenerated lambda function, since they don't
-                have template arguments.  Find a containing non-lambda
-                template instantiation.  */
-             tree ctx = fn;
-             while (ctx && !get_template_info (ctx))
-               ctx = get_containing_scope (ctx);
-             template_decl = ctx;
-           }
+            but have no TEMPLATE_INFO, so don't try to check it.  */
+         template_decl = NULL_TREE;
        }
       else if (VAR_P (decl) && DECL_TINFO_P (decl)
               && flag_visibility_ms_compat)
index 95b8b84..f7895de 100644 (file)
@@ -3286,8 +3286,13 @@ void
 cxx_print_error_function (diagnostic_context *context, const char *file,
                          diagnostic_info *diagnostic)
 {
+  char *prefix;
+  if (file)
+    prefix = xstrdup (file);
+  else
+    prefix = NULL;
   lhd_print_error_function (context, file, diagnostic);
-  pp_set_prefix (context->printer, file);
+  pp_set_prefix (context->printer, prefix);
   maybe_print_instantiation_context (context);
 }
 
@@ -3315,7 +3320,7 @@ cp_print_error_function (diagnostic_context *context,
     return;
   if (diagnostic_last_function_changed (context, diagnostic))
     {
-      const char *old_prefix = context->printer->prefix;
+      char *old_prefix = pp_take_prefix (context->printer);
       const char *file = LOCATION_FILE (diagnostic_location (diagnostic));
       tree abstract_origin = diagnostic_abstract_origin (diagnostic);
       char *new_prefix = (file && abstract_origin == NULL)
index 15894fc..a9bf37b 100644 (file)
@@ -139,6 +139,9 @@ mark_use (tree expr, bool rvalue_p, bool read_p,
                  break;
                }
            }
+         temp_override<location_t> l (input_location);
+         if (loc != UNKNOWN_LOCATION)
+           input_location = loc;
          expr = process_outer_var_ref (expr, tf_warning_or_error, true);
          if (!(TREE_TYPE (oexpr)
                && TREE_CODE (TREE_TYPE (oexpr)) == REFERENCE_TYPE))
@@ -183,6 +186,14 @@ mark_use (tree expr, bool rvalue_p, bool read_p,
            expr = convert_from_reference (r);
        }
       break;
+
+    CASE_CONVERT:
+    case VIEW_CONVERT_EXPR:
+      if (location_wrapper_p (expr))
+       loc = EXPR_LOCATION (expr);
+      recurse_op[0] = true;
+      break;
+
     default:
       break;
     }
index d6c0bcf..302c603 100644 (file)
@@ -577,6 +577,16 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
 
          DECL_INSTANTIATING_NSDMI_P (member) = 1;
 
+         bool pushed = false;
+         if (!currently_open_class (DECL_CONTEXT (member)))
+           {
+             push_to_top_level ();
+             push_nested_class (DECL_CONTEXT (member));
+             pushed = true;
+           }
+
+         gcc_checking_assert (!processing_template_decl);
+
          inject_this_parameter (DECL_CONTEXT (member), TYPE_UNQUALIFIED);
 
          start_lambda_scope (member);
@@ -599,6 +609,12 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
              nsdmi_inst->put (member, init);
            }
 
+         if (pushed)
+           {
+             pop_nested_class ();
+             pop_from_top_level ();
+           }
+
          input_location = sloc;
          cp_unevaluated_operand = un;
        }
@@ -1678,6 +1694,7 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
       if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp))
        {
          from_array = 1;
+         init = mark_rvalue_use (init);
          if (init && DECL_P (init)
              && !(flags & LOOKUP_ONLYCONVERTING))
            {
@@ -2856,10 +2873,9 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
       outer_nelts_from_type = true;
     }
 
-  /* Lots of logic below. depends on whether we have a constant number of
+  /* Lots of logic below depends on whether we have a constant number of
      elements, so go ahead and fold it now.  */
-  if (outer_nelts)
-    outer_nelts = maybe_constant_value (outer_nelts);
+  const_tree cst_outer_nelts = fold_non_dependent_expr (outer_nelts);
 
   /* If our base type is an array, then make sure we know how many elements
      it has.  */
@@ -2911,7 +2927,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
   /* Warn if we performed the (T[N]) to T[N] transformation and N is
      variable.  */
   if (outer_nelts_from_type
-      && !TREE_CONSTANT (outer_nelts))
+      && !TREE_CONSTANT (cst_outer_nelts))
     {
       if (complain & tf_warning_or_error)
        {
@@ -3010,9 +3026,9 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 
       size = size_binop (MULT_EXPR, size, fold_convert (sizetype, nelts));
 
-      if (INTEGER_CST == TREE_CODE (outer_nelts))
+      if (TREE_CODE (cst_outer_nelts) == INTEGER_CST)
        {
-         if (tree_int_cst_lt (max_outer_nelts_tree, outer_nelts))
+         if (tree_int_cst_lt (max_outer_nelts_tree, cst_outer_nelts))
            {
              /* When the array size is constant, check it at compile time
                 to make sure it doesn't exceed the implementation-defined
@@ -3638,13 +3654,13 @@ build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
       /* Try to determine the constant value only for the purposes
         of the diagnostic below but continue to use the original
         value and handle const folding later.  */
-      const_tree cst_nelts = maybe_constant_value (nelts);
+      const_tree cst_nelts = fold_non_dependent_expr (nelts);
 
       /* The expression in a noptr-new-declarator is erroneous if it's of
         non-class type and its value before converting to std::size_t is
         less than zero. ... If the expression is a constant expression,
         the program is ill-fomed.  */
-      if (INTEGER_CST == TREE_CODE (cst_nelts)
+      if (TREE_CODE (cst_nelts) == INTEGER_CST
          && tree_int_cst_sgn (cst_nelts) == -1)
        {
          if (complain & tf_error)
@@ -4006,7 +4022,7 @@ build_vec_init (tree base, tree maxindex, tree init,
   tree compound_stmt;
   int destroy_temps;
   tree try_block = NULL_TREE;
-  int num_initialized_elts = 0;
+  HOST_WIDE_INT num_initialized_elts = 0;
   bool is_global;
   tree obase = base;
   bool xvalue = false;
@@ -4441,10 +4457,13 @@ build_vec_init (tree base, tree maxindex, tree init,
 
          if (e)
            {
-             int max = tree_to_shwi (maxindex)+1;
-             for (; num_initialized_elts < max; ++num_initialized_elts)
+             HOST_WIDE_INT last = tree_to_shwi (maxindex);
+             if (num_initialized_elts <= last)
                {
                  tree field = size_int (num_initialized_elts);
+                 if (num_initialized_elts != last)
+                   field = build2 (RANGE_EXPR, sizetype, field,
+                                   size_int (last));
                  CONSTRUCTOR_APPEND_ELT (const_vec, field, e);
                }
            }
index e9b962a..6c04393 100644 (file)
@@ -262,6 +262,9 @@ is_capture_proxy (tree decl)
          && DECL_HAS_VALUE_EXPR_P (decl)
          && !DECL_ANON_UNION_VAR_P (decl)
          && !DECL_DECOMPOSITION_P (decl)
+         && !(DECL_ARTIFICIAL (decl)
+              && DECL_LANG_SPECIFIC (decl)
+              && DECL_OMP_PRIVATIZED_MEMBER (decl))
          && LAMBDA_FUNCTION_P (DECL_CONTEXT (decl)));
 }
 
@@ -884,7 +887,7 @@ resolvable_dummy_lambda (tree object)
       && current_class_type
       && LAMBDA_TYPE_P (current_class_type)
       && lambda_function (current_class_type)
-      && DERIVED_FROM_P (type, current_nonlambda_class_type ()))
+      && DERIVED_FROM_P (type, nonlambda_method_basetype()))
     return CLASSTYPE_LAMBDA_EXPR (current_class_type);
 
   return NULL_TREE;
@@ -949,30 +952,37 @@ current_nonlambda_function (void)
   return fn;
 }
 
-/* Returns the method basetype of the innermost non-lambda function, or
-   NULL_TREE if none.  */
+/* Returns the method basetype of the innermost non-lambda function, including
+   a hypothetical constructor if inside an NSDMI, or NULL_TREE if none.  */
 
 tree
 nonlambda_method_basetype (void)
 {
-  tree fn, type;
   if (!current_class_ref)
     return NULL_TREE;
 
-  type = current_class_type;
+  tree type = current_class_type;
   if (!type || !LAMBDA_TYPE_P (type))
     return type;
 
-  /* Find the nearest enclosing non-lambda function.  */
-  fn = TYPE_NAME (type);
-  do
-    fn = decl_function_context (fn);
-  while (fn && LAMBDA_FUNCTION_P (fn));
-
-  if (!fn || !DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
-    return NULL_TREE;
-
-  return TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
+  while (true)
+    {
+      tree lam = CLASSTYPE_LAMBDA_EXPR (type);
+      tree ex = LAMBDA_EXPR_EXTRA_SCOPE (lam);
+      if (ex && TREE_CODE (ex) == FIELD_DECL)
+       /* Lambda in an NSDMI.  */
+       return DECL_CONTEXT (ex);
+
+      tree fn = TYPE_CONTEXT (type);
+      if (!fn || TREE_CODE (fn) != FUNCTION_DECL
+         || !DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+       /* No enclosing non-lambda method.  */
+       return NULL_TREE;
+      if (!LAMBDA_FUNCTION_P (fn))
+       /* Found an enclosing non-lambda method.  */
+       return TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
+      type = DECL_CONTEXT (fn);
+    }
 }
 
 /* Like current_scope, but looking through lambdas.  */
@@ -1108,6 +1118,9 @@ maybe_add_lambda_conv_op (tree type)
       {
        tree new_node = copy_node (src);
 
+       /* Clear TREE_ADDRESSABLE on thunk arguments.  */
+       TREE_ADDRESSABLE (new_node) = 0;
+
        if (!fn_args)
          fn_args = tgt = new_node;
        else
@@ -1373,6 +1386,24 @@ record_lambda_scope (tree lambda)
   LAMBDA_EXPR_DISCRIMINATOR (lambda) = lambda_count++;
 }
 
+/* This lambda is an instantiation of a lambda in a template default argument
+   that got no LAMBDA_EXPR_EXTRA_SCOPE, so this shouldn't either.  But we do
+   need to use and increment the global count to avoid collisions.  */
+
+void
+record_null_lambda_scope (tree lambda)
+{
+  if (vec_safe_is_empty (lambda_scope_stack))
+    record_lambda_scope (lambda);
+  else
+    {
+      tree_int *p = lambda_scope_stack->begin();
+      LAMBDA_EXPR_EXTRA_SCOPE (lambda) = p->t;
+      LAMBDA_EXPR_DISCRIMINATOR (lambda) = p->i++;
+    }
+  gcc_assert (LAMBDA_EXPR_EXTRA_SCOPE (lambda) == NULL_TREE);
+}
+
 void
 finish_lambda_scope (void)
 {
@@ -1446,8 +1477,10 @@ mark_const_cap_r (tree *t, int *walk_subtrees, void *data)
     {
       tree decl = DECL_EXPR_DECL (*t);
       if (is_constant_capture_proxy (decl))
-       var = DECL_CAPTURED_VARIABLE (decl);
-      *walk_subtrees = 0;
+       {
+         var = DECL_CAPTURED_VARIABLE (decl);
+         *walk_subtrees = 0;
+       }
     }
   else if (is_constant_capture_proxy (*t))
     var = DECL_CAPTURED_VARIABLE (*t);
@@ -1486,8 +1519,8 @@ prune_lambda_captures (tree body)
       tree cap = *capp;
       if (tree var = var_to_maybe_prune (cap))
        {
-         tree *use = *const_vars.get (var);
-         if (TREE_CODE (*use) == DECL_EXPR)
+         tree **use = const_vars.get (var);
+         if (use && TREE_CODE (**use) == DECL_EXPR)
            {
              /* All uses of this capture were folded away, leaving only the
                 proxy declaration.  */
@@ -1502,7 +1535,7 @@ prune_lambda_captures (tree body)
              *fieldp = DECL_CHAIN (*fieldp);
 
              /* And remove the capture proxy declaration.  */
-             *use = void_node;
+             **use = void_node;
              continue;
            }
        }
index eaa930f..d10f1a6 100644 (file)
@@ -1144,11 +1144,11 @@ static tree
 constructible_expr (tree to, tree from)
 {
   tree expr;
+  cp_unevaluated cp_uneval_guard;
   if (CLASS_TYPE_P (to))
     {
       tree ctype = to;
       vec<tree, va_gc> *args = NULL;
-      cp_unevaluated cp_uneval_guard;
       if (TREE_CODE (to) != REFERENCE_TYPE)
        to = cp_build_reference_type (to, /*rval*/false);
       tree ob = build_stub_object (to);
@@ -1216,7 +1216,7 @@ is_trivially_xible (enum tree_code code, tree to, tree from)
   tree expr;
   expr = is_xible_helper (code, to, from, /*trivial*/true);
 
-  if (expr == error_mark_node)
+  if (expr == NULL_TREE || expr == error_mark_node)
     return false;
   tree nt = cp_walk_tree_without_duplicates (&expr, check_nontriv, NULL);
   return !nt;
@@ -1843,8 +1843,12 @@ maybe_explain_implicit_delete (tree decl)
       if (!informed)
        {
          tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
-         tree parm_type = TREE_VALUE (parms);
-         bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
+         bool const_p = false;
+         if (parms)
+           {
+             tree parm_type = TREE_VALUE (parms);
+             const_p = CP_TYPE_CONST_P (non_reference (parm_type));
+           }
          tree raises = NULL_TREE;
          bool deleted_p = false;
          tree scope = push_scope (ctype);
@@ -2405,7 +2409,7 @@ lazily_declare_fn (special_function_kind sfk, tree type)
 
   /* Add it to the class  */
   bool added = add_method (type, fn, false);
-  gcc_assert (added);
+  gcc_assert (added || errorcount);
 
   /* Add it to TYPE_FIELDS.  */
   if (sfk == sfk_destructor
index 95a07b5..4e8263b 100644 (file)
@@ -560,11 +560,14 @@ name_lookup::search_namespace (tree scope)
 
   /* Look in exactly namespace. */
   bool found = search_namespace_only (scope);
-  
-  /* Recursively look in its inline children.  */
-  if (vec<tree, va_gc> *inlinees = DECL_NAMESPACE_INLINEES (scope))
-    for (unsigned ix = inlinees->length (); ix--;)
-      found |= search_namespace ((*inlinees)[ix]);
+
+  /* Don't look into inline children, if we're looking for an
+     anonymous name -- it must be in the current scope, if anywhere.  */
+  if (name)
+    /* Recursively look in its inline children.  */
+    if (vec<tree, va_gc> *inlinees = DECL_NAMESPACE_INLINEES (scope))
+      for (unsigned ix = inlinees->length (); ix--;)
+       found |= search_namespace ((*inlinees)[ix]);
 
   if (found)
     mark_found (scope);
@@ -1237,17 +1240,6 @@ get_class_binding_direct (tree klass, tree name, int type_or_fns)
        }
       else if (STAT_HACK_P (val))
        val = STAT_DECL (val);
-
-      if (val && TREE_CODE (val) == OVERLOAD
-         && TREE_CODE (OVL_FUNCTION (val)) == USING_DECL)
-       {
-         /* An overload with a dependent USING_DECL.  Does the caller
-            want the USING_DECL or the functions?  */
-         if (type_or_fns < 0)
-           val = OVL_CHAIN (val);
-         else
-           val = OVL_FUNCTION (val);  
-       }
     }
   else
     {
@@ -2737,6 +2729,13 @@ check_local_shadow (tree decl)
               && (same_type_p (TREE_TYPE (old), TREE_TYPE (decl))
                   || (!dependent_type_p (TREE_TYPE (decl))
                       && !dependent_type_p (TREE_TYPE (old))
+                      /* If the new decl uses auto, we don't yet know
+                         its type (the old type cannot be using auto
+                         at this point, without also being
+                         dependent).  This is an indication we're
+                         (now) doing the shadow checking too
+                         early.  */
+                      && !type_uses_auto (TREE_TYPE (decl))
                       && can_convert (TREE_TYPE (old), TREE_TYPE (decl),
                                       tf_none))))
        warning_code = OPT_Wshadow_compatible_local;
@@ -5864,10 +5863,21 @@ consider_binding_level (tree name, best_match <tree, const char *> &bm,
          && DECL_ANTICIPATED (d))
        continue;
 
+      /* Skip compiler-generated variables (e.g. __for_begin/__for_end
+        within range for).  */
+      if (TREE_CODE (d) == VAR_DECL
+         && DECL_ARTIFICIAL (d))
+       continue;
+
       tree suggestion = DECL_NAME (d);
       if (!suggestion)
        continue;
 
+      /* Don't suggest names that are for anonymous aggregate types, as
+        they are an implementation detail generated by the compiler.  */
+      if (anon_aggrname_p (suggestion))
+       continue;
+
       const char *suggestion_str = IDENTIFIER_POINTER (suggestion);
 
       /* Ignore internal names with spaces in them.  */
@@ -6624,6 +6634,14 @@ do_pushtag (tree name, tree type, tag_scope scope)
        {
          tree cs = current_scope ();
 
+         /* Avoid setting the lambda context to a current_function_decl that
+            we aren't actually inside, e.g. one set by push_access_scope
+            during tsubst_default_argument.  */
+         if (cs && TREE_CODE (cs) == FUNCTION_DECL
+             && LAMBDA_TYPE_P (type)
+             && !at_function_scope_p ())
+           cs = DECL_CONTEXT (cs);
+
          if (scope == ts_current
              || (cs && TREE_CODE (cs) == FUNCTION_DECL))
            context = cs;
@@ -6928,7 +6946,7 @@ do_push_to_top_level (void)
 
   scope_chain = s;
   current_function_decl = NULL_TREE;
-  vec_alloc (current_lang_base, 10);
+  current_lang_base = NULL;
   current_lang_name = lang_name_cplusplus;
   current_namespace = global_namespace;
   push_class_stack ();
@@ -6948,7 +6966,7 @@ do_pop_from_top_level (void)
     invalidate_class_lookup_cache ();
   pop_class_stack ();
 
-  current_lang_base = 0;
+  release_tree_vector (current_lang_base);
 
   scope_chain = s->prev;
   FOR_EACH_VEC_SAFE_ELT (s->old_bindings, i, saved)
index fdb1650..df6421f 100644 (file)
@@ -46,6 +46,8 @@ update_cloned_parm (tree parm, tree cloned_parm, bool first)
   /* We may have taken its address.  */
   TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
 
+  DECL_BY_REFERENCE (cloned_parm) = DECL_BY_REFERENCE (parm);
+
   /* The definition might have different constness.  */
   TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
 
@@ -59,6 +61,25 @@ update_cloned_parm (tree parm, tree cloned_parm, bool first)
   DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
 }
 
+/* Like copy_decl_no_change, but handle DECL_OMP_PRIVATIZED_MEMBER
+   properly.  */
+
+static tree
+cxx_copy_decl (tree decl, copy_body_data *id)
+{
+  tree copy = copy_decl_no_change (decl, id);
+  if (VAR_P (decl)
+      && DECL_HAS_VALUE_EXPR_P (decl)
+      && DECL_ARTIFICIAL (decl)
+      && DECL_LANG_SPECIFIC (decl)
+      && DECL_OMP_PRIVATIZED_MEMBER (decl))
+    {
+      tree expr = DECL_VALUE_EXPR (copy);
+      walk_tree (&expr, copy_tree_body_r, id, NULL);
+      SET_DECL_VALUE_EXPR (copy, expr);
+    }
+  return copy;
+}
 
 /* FN is a function in High GIMPLE form that has a complete body and no
    CFG.  CLONE is a function whose body is to be set to a copy of FN,
@@ -78,7 +99,7 @@ clone_body (tree clone, tree fn, void *arg_map)
   id.src_cfun = DECL_STRUCT_FUNCTION (fn);
   id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map);
 
-  id.copy_decl = copy_decl_no_change;
+  id.copy_decl = cxx_copy_decl;
   id.transform_call_graph_edges = CB_CGE_DUPLICATE;
   id.transform_new_cfg = true;
   id.transform_return_to_modify = false;
@@ -386,6 +407,8 @@ maybe_thunk_body (tree fn, bool force)
                  gcc_assert (clone_parm);
                  DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
                  args[parmno] = clone_parm;
+                 /* Clear TREE_ADDRESSABLE on thunk arguments.  */
+                 TREE_ADDRESSABLE (clone_parm) = 0;
                  clone_parm = TREE_CHAIN (clone_parm);
                }
              if (fn_parm_typelist)
index d8ce28a..18b09af 100644 (file)
@@ -2243,7 +2243,7 @@ static tree cp_parser_default_argument
 static void cp_parser_function_body
   (cp_parser *, bool);
 static tree cp_parser_initializer
-  (cp_parser *, bool *, bool *);
+  (cp_parser *, bool *, bool *, bool = false);
 static cp_expr cp_parser_initializer_clause
   (cp_parser *, bool *);
 static cp_expr cp_parser_braced_list
@@ -5609,6 +5609,9 @@ cp_parser_primary_expression (cp_parser *parser,
              }
          }
 
+       if (processing_template_decl && is_overloaded_fn (decl))
+         lookup_keep (get_fns (decl), true);
+
        decl = (finish_id_expression
                (id_expression, decl, parser->scope,
                 idk,
@@ -7147,14 +7150,19 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                else if (!args->is_empty ()
                         && is_overloaded_fn (postfix_expression))
                  {
+                   /* We only need to look at the first function,
+                      because all the fns share the attribute we're
+                      concerned with (all member fns or all local
+                      fns).  */
                    tree fn = get_first_fn (postfix_expression);
                    fn = STRIP_TEMPLATE (fn);
 
                    /* Do not do argument dependent lookup if regular
                       lookup finds a member function or a block-scope
                       function declaration.  [basic.lookup.argdep]/3  */
-                   if (!DECL_FUNCTION_MEMBER_P (fn)
-                       && !DECL_LOCAL_FUNCTION_P (fn))
+                   if (!((TREE_CODE (fn) == USING_DECL && DECL_DEPENDENT_P (fn))
+                         || DECL_FUNCTION_MEMBER_P (fn)
+                         || DECL_LOCAL_FUNCTION_P (fn)))
                      {
                        koenig_p = true;
                        if (!any_type_dependent_arguments_p (args))
@@ -7494,10 +7502,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
         access (5.2.5) outside the member function body.  */
       if (postfix_expression != current_class_ref
          && scope != error_mark_node
-         && !(processing_template_decl
-              && current_class_type
-              && (same_type_ignoring_top_level_qualifiers_p
-                  (scope, current_class_type))))
+         && !currently_open_class (scope))
        {
          scope = complete_type (scope);
          if (!COMPLETE_TYPE_P (scope)
@@ -10358,7 +10363,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
                     "lambda capture initializers "
                     "only available with -std=c++14 or -std=gnu++14&q