This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 15337, 14777, 15554, 15057, 15766
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 7 Jun 2004 09:21:12 -0700
- Subject: C++ PATCH: PR 15337, 14777, 15554, 15057, 15766
- Reply-to: mark at codesourcery dot com
This patch fixes (or partially fixes) a few more C++ regressions.
* PR 15337
Some code got commonized between the C/C++ front ends, and at that
time the C front end didn't support "%T" in error messages, so an
error message got worse. Then, we commonized the "%T" stuff -- but
didn't fix the error message. (This is part of why I think we
should be trying to mush together the front ends, not trying to
abstract away commonality.)
* PR 15766
This PR is really several bug reports squished together about
imperfect error message from the C++ front end. This patch fixes
the easiest one -- a typo in an error message that makes us report
the nonsensical "expected `;' before ';'".
* PR 14777
We were forgetting not to defer access checks when instantiaing a
default argument, with the result that we sometimes did the checks
in an incorrect context, issuing spurious error messages. There is
another problem in the PR, but that one is an accepts-invalid,
probably not a regression, and much harder to fix.
* PR 15554
We were crashing on a semi-self-referential case involving templates
and enumeration constants.
* PR 15057
We forgot to initialize a variable in the front end. Oops.
Tested on i686-pc-linux-gnu, applied on the mainline and on the
branch.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2004-06-07 Mark Mitchell <mark@codesourcery.com>
PR c++/15337
* c-common.c (c_sizeof_or_alignof_type): Use more detailed error
message.
2004-06-07 Mark Mitchell <mark@codesourcery.com>
PR c++/15766
* parser.c (cp_parser_iteration_statement): Fix typo in error
message.
PR c++/14777
* pt.c (tsubst_default_argument): Do not defer access checks
while substituting into the default argument.
PR c++/15554
* pt.c (tsubst_copy): Do not try to substitute for an enumeration
constant in a non-dependent context.
PR c++/15057
* except.c (build_throw): Ensure that temp_expr has been
initialized.
2004-06-07 Mark Mitchell <mark@codesourcery.com>
PR c++/15337
* g++.dg/expr/sizeof3.C: New test.
PR c++/14777
* g++.dg/template/access14.C: New test.
PR c++/15554
* g++.dg/template/enum1.C: New test.
PR c++/15057
* g++.dg/eh/throw1.C: New test.
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.476.4.6
diff -c -5 -p -r1.476.4.6 c-common.c
*** c-common.c 19 Mar 2004 01:32:59 -0000 1.476.4.6
--- c-common.c 7 Jun 2004 15:40:17 -0000
*************** c_sizeof_or_alignof_type (tree type, enu
*** 2946,2956 ****
value = size_one_node;
}
else if (!COMPLETE_TYPE_P (type))
{
if (complain)
! error ("invalid application of `%s' to an incomplete type", op_name);
value = size_zero_node;
}
else
{
if (op == SIZEOF_EXPR)
--- 2946,2957 ----
value = size_one_node;
}
else if (!COMPLETE_TYPE_P (type))
{
if (complain)
! error ("invalid application of `%s' to incomplete type `%T' ",
! op_name, type);
value = size_zero_node;
}
else
{
if (op == SIZEOF_EXPR)
Index: cp/except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/except.c,v
retrieving revision 1.164.4.4
diff -c -5 -p -r1.164.4.4 except.c
*** cp/except.c 10 Mar 2004 21:04:13 -0000 1.164.4.4
--- cp/except.c 7 Jun 2004 15:40:18 -0000
*************** build_throw (tree exp)
*** 682,691 ****
--- 682,692 ----
Note that we don't check the return value from stabilize_init
because it will only return false in cases where elided is true,
and therefore we don't need to work around the failure to
preevaluate. */
+ temp_expr = NULL_TREE;
stabilize_init (exp, &temp_expr);
if (elided)
exp = build (TRY_CATCH_EXPR, void_type_node, exp,
do_free_exception (ptr));
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.157.2.29
diff -c -5 -p -r1.157.2.29 parser.c
*** cp/parser.c 28 May 2004 20:12:07 -0000 1.157.2.29
--- cp/parser.c 7 Jun 2004 15:40:18 -0000
*************** cp_parser_iteration_statement (cp_parser
*** 5954,5965 ****
/* If there's an expression, process it. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
expression = cp_parser_expression (parser);
finish_for_expr (expression, statement);
/* Look for the `)'. */
! cp_parser_require (parser, CPP_CLOSE_PAREN, "`;'");
!
/* Parse the body of the for-statement. */
parser->in_iteration_statement_p = true;
cp_parser_already_scoped_statement (parser);
parser->in_iteration_statement_p = in_iteration_statement_p;
--- 5954,5965 ----
/* If there's an expression, process it. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
expression = cp_parser_expression (parser);
finish_for_expr (expression, statement);
/* Look for the `)'. */
! cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
!
/* Parse the body of the for-statement. */
parser->in_iteration_statement_p = true;
cp_parser_already_scoped_statement (parser);
parser->in_iteration_statement_p = in_iteration_statement_p;
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.816.2.27
diff -c -5 -p -r1.816.2.27 pt.c
*** cp/pt.c 31 May 2004 21:04:11 -0000 1.816.2.27
--- cp/pt.c 7 Jun 2004 15:40:19 -0000
*************** tsubst_default_argument (tree fn, tree t
*** 5881,5906 ****
static T t();
void f(T = t());
};
we must be careful to do name lookup in the scope of S<T>,
! rather than in the current class.
!
! ??? current_class_type affects a lot more than name lookup. This is
! very fragile. Fortunately, it will go away when we do 2-phase name
! binding properly. */
!
! /* FN is already the desired FUNCTION_DECL. */
push_access_scope (fn);
/* The default argument expression should not be considered to be
within the scope of FN. Since push_access_scope sets
current_function_decl, we must explicitly clear it here. */
current_function_decl = NULL_TREE;
arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
tf_error | tf_warning, NULL_TREE);
!
pop_access_scope (fn);
/* Make sure the default argument is reasonable. */
arg = check_default_argument (type, arg);
--- 5881,5902 ----
static T t();
void f(T = t());
};
we must be careful to do name lookup in the scope of S<T>,
! rather than in the current class. */
push_access_scope (fn);
/* The default argument expression should not be considered to be
within the scope of FN. Since push_access_scope sets
current_function_decl, we must explicitly clear it here. */
current_function_decl = NULL_TREE;
+ push_deferring_access_checks(dk_no_deferred);
arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
tf_error | tf_warning, NULL_TREE);
! pop_deferring_access_checks();
!
pop_access_scope (fn);
/* Make sure the default argument is reasonable. */
arg = check_default_argument (type, arg);
*************** tsubst_copy (tree t, tree args, tsubst_f
*** 7409,7418 ****
--- 7405,7417 ----
return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
/* There is no need to substitute into namespace-scope
enumerators. */
if (DECL_NAMESPACE_SCOPE_P (t))
return t;
+ /* If ARGS is NULL, then T is known to be non-dependent. */
+ if (args == NULL_TREE)
+ return t;
/* Unfortunately, we cannot just call lookup_name here.
Consider:
template <int I> int f() {
Index: testsuite/g++.dg/eh/throw1.C
===================================================================
RCS file: testsuite/g++.dg/eh/throw1.C
diff -N testsuite/g++.dg/eh/throw1.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/eh/throw1.C 7 Jun 2004 15:40:20 -0000
***************
*** 0 ****
--- 1,9 ----
+ class S
+ {
+ public:
+ S(){}
+ };
+
+ int foo(char* m1) {
+ throw (m1 ? S() : S());
+ }
Index: testsuite/g++.dg/expr/sizeof3.C
===================================================================
RCS file: testsuite/g++.dg/expr/sizeof3.C
diff -N testsuite/g++.dg/expr/sizeof3.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/expr/sizeof3.C 7 Jun 2004 15:40:20 -0000
***************
*** 0 ****
--- 1,4 ----
+ // PR c++/15337
+
+ class CCC;
+ int main() { sizeof(CCC); return 0; } // { dg-error ".*CCC.*" }
Index: testsuite/g++.dg/template/access14.C
===================================================================
RCS file: testsuite/g++.dg/template/access14.C
diff -N testsuite/g++.dg/template/access14.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/access14.C 7 Jun 2004 15:40:20 -0000
***************
*** 0 ****
--- 1,16 ----
+ // PR c++/14777
+
+ template <typename T>
+ struct B
+ {
+ protected:
+ typedef int M;
+ };
+
+ template <typename T>
+ struct A : B<T> {
+ typedef typename B<T>::M N;
+ A (int = N ());
+ };
+
+ A<int> a = A<int> ();
Index: testsuite/g++.dg/template/enum1.C
===================================================================
RCS file: testsuite/g++.dg/template/enum1.C
diff -N testsuite/g++.dg/template/enum1.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/enum1.C 7 Jun 2004 15:40:20 -0000
***************
*** 0 ****
--- 1,5 ----
+ // PR c++/15554
+
+ template <int n> struct T1 { enum { N = 3 }; };
+ template <int n> struct T2 { enum { N = 3, N1 = T1<N>::N }; };
+