aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/class.cc3
-rw-r--r--gcc/cp/decl2.cc4
-rw-r--r--gcc/cp/pt.cc2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-nondep6.C12
-rw-r--r--gcc/testsuite/gnat.dg/opt106.adb11
-rw-r--r--gcc/testsuite/gnat.dg/opt106_pkg1.adb39
-rw-r--r--gcc/testsuite/gnat.dg/opt106_pkg1.ads16
-rw-r--r--gcc/testsuite/gnat.dg/opt106_pkg2.adb11
-rw-r--r--gcc/testsuite/gnat.dg/opt106_pkg2.ads8
-rw-r--r--gcc/tree-vect-stmts.cc139
-rw-r--r--gcc/vr-values.cc11
11 files changed, 191 insertions, 65 deletions
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 370bfa3..2764bb5 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -5744,6 +5744,9 @@ type_has_converting_constructor (tree t)
{
tree fn = *iter;
tree parm = FUNCTION_FIRST_USER_PARMTYPE (fn);
+ if (parm == NULL_TREE)
+ /* Varargs. */
+ return true;
if (parm == void_list_node
|| !sufficient_parms_p (TREE_CHAIN (parm)))
/* Can't accept a single argument, so won't be considered for
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 21156f1..15db1d6 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -3160,7 +3160,9 @@ determine_visibility (tree decl)
&& !attr)
{
int depth = TMPL_ARGS_DEPTH (args);
- if (DECL_VISIBILITY_SPECIFIED (decl))
+ if (DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (TI_TEMPLATE (tinfo)))
+ /* Class template args don't affect template friends. */;
+ else if (DECL_VISIBILITY_SPECIFIED (decl))
{
/* A class template member with explicit visibility
overrides the class visibility, so we need to apply
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 0694c28..09f74a2 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -23254,7 +23254,7 @@ fn_type_unification (tree fn,
conversions that we know are not going to induce template instantiation
(PR99599). */
if (strict == DEDUCE_CALL
- && incomplete
+ && incomplete && flag_concepts
&& check_non_deducible_conversions (parms, args, nargs, fn, strict, flags,
convs, explain_p,
/*noninst_only_p=*/true))
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-nondep6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-nondep6.C
new file mode 100644
index 0000000..7adf6ec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-nondep6.C
@@ -0,0 +1,12 @@
+// PR c++/120185
+
+struct A {
+ A(...);
+};
+
+template <class T> void f(A, T) { }
+
+int main()
+{
+ f(42, 24);
+}
diff --git a/gcc/testsuite/gnat.dg/opt106.adb b/gcc/testsuite/gnat.dg/opt106.adb
new file mode 100644
index 0000000..525930b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt106.adb
@@ -0,0 +1,11 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with Opt106_Pkg1; use Opt106_Pkg1;
+
+procedure Opt106 is
+ Obj : T := (False, 0, 0, 0, True);
+
+begin
+ Proc (Obj, 0, False, True);
+end;
diff --git a/gcc/testsuite/gnat.dg/opt106_pkg1.adb b/gcc/testsuite/gnat.dg/opt106_pkg1.adb
new file mode 100644
index 0000000..154b13f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt106_pkg1.adb
@@ -0,0 +1,39 @@
+with Opt106_Pkg2; use Opt106_Pkg2;
+
+package body Opt106_Pkg1 is
+
+ procedure Proc (Obj : in out T;
+ Data : Integer;
+ Last : Boolean;
+ Stretch : Boolean) is
+
+ begin
+ if Stretch and then (Obj.Delayed /= 0 or else not Obj.Attach_Last) then
+ raise Program_Error;
+ end if;
+
+ if Obj.Delayed /= 0 then
+ Stop (Obj.Delayed, Obj.Before, Data, False);
+ end if;
+
+ if Last or (Obj.Delayed = 0 and not Stretch) then
+ Stop (Data, Obj.Before, 0, Last);
+
+ if Last then
+ Obj.Initialized := False;
+ else
+ Obj.Next := 0;
+ Obj.Before := Data;
+ end if;
+
+ else
+ if Stretch then
+ Obj.Next := 1;
+ else
+ Obj.Before := Obj.Delayed;
+ end if;
+ Obj.Delayed := Data;
+ end if;
+ end;
+
+end Opt106_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/opt106_pkg1.ads b/gcc/testsuite/gnat.dg/opt106_pkg1.ads
new file mode 100644
index 0000000..85ac24d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt106_pkg1.ads
@@ -0,0 +1,16 @@
+package Opt106_Pkg1 is
+
+ type T is record
+ Initialized : Boolean;
+ Before : Integer;
+ Delayed : Integer;
+ Next : Integer;
+ Attach_Last : Boolean;
+ end record;
+
+ procedure Proc (Obj : in out T;
+ Data : Integer;
+ Last : Boolean;
+ Stretch : Boolean);
+
+end Opt106_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/opt106_pkg2.adb b/gcc/testsuite/gnat.dg/opt106_pkg2.adb
new file mode 100644
index 0000000..cf63956
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt106_pkg2.adb
@@ -0,0 +1,11 @@
+package body Opt106_Pkg2 is
+
+ procedure Stop (Delayed : Integer;
+ Before : Integer;
+ After : Integer;
+ Last : Boolean) is
+ begin
+ raise Program_Error;
+ end;
+
+end Opt106_Pkg2;
diff --git a/gcc/testsuite/gnat.dg/opt106_pkg2.ads b/gcc/testsuite/gnat.dg/opt106_pkg2.ads
new file mode 100644
index 0000000..77e5b40
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt106_pkg2.ads
@@ -0,0 +1,8 @@
+package Opt106_Pkg2 is
+
+ procedure Stop (Delayed : Integer;
+ Before : Integer;
+ After : Integer;
+ Last : Boolean);
+
+end Opt106_Pkg2;
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index ae9644a..efe6a2c 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -7025,9 +7025,10 @@ vectorizable_operation (vec_info *vinfo,
ops we have to lower the lowering code assumes we are
dealing with word_mode. */
if (!INTEGRAL_TYPE_P (TREE_TYPE (vectype))
+ || !GET_MODE_SIZE (vec_mode).is_constant ()
|| (((code == PLUS_EXPR || code == MINUS_EXPR || code == NEGATE_EXPR)
- || !target_support_p)
- && maybe_ne (GET_MODE_SIZE (vec_mode), UNITS_PER_WORD))
+ || !target_support_p)
+ && maybe_ne (GET_MODE_SIZE (vec_mode), UNITS_PER_WORD))
/* Check only during analysis. */
|| (!vec_stmt && !vect_can_vectorize_without_simd_p (code)))
{
@@ -7167,88 +7168,108 @@ vectorizable_operation (vec_info *vinfo,
vop1 = ((op_type == binary_op || op_type == ternary_op)
? vec_oprnds1[i] : NULL_TREE);
vop2 = ((op_type == ternary_op) ? vec_oprnds2[i] : NULL_TREE);
- if (using_emulated_vectors_p
- && (code == PLUS_EXPR || code == MINUS_EXPR || code == NEGATE_EXPR))
+ if (using_emulated_vectors_p)
{
/* Lower the operation. This follows vector lowering. */
- unsigned int width = vector_element_bits (vectype);
- tree inner_type = TREE_TYPE (vectype);
- tree word_type
- = build_nonstandard_integer_type (GET_MODE_BITSIZE (word_mode), 1);
- HOST_WIDE_INT max = GET_MODE_MASK (TYPE_MODE (inner_type));
- tree low_bits = build_replicated_int_cst (word_type, width, max >> 1);
- tree high_bits
- = build_replicated_int_cst (word_type, width, max & ~(max >> 1));
+ tree word_type = build_nonstandard_integer_type
+ (GET_MODE_BITSIZE (vec_mode).to_constant (), 1);
tree wvop0 = make_ssa_name (word_type);
new_stmt = gimple_build_assign (wvop0, VIEW_CONVERT_EXPR,
build1 (VIEW_CONVERT_EXPR,
word_type, vop0));
vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
- tree result_low, signs;
- if (code == PLUS_EXPR || code == MINUS_EXPR)
+ tree wvop1 = NULL_TREE;
+ if (vop1)
{
- tree wvop1 = make_ssa_name (word_type);
+ wvop1 = make_ssa_name (word_type);
new_stmt = gimple_build_assign (wvop1, VIEW_CONVERT_EXPR,
build1 (VIEW_CONVERT_EXPR,
word_type, vop1));
vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
- signs = make_ssa_name (word_type);
- new_stmt = gimple_build_assign (signs,
- BIT_XOR_EXPR, wvop0, wvop1);
- vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
- tree b_low = make_ssa_name (word_type);
- new_stmt = gimple_build_assign (b_low,
- BIT_AND_EXPR, wvop1, low_bits);
- vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
- tree a_low = make_ssa_name (word_type);
- if (code == PLUS_EXPR)
- new_stmt = gimple_build_assign (a_low,
- BIT_AND_EXPR, wvop0, low_bits);
- else
- new_stmt = gimple_build_assign (a_low,
- BIT_IOR_EXPR, wvop0, high_bits);
- vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
- if (code == MINUS_EXPR)
+ }
+
+ tree result_low;
+ if (code == PLUS_EXPR || code == MINUS_EXPR || code == NEGATE_EXPR)
+ {
+ unsigned int width = vector_element_bits (vectype);
+ tree inner_type = TREE_TYPE (vectype);
+ HOST_WIDE_INT max = GET_MODE_MASK (TYPE_MODE (inner_type));
+ tree low_bits
+ = build_replicated_int_cst (word_type, width, max >> 1);
+ tree high_bits
+ = build_replicated_int_cst (word_type,
+ width, max & ~(max >> 1));
+ tree signs;
+ if (code == PLUS_EXPR || code == MINUS_EXPR)
{
- new_stmt = gimple_build_assign (NULL_TREE,
- BIT_NOT_EXPR, signs);
+ signs = make_ssa_name (word_type);
+ new_stmt = gimple_build_assign (signs,
+ BIT_XOR_EXPR, wvop0, wvop1);
+ vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+ tree b_low = make_ssa_name (word_type);
+ new_stmt = gimple_build_assign (b_low, BIT_AND_EXPR,
+ wvop1, low_bits);
+ vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+ tree a_low = make_ssa_name (word_type);
+ if (code == PLUS_EXPR)
+ new_stmt = gimple_build_assign (a_low, BIT_AND_EXPR,
+ wvop0, low_bits);
+ else
+ new_stmt = gimple_build_assign (a_low, BIT_IOR_EXPR,
+ wvop0, high_bits);
+ vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+ if (code == MINUS_EXPR)
+ {
+ new_stmt = gimple_build_assign (NULL_TREE,
+ BIT_NOT_EXPR, signs);
+ signs = make_ssa_name (word_type);
+ gimple_assign_set_lhs (new_stmt, signs);
+ vect_finish_stmt_generation (vinfo, stmt_info,
+ new_stmt, gsi);
+ }
+ new_stmt = gimple_build_assign (NULL_TREE, BIT_AND_EXPR,
+ signs, high_bits);
signs = make_ssa_name (word_type);
gimple_assign_set_lhs (new_stmt, signs);
vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+ result_low = make_ssa_name (word_type);
+ new_stmt = gimple_build_assign (result_low, code,
+ a_low, b_low);
+ vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
}
- new_stmt = gimple_build_assign (NULL_TREE,
- BIT_AND_EXPR, signs, high_bits);
- signs = make_ssa_name (word_type);
- gimple_assign_set_lhs (new_stmt, signs);
- vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+ else /* if (code == NEGATE_EXPR) */
+ {
+ tree a_low = make_ssa_name (word_type);
+ new_stmt = gimple_build_assign (a_low, BIT_AND_EXPR,
+ wvop0, low_bits);
+ vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+ signs = make_ssa_name (word_type);
+ new_stmt = gimple_build_assign (signs, BIT_NOT_EXPR, wvop0);
+ vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+ new_stmt = gimple_build_assign (NULL_TREE, BIT_AND_EXPR,
+ signs, high_bits);
+ signs = make_ssa_name (word_type);
+ gimple_assign_set_lhs (new_stmt, signs);
+ vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+ result_low = make_ssa_name (word_type);
+ new_stmt = gimple_build_assign (result_low,
+ MINUS_EXPR, high_bits, a_low);
+ vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+ }
+ new_stmt = gimple_build_assign (NULL_TREE, BIT_XOR_EXPR,
+ result_low, signs);
result_low = make_ssa_name (word_type);
- new_stmt = gimple_build_assign (result_low, code, a_low, b_low);
+ gimple_assign_set_lhs (new_stmt, result_low);
vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
}
else
{
- tree a_low = make_ssa_name (word_type);
- new_stmt = gimple_build_assign (a_low,
- BIT_AND_EXPR, wvop0, low_bits);
- vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
- signs = make_ssa_name (word_type);
- new_stmt = gimple_build_assign (signs, BIT_NOT_EXPR, wvop0);
- vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
- new_stmt = gimple_build_assign (NULL_TREE,
- BIT_AND_EXPR, signs, high_bits);
- signs = make_ssa_name (word_type);
- gimple_assign_set_lhs (new_stmt, signs);
- vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+ new_stmt = gimple_build_assign (NULL_TREE, code, wvop0, wvop1);
result_low = make_ssa_name (word_type);
- new_stmt = gimple_build_assign (result_low,
- MINUS_EXPR, high_bits, a_low);
+ gimple_assign_set_lhs (new_stmt, result_low);
vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+
}
- new_stmt = gimple_build_assign (NULL_TREE, BIT_XOR_EXPR, result_low,
- signs);
- result_low = make_ssa_name (word_type);
- gimple_assign_set_lhs (new_stmt, result_low);
- vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
new_stmt = gimple_build_assign (NULL_TREE, VIEW_CONVERT_EXPR,
build1 (VIEW_CONVERT_EXPR,
vectype, result_low));
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 6603d90..4c78759 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -1996,10 +1996,13 @@ simplify_using_ranges::simplify (gimple_stmt_iterator *gsi)
case BIT_AND_EXPR:
case BIT_IOR_EXPR:
- /* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR
- if all the bits being cleared are already cleared or
- all the bits being set are already set. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
+ /* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR if all the bits
+ being cleared are already cleared or all the bits being set
+ are already set. Beware that boolean types must be handled
+ logically (see range-op.cc) unless they have precision 1. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+ && (TREE_CODE (TREE_TYPE (rhs1)) != BOOLEAN_TYPE
+ || TYPE_PRECISION (TREE_TYPE (rhs1)) == 1))
return simplify_bit_ops_using_ranges (gsi, stmt);
break;