PR c++/27666
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Jun 2006 02:33:35 +0000 (02:33 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Jun 2006 02:33:35 +0000 (02:33 +0000)
* call.c (build_conditional_expr): Robustify.
PR c++/27666
* g++.dg/expr/cond9.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114702 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/expr/cond9.C [new file with mode: 0644]

index f80d362..778658a 100644 (file)
@@ -1,5 +1,8 @@
 2006-06-15  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/27666
+       * call.c (build_conditional_expr): Robustify.
+
        PR c++/27640
        * pt.c (instantiate_template): Set processing_template_decl to
        zero while performing substitutions.
index db8dd21..cd82732 100644 (file)
@@ -3322,12 +3322,21 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
          arg2 = convert_like (conv2, arg2);
          arg2 = convert_from_reference (arg2);
          arg2_type = TREE_TYPE (arg2);
+         /* Even if CONV2 is a valid conversion, the result of the
+            conversion may be invalid.  For example, if ARG3 has type
+            "volatile X", and X does not have a copy constructor
+            accepting a "volatile X&", then even if ARG2 can be
+            converted to X, the conversion will fail.  */
+         if (error_operand_p (arg2))
+           result = error_mark_node;
        }
       else if (conv3 && (!conv3->bad_p || !conv2))
        {
          arg3 = convert_like (conv3, arg3);
          arg3 = convert_from_reference (arg3);
          arg3_type = TREE_TYPE (arg3);
+         if (error_operand_p (arg3))
+           result = error_mark_node;
        }
 
       /* Free all the conversions we allocated.  */
index 9f056c3..0696d9a 100644 (file)
@@ -1,5 +1,8 @@
 2006-06-15  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/27666
+       * g++.dg/expr/cond9.C: New test.
+
        PR c++/27640
        * g++.dg/template/ctor7.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/expr/cond9.C b/gcc/testsuite/g++.dg/expr/cond9.C
new file mode 100644 (file)
index 0000000..9e8f08c
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/27666
+
+struct A { // { dg-error "A" }
+  A(int); // { dg-error "A" }
+};
+
+void foo(volatile A a) { 
+  1 ? a : 0; // { dg-error "match|temporary" }
+  1 ? 0 : a; // { dg-error "match|temporary" }
+}