aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-06-10 14:26:23 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-06-10 14:26:23 +0000
commit109e00403a6044810028032054543fc8dcfeed3a (patch)
treeb0a15b965ae2b596d373e44dc59125e68f178fe4 /gcc
parent9655d83b750bc6de0074b0501044d4bcb28679d9 (diff)
downloadgcc-109e00403a6044810028032054543fc8dcfeed3a.zip
gcc-109e00403a6044810028032054543fc8dcfeed3a.tar.gz
gcc-109e00403a6044810028032054543fc8dcfeed3a.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/parser.c6
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/typeck.c12
-rw-r--r--gcc/testsuite/g++.dg/conversion/const1.C5
-rw-r--r--gcc/testsuite/g++.dg/conversion/reinterpret1.C6
-rw-r--r--gcc/testsuite/g++.dg/template/enum2.C4
-rw-r--r--gcc/testsuite/g++.dg/template/error13.C5
8 files changed, 50 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c080fb3..5f49e4b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,17 @@
+2004-06-10 Mark Mitchell <mark@codesourcery.com>
+
+ 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 <jakub@redhat.com>
PR c++/14791
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index a90dabd..17242ba 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 8e29e24..fd75f78 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 5e5dcc4..bcdd316 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 0000000..5e43bc0
--- /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<char *>(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 0000000..72ec750
--- /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<int>(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 0000000..7a6c207
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/enum2.C
@@ -0,0 +1,4 @@
+// PR c++/15877
+
+template <int n> struct T1 { enum { N = 3 }; };
+template <int n> struct T2 { enum { N = n, N1 = T1<N>::N }; };
diff --git a/gcc/testsuite/g++.dg/template/error13.C b/gcc/testsuite/g++.dg/template/error13.C
new file mode 100644
index 0000000..13d8794
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/error13.C
@@ -0,0 +1,5 @@
+// PR c++/15227
+
+template<typename> struct A {};
+
+template<typename T> void A<T>::B::foo() {} // { dg-error "" }