diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index df0297ae5b2..ba2ee1a2acf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2003-10-21 Mark Mitchell + + PR c++/11962 + * typeck.c (build_x_conditional_expr): Handle missing middle + operands in templates. + * mangle.c (write_expression): Issue errors about attempts to + mangle a non-existant middle operator to the ?: operator. + 2003-10-21 Robert Bowdidge * decl.c (cp_finish_decl): Remove clause intended for asm directives in struct or class fields: this code is never executed. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index c8b3a84ddde..15334f321e3 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2041,7 +2041,21 @@ write_expression (tree expr) default: for (i = 0; i < TREE_CODE_LENGTH (code); ++i) - write_expression (TREE_OPERAND (expr, i)); + { + tree operand = TREE_OPERAND (expr, i); + /* As a GNU expression, the middle operand of a + conditional may be omitted. Since expression + manglings are supposed to represent the input token + stream, there's no good way to mangle such an + expression without extending the C++ ABI. */ + if (code == COND_EXPR && i == 1 && !operand) + { + error ("omitted middle operand to `?:' operand " + "cannot be mangled"); + continue; + } + write_expression (operand); + } } } } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index f2111512066..e469a5ace7e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4284,11 +4284,13 @@ build_x_conditional_expr (tree ifexp, tree op1, tree op2) IFEXP is type-dependent, even though the eventual type of the expression doesn't dependent on IFEXP. */ if (type_dependent_expression_p (ifexp) - || type_dependent_expression_p (op1) + /* As a GNU extension, the middle operand may be omitted. */ + || (op1 && type_dependent_expression_p (op1)) || type_dependent_expression_p (op2)) return build_min_nt (COND_EXPR, ifexp, op1, op2); ifexp = build_non_dependent_expr (ifexp); - op1 = build_non_dependent_expr (op1); + if (op1) + op1 = build_non_dependent_expr (op1); op2 = build_non_dependent_expr (op2); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a4509ebb3e9..5153e076400 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-10-21 Mark Mitchell + + PR c++/11962 + * g++.dg/template/cond2.C: New test. + 2003-10-20 Joseph S. Myers * gcc.dg/builtins-28.c: New test. diff --git a/gcc/testsuite/g++.dg/template/cond2.C b/gcc/testsuite/g++.dg/template/cond2.C new file mode 100644 index 00000000000..abb6ebb5d46 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/cond2.C @@ -0,0 +1,10 @@ +// PR c++/11962 +// { dg-options "" } + +template class c; + +template int test(c&); + +void test(c<2>*c2) { + test<0, 2>(*c2); // { dg-error "omitted" } +}