aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2008-01-25 14:45:11 -0500
committerJason Merrill <jason@gcc.gnu.org>2008-01-25 14:45:11 -0500
commitb6219f420890d1f8e4eb4bc586499c75f4612f38 (patch)
treed63ed006c4a66749f6e6342f438d45f7bd2ec881
parent7fa4b30a1674de01bf12aef706415e876aa08e4f (diff)
downloadgcc-b6219f420890d1f8e4eb4bc586499c75f4612f38.zip
gcc-b6219f420890d1f8e4eb4bc586499c75f4612f38.tar.gz
gcc-b6219f420890d1f8e4eb4bc586499c75f4612f38.tar.bz2
re PR c++/31780 (ICE with incompatible types for ?: with "complex type" conversion)
PR c++/31780 * call.c (standard_conversion): Allow conversion from integer/real to complex. (compare_ics): Such a conversion is worse than a normal arithmetic conversion. Co-Authored-By: Mark Mitchell <mark@codesourcery.com> From-SVN: r131832
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/call.c27
-rw-r--r--gcc/testsuite/g++.dg/ext/complex3.C28
3 files changed, 58 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4dca2f1..9383ccd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2008-01-25 Jason Merrill <jason@redhat.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/31780
+ * call.c (standard_conversion): Allow conversion from integer/real
+ to complex.
+ (compare_ics): Such a conversion is worse than a normal arithmetic
+ conversion.
+
2008-01-25 Richard Guenther <rguenther@suse.de>
PR c++/33887
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 1e591a6..3cd80b4 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -846,8 +846,8 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
}
/* We don't check for ENUMERAL_TYPE here because there are no standard
conversions to enum type. */
- else if (tcode == INTEGER_TYPE || tcode == BOOLEAN_TYPE
- || tcode == REAL_TYPE)
+ /* As an extension, allow conversion to complex type. */
+ else if (ARITHMETIC_TYPE_P (to))
{
if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE))
return NULL;
@@ -5937,6 +5937,10 @@ compare_ics (conversion *ics1, conversion *ics2)
from_type2 = t2->type;
}
+ /* One sequence can only be a subsequence of the other if they start with
+ the same type. They can start with different types when comparing the
+ second standard conversion sequence in two user-defined conversion
+ sequences. */
if (same_type_p (from_type1, from_type2))
{
if (is_subseq (ics1, ics2))
@@ -5944,10 +5948,6 @@ compare_ics (conversion *ics1, conversion *ics2)
if (is_subseq (ics2, ics1))
return -1;
}
- /* Otherwise, one sequence cannot be a subsequence of the other; they
- don't start with the same type. This can happen when comparing the
- second standard conversion sequence in two user-defined conversion
- sequences. */
/* [over.ics.rank]
@@ -5977,6 +5977,21 @@ compare_ics (conversion *ics1, conversion *ics2)
to_type1 = ics1->type;
to_type2 = ics2->type;
+ /* A conversion from scalar arithmetic type to complex is worse than a
+ conversion between scalar arithmetic types. */
+ if (same_type_p (from_type1, from_type2)
+ && ARITHMETIC_TYPE_P (from_type1)
+ && ARITHMETIC_TYPE_P (to_type1)
+ && ARITHMETIC_TYPE_P (to_type2)
+ && ((TREE_CODE (to_type1) == COMPLEX_TYPE)
+ != (TREE_CODE (to_type2) == COMPLEX_TYPE)))
+ {
+ if (TREE_CODE (to_type1) == COMPLEX_TYPE)
+ return -1;
+ else
+ return 1;
+ }
+
if (TYPE_PTR_P (from_type1)
&& TYPE_PTR_P (from_type2)
&& TYPE_PTR_P (to_type1)
diff --git a/gcc/testsuite/g++.dg/ext/complex3.C b/gcc/testsuite/g++.dg/ext/complex3.C
new file mode 100644
index 0000000..062c2d4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/complex3.C
@@ -0,0 +1,28 @@
+// PR c++/31780
+// { dg-do run }
+// { dg-options "" }
+
+// Test that we can implicitly convert to _Complex, but that it's worse
+// than a scalar arithmetic conversion.
+
+extern "C" void exit (int);
+
+int r = 0;
+
+void f (_Complex int) { ++r; }
+void f (double) { }
+
+void g (_Complex int) { }
+
+int main()
+{
+ f (1);
+ g (1);
+
+ return r;
+}
+
+void bar()
+{
+ r ? 0i : 0;
+}