From 109e00403a6044810028032054543fc8dcfeed3a Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Thu, 10 Jun 2004 14:26:23 +0000 Subject: [PATCH] re PR c++/15227 (Trouble with invalid function definition) PR c++/15227 * parser.c (cp_parser_direct_declarator): Robustify. PR c++/15877 * pt.c (tsubst_copy): Use decl_constant_value on enumeration constants in non-dependent contexts. PR c++/14211 PR c++/15076 * typeck.c (build_static_cast): Wrap casts in NON_LVALUE_EXPR when necessary. PR c++/14211 * g++.dg/conversion/const1.C: New test. PR c++/15076 * g++.dg/conversion/reinterpret1.C: New test. PR c++/15877 * g++.dg/template/enum2.C: New test. PR c++/15227 * g++.dg/template/error13.C: New test. From-SVN: r82917 --- gcc/cp/ChangeLog | 14 ++++++++++++++ gcc/cp/parser.c | 6 ++++-- gcc/cp/pt.c | 2 +- gcc/cp/typeck.c | 12 +++++++++++- gcc/testsuite/g++.dg/conversion/const1.C | 5 +++++ gcc/testsuite/g++.dg/conversion/reinterpret1.C | 6 ++++++ gcc/testsuite/g++.dg/template/enum2.C | 4 ++++ gcc/testsuite/g++.dg/template/error13.C | 5 +++++ 8 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/conversion/const1.C create mode 100644 gcc/testsuite/g++.dg/conversion/reinterpret1.C create mode 100644 gcc/testsuite/g++.dg/template/enum2.C create mode 100644 gcc/testsuite/g++.dg/template/error13.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c080fb3aba7..5f49e4ba24f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2004-06-10 Mark Mitchell + + PR c++/15227 + * parser.c (cp_parser_direct_declarator): Robustify. + + PR c++/15877 + * pt.c (tsubst_copy): Use decl_constant_value on enumeration + constants in non-dependent contexts. + + PR c++/14211 + PR c++/15076 + * typeck.c (build_static_cast): Wrap casts in NON_LVALUE_EXPR when + necessary. + 2004-06-10 Jakub Jelinek PR c++/14791 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a90dabd0c8c..17242ba3457 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10726,8 +10726,10 @@ cp_parser_direct_declarator (cp_parser* parser, type = resolve_typename_type (scope, /*only_current_p=*/false); /* If that failed, the declarator is invalid. */ - if (type != error_mark_node) - scope = type; + if (type == error_mark_node) + error ("`%T::%D' is not a type", + TYPE_CONTEXT (scope), + TYPE_IDENTIFIER (scope)); /* Build a new DECLARATOR. */ declarator = build_nt (SCOPE_REF, scope, diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8e29e244f71..fd75f78cd9a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7421,7 +7421,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) return t; /* If ARGS is NULL, then T is known to be non-dependent. */ if (args == NULL_TREE) - return t; + return decl_constant_value (t); /* Unfortunately, we cannot just call lookup_name here. Consider: diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 5e5dcc4a2ae..bcdd316131b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4535,7 +4535,17 @@ build_static_cast (tree type, tree expr) t. */ result = perform_direct_initialization_if_possible (type, expr); if (result) - return convert_from_reference (result); + { + result = convert_from_reference (result); + /* [expr.static.cast] + + If T is a reference type, the result is an lvalue; otherwise, + the result is an rvalue. */ + if (TREE_CODE (type) != REFERENCE_TYPE + && real_lvalue_p (result)) + result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result); + return result; + } /* [expr.static.cast] diff --git a/gcc/testsuite/g++.dg/conversion/const1.C b/gcc/testsuite/g++.dg/conversion/const1.C new file mode 100644 index 00000000000..5e43bc06397 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/const1.C @@ -0,0 +1,5 @@ +// PR c++/14211 + +void f(char *str) { + char *& m = const_cast(str); // { dg-error "" } +} diff --git a/gcc/testsuite/g++.dg/conversion/reinterpret1.C b/gcc/testsuite/g++.dg/conversion/reinterpret1.C new file mode 100644 index 00000000000..72ec7501219 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/reinterpret1.C @@ -0,0 +1,6 @@ +// PR c++/15076 + +struct Y { Y(int &); }; // { dg-error "" } + +int v; +Y y1(reinterpret_cast(v)); // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/enum2.C b/gcc/testsuite/g++.dg/template/enum2.C new file mode 100644 index 00000000000..7a6c2072a75 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/enum2.C @@ -0,0 +1,4 @@ +// PR c++/15877 + +template struct T1 { enum { N = 3 }; }; +template struct T2 { enum { N = n, N1 = T1::N }; }; diff --git a/gcc/testsuite/g++.dg/template/error13.C b/gcc/testsuite/g++.dg/template/error13.C new file mode 100644 index 00000000000..13d8794d785 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error13.C @@ -0,0 +1,5 @@ +// PR c++/15227 + +template struct A {}; + +template void A::B::foo() {} // { dg-error "" } -- 2.30.2