re PR c++/51989 (std::deque::iterator recognised as container)
authorPaolo Carlini <paolo.carlini@oracle.com>
Fri, 2 Mar 2012 16:18:25 +0000 (16:18 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Fri, 2 Mar 2012 16:18:25 +0000 (16:18 +0000)
/cp
2012-03-02  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/51989
* typeck2.c (build_x_arrow): Take a tsubst_flags_t argument and
propagate it.
* cp-tree.h (build_x_arrow): Adjust prototype.
* pt.c (tsubst_copy_and_build): Adjust call.
* parser.c (cp_parser_postfix_dot_deref_expression): Likewise.

/testsuite
2012-03-02  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/51989
* g++.dg/cpp0x/sfinae32.C: New.

From-SVN: r184796

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/sfinae32.C [new file with mode: 0644]

index 1749cc134c7ebb7c6cde55cf3228ce234cf1b0b6..6d73ea813e22964239943d0bba749c3a3b588ea7 100644 (file)
@@ -1,3 +1,12 @@
+2012-03-02  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/51989
+       * typeck2.c (build_x_arrow): Take a tsubst_flags_t argument and
+       propagate it.
+       * cp-tree.h (build_x_arrow): Adjust prototype.
+       * pt.c (tsubst_copy_and_build): Adjust call.
+       * parser.c (cp_parser_postfix_dot_deref_expression): Likewise.
+
 2012-03-02  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * name-lookup.c (binding_to_template_parms_of_scope_p): Clean up.
index d435dbdaa0a5ab7d7a2a98a58cb4d32b8296ec75..71573ff0b37afcf6f97dd69dafac806c79afabb0 100644 (file)
@@ -5880,7 +5880,7 @@ extern void check_narrowing                       (tree, tree);
 extern tree digest_init                                (tree, tree, tsubst_flags_t);
 extern tree digest_init_flags                  (tree, tree, int);
 extern tree build_scoped_ref                   (tree, tree, tree *);
-extern tree build_x_arrow                      (tree);
+extern tree build_x_arrow                      (tree, tsubst_flags_t);
 extern tree build_m_component_ref              (tree, tree);
 extern tree build_functional_cast              (tree, tree, tsubst_flags_t);
 extern tree add_exception_specifier            (tree, tree, int);
index 491f48e0fcc757d042a9aa910656dc91778c35d4..c6bd2906203b646f5d7fe65e5ce59451ecc1ec24 100644 (file)
@@ -5910,7 +5910,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
 
   /* If this is a `->' operator, dereference the pointer.  */
   if (token_type == CPP_DEREF)
-    postfix_expression = build_x_arrow (postfix_expression);
+    postfix_expression = build_x_arrow (postfix_expression,
+                                       tf_warning_or_error);
   /* Check to see whether or not the expression is type-dependent.  */
   dependent_p = type_dependent_expression_p (postfix_expression);
   /* The identifier following the `->' or `.' is not qualified.  */
index c9cd953deccf8bbb99d80c2c8c3174b0f7b5f953..8f24d6180af0d9dccab6a9386dac10028e09d015 100644 (file)
@@ -13691,7 +13691,7 @@ tsubst_copy_and_build (tree t,
       /* Remember that there was a reference to this entity.  */
       if (DECL_P (op1))
        mark_used (op1);
-      return build_x_arrow (op1);
+      return build_x_arrow (op1, complain);
 
     case NEW_EXPR:
       {
index 7793744ae4fa031427c8ced845f13602516f8e47..a2606f17abb7659383d3dc347da6eabad68c4e69 100644 (file)
@@ -1462,7 +1462,7 @@ build_scoped_ref (tree datum, tree basetype, tree* binfo_p)
    delegation is detected.  */
 
 tree
-build_x_arrow (tree expr)
+build_x_arrow (tree expr, tsubst_flags_t complain)
 {
   tree orig_expr = expr;
   tree type = TREE_TYPE (expr);
@@ -1486,7 +1486,7 @@ build_x_arrow (tree expr)
 
       while ((expr = build_new_op (COMPONENT_REF, LOOKUP_NORMAL, expr,
                                   NULL_TREE, NULL_TREE,
-                                  &fn, tf_warning_or_error)))
+                                  &fn, complain)))
        {
          if (expr == error_mark_node)
            return error_mark_node;
@@ -1497,7 +1497,8 @@ build_x_arrow (tree expr)
 
          if (vec_member (TREE_TYPE (expr), types_memoized))
            {
-             error ("circular pointer delegation detected");
+             if (complain & tf_error)
+               error ("circular pointer delegation detected");
              return error_mark_node;
            }
 
@@ -1510,7 +1511,8 @@ build_x_arrow (tree expr)
 
       if (last_rval == NULL_TREE)
        {
-         error ("base operand of %<->%> has non-pointer type %qT", type);
+         if (complain & tf_error)
+           error ("base operand of %<->%> has non-pointer type %qT", type);
          return error_mark_node;
        }
 
@@ -1530,13 +1532,16 @@ build_x_arrow (tree expr)
          return expr;
        }
 
-      return cp_build_indirect_ref (last_rval, RO_NULL, tf_warning_or_error);
+      return cp_build_indirect_ref (last_rval, RO_NULL, complain);
     }
 
-  if (types_memoized)
-    error ("result of %<operator->()%> yields non-pointer result");
-  else
-    error ("base operand of %<->%> is not a pointer");
+  if (complain & tf_error)
+    {
+      if (types_memoized)
+       error ("result of %<operator->()%> yields non-pointer result");
+      else
+       error ("base operand of %<->%> is not a pointer");
+    }
   return error_mark_node;
 }
 
index 4be8f24565f53159561b08707d940ea01fac1883..9efc01be3b3b76d1c8befc9c7e8f49cd31bfe440 100644 (file)
@@ -1,3 +1,8 @@
+2012-03-02  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/51989
+       * g++.dg/cpp0x/sfinae32.C: New.
+
 2012-03-02  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/52406
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae32.C b/gcc/testsuite/g++.dg/cpp0x/sfinae32.C
new file mode 100644 (file)
index 0000000..db3bf5a
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/51989
+// { dg-options -std=c++0x }
+
+template <typename T>
+struct is_container
+{
+  template <typename U, typename V = decltype(((U*)0)->begin())>
+  static char test(U* u);
+
+  template <typename U> static long test(...);
+
+  enum { value = sizeof test<T>(0) == 1 };
+};
+
+int main()
+{
+  return is_container<void>::value;
+}