This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 14369
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 1 Mar 2004 21:49:22 -0800
- Subject: C++ PATCH: PR 14369
- Reply-to: mark at codesourcery dot com
PR 14369 is a problem with the ?: operator in a template when the
second or third argument is a throw-expression. There are special
rules about that case in the standard, and creating a
NON_DEPENDENT_EXPR for the thrown value causes us to lose track of the
fact that these arguments are throw-expressions. We shouldn't need a
NON_DEPDENENT_EXPR in this case; nothing is going to do anything with
the expression. So, this patch causes us not to create a
NON_DEPENDENT_EXPR in that case.
Tested on i686-pc-linux-gnu, applied on the mainline and on the
3.4 branch.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2004-03-01 Mark Mitchell <mark@codesourcery.com>
PR c++/14369
* pt.c (build_non_dependent_expr): Do not create a
NON_DEPENDENT_EXPR for a THROW_EXPR.
2004-03-01 Mark Mitchell <mark@codesourcery.com>
PR c++/14369
* g++.dg/template/cond4.C: New test.
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.816.2.16
diff -c -5 -p -r1.816.2.16 pt.c
*** cp/pt.c 2 Mar 2004 02:00:00 -0000 1.816.2.16
--- cp/pt.c 2 Mar 2004 05:45:06 -0000
*************** build_non_dependent_expr (tree expr)
*** 12108,12117 ****
--- 12108,12124 ----
return expr;
/* Preserve arithmetic constants, as an optimization -- there is no
reason to create a new node. */
if (TREE_CODE (expr) == INTEGER_CST || TREE_CODE (expr) == REAL_CST)
return expr;
+ /* Preserve THROW_EXPRs -- all throw-expressions have type "void".
+ There is at least one place where we want to know that a
+ particular expression is a throw-expression: when checking a ?:
+ expression, there are special rules if the second or third
+ argument is a throw-expresion. */
+ if (TREE_CODE (expr) == THROW_EXPR)
+ return expr;
if (TREE_CODE (expr) == COND_EXPR)
return build (COND_EXPR,
TREE_TYPE (expr),
TREE_OPERAND (expr, 0),
Index: testsuite/g++.dg/template/cond4.C
===================================================================
RCS file: testsuite/g++.dg/template/cond4.C
diff -N testsuite/g++.dg/template/cond4.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/cond4.C 2 Mar 2004 05:45:06 -0000
***************
*** 0 ****
--- 1,20 ----
+ // PR c++/14369
+
+ struct A { };
+
+ template<class T>
+ struct X : A {
+ const A* bar() const
+ { return this; }
+
+ const A& foo() const;
+ };
+
+ template<class T>
+ const A& X<T>::foo() const
+ {
+ const A* t = bar();
+ return *(t ? t : throw 0);
+ }
+
+