diff options
author | Douglas Gregor <doug.gregor@gmail.com> | 2007-11-07 23:37:29 +0000 |
---|---|---|
committer | Doug Gregor <dgregor@gcc.gnu.org> | 2007-11-07 23:37:29 +0000 |
commit | e4fd5b87bf37f1a58194897e10fae8132470f84a (patch) | |
tree | 574bfa372c1500897f79a6972c7271c01ea484be /gcc/cp | |
parent | 4a54716a857f614647b249bc91345f58c18d2c68 (diff) | |
download | gcc-e4fd5b87bf37f1a58194897e10fae8132470f84a.zip gcc-e4fd5b87bf37f1a58194897e10fae8132470f84a.tar.gz gcc-e4fd5b87bf37f1a58194897e10fae8132470f84a.tar.bz2 |
re PR c++/33045 ([c++0x] Incorrect decltype result for function calls.)
2007-11-07 Douglas Gregor <doug.gregor@gmail.com>
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 <doug.gregor@gmail.com>
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.
From-SVN: r129975
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/parser.c | 2 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 16 |
3 files changed, 26 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d62d29d..a294e76 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2007-11-07 Douglas Gregor <doug.gregor@gmail.com> + + 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 <jakub@redhat.com> PR c++/33501 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 23994b0..41cb26e 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 50118a2..a27b33e 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); |