From a7905afa00a185861ad143eea26089abd5dbb966 Mon Sep 17 00:00:00 2001 From: dgregor Date: Wed, 7 Nov 2007 23:37:29 +0000 Subject: [PATCH] 2007-11-07 Douglas Gregor PR c++/33045 PR c++/33837 PR c++/33838 * semantics.c (finish_decltype_type): See through INDIRECT_REFs. Be careful with ERROR_MARK_NODEs. * parser.c (cp_parser_check_access_in_redeclaration): Handle NULL argument. 2007-11-07 Douglas Gregor PR c++/33045 PR c++/33837 PR c++/33838 * g++.dg/cpp0x/decltype-33837.C: New. * g++.dg/cpp0x/decltype-refbug.C: New. * g++.dg/cpp0x/decltype-33838.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129975 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/parser.c | 2 +- gcc/cp/semantics.c | 16 +++++++++++++++- gcc/testsuite/ChangeLog | 9 +++++++++ gcc/testsuite/g++.dg/cpp0x/decltype-33837.C | 7 +++++++ gcc/testsuite/g++.dg/cpp0x/decltype-33838.C | 6 ++++++ gcc/testsuite/g++.dg/cpp0x/decltype-refbug.C | 17 +++++++++++++++++ 7 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/decltype-33837.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/decltype-33838.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/decltype-refbug.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d62d29df51b..a294e762620 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2007-11-07 Douglas Gregor + + PR c++/33045 + PR c++/33837 + PR c++/33838 + * semantics.c (finish_decltype_type): See through INDIRECT_REFs. + Be careful with ERROR_MARK_NODEs. + * parser.c (cp_parser_check_access_in_redeclaration): Handle NULL + argument. + 2007-11-07 Jakub Jelinek PR c++/33501 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 23994b0808a..41cb26e5e0f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -17858,7 +17858,7 @@ cp_parser_check_class_key (enum tag_types class_key, tree type) static void cp_parser_check_access_in_redeclaration (tree decl) { - if (!CLASS_TYPE_P (TREE_TYPE (decl))) + if (!decl || !CLASS_TYPE_P (TREE_TYPE (decl))) return; if ((TREE_PRIVATE (decl) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 50118a25f12..a27b33e4911 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4049,6 +4049,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) tree orig_expr = expr; tree type; + if (!expr || error_operand_p (expr)) + return error_mark_node; + if (type_dependent_expression_p (expr)) { type = make_aggr_type (DECLTYPE_TYPE); @@ -4147,6 +4150,15 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) { tree fndecl; + /* Expressions of reference type are sometimes wrapped in + INDIRECT_REFs. INDIRECT_REFs are just internal compiler + representation, not part of the language, so we have to look + through them. */ + if (TREE_CODE (expr) == INDIRECT_REF + && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) + == REFERENCE_TYPE) + expr = TREE_OPERAND (expr, 0); + if (TREE_CODE (expr) == CALL_EXPR && (fndecl = get_callee_fndecl (expr)) && (fndecl != error_mark_node)) @@ -4176,7 +4188,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) decltype(e) is defined as T&, otherwise decltype(e) is defined as T. */ type = TREE_TYPE (expr); - if (expr == current_class_ptr) + if (type == error_mark_node) + return error_mark_node; + else if (expr == current_class_ptr) /* If the expression is just "this", we want the cv-unqualified pointer for the "this" type. */ type = TYPE_MAIN_VARIANT (type); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ff2affba019..063d20f97ce 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2007-11-07 Douglas Gregor + + PR c++/33045 + PR c++/33837 + PR c++/33838 + * g++.dg/cpp0x/decltype-33837.C: New. + * g++.dg/cpp0x/decltype-refbug.C: New. + * g++.dg/cpp0x/decltype-33838.C: New. + 2007-11-07 Eric Botcazou * gcc.c-torture/compile/20071107-1.c: New test. diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-33837.C b/gcc/testsuite/g++.dg/cpp0x/decltype-33837.C new file mode 100644 index 00000000000..35689fbc279 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype-33837.C @@ -0,0 +1,7 @@ +// { dg-options -std=c++0x } +// PR c++/33837 +void foo() +{ + __decltype (A::foo()); // { dg-error "was not declared|expected initializer" } + __decltype (B); // { dg-error "was not declared" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-33838.C b/gcc/testsuite/g++.dg/cpp0x/decltype-33838.C new file mode 100644 index 00000000000..260a0d1cf09 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype-33838.C @@ -0,0 +1,6 @@ +// { dg-options -std=c++0x } +// PR c++/33838 +template struct A +{ + __decltype (T* foo()); // { dg-error "expected|no arguments|accept" } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-refbug.C b/gcc/testsuite/g++.dg/cpp0x/decltype-refbug.C new file mode 100644 index 00000000000..8e3c8240724 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype-refbug.C @@ -0,0 +1,17 @@ +// { dg-options "-std=c++0x" } +// PR c++/33045 +int && f (); + +template +struct is_same +{ + static const bool value = false; +}; + +template +struct is_same +{ + static const bool value = true; +}; + +static_assert(is_same::value, "decltype of rvalue reference"); -- 2.11.0