OSDN Git Service

2007-11-07 Douglas Gregor <doug.gregor@gmail.com>
authordgregor <dgregor@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Nov 2007 23:37:29 +0000 (23:37 +0000)
committerdgregor <dgregor@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Nov 2007 23:37:29 +0000 (23:37 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129975 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/decltype-33837.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/decltype-33838.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/decltype-refbug.C [new file with mode: 0644]

index d62d29d..a294e76 100644 (file)
@@ -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
 2007-11-07  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/33501
index 23994b0..41cb26e 100644 (file)
@@ -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)
 {
 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)
     return;
 
   if ((TREE_PRIVATE (decl)
index 50118a2..a27b33e 100644 (file)
@@ -4049,6 +4049,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
   tree orig_expr = expr;
   tree type;
 
   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);
   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;
 
     {
       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))
       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);
                  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);
                 /* If the expression is just "this", we want the
                    cv-unqualified pointer for the "this" type.  */
                 type = TYPE_MAIN_VARIANT (type);
index ff2affb..063d20f 100644 (file)
@@ -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.
 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 (file)
index 0000000..35689fb
--- /dev/null
@@ -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 (file)
index 0000000..260a0d1
--- /dev/null
@@ -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 (file)
index 0000000..8e3c824
--- /dev/null
@@ -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");