aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDouglas Gregor <doug.gregor@gmail.com>2007-11-07 23:37:29 +0000
committerDoug Gregor <dgregor@gcc.gnu.org>2007-11-07 23:37:29 +0000
commite4fd5b87bf37f1a58194897e10fae8132470f84a (patch)
tree574bfa372c1500897f79a6972c7271c01ea484be /gcc
parent4a54716a857f614647b249bc91345f58c18d2c68 (diff)
downloadgcc-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')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/parser.c2
-rw-r--r--gcc/cp/semantics.c16
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype-33837.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype-33838.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype-refbug.C17
7 files changed, 65 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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ff2affb..063d20f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+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.
+
2007-11-07 Eric Botcazou <ebotcazou@libertysurf.fr>
* 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 0000000..35689fb
--- /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 0000000..260a0d1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype-33838.C
@@ -0,0 +1,6 @@
+// { dg-options -std=c++0x }
+// PR c++/33838
+template<typename T> 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 0000000..8e3c824
--- /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<typename T, typename U>
+struct is_same
+{
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T>
+{
+ static const bool value = true;
+};
+
+static_assert(is_same<decltype(f()), int&&>::value, "decltype of rvalue reference");