semantics.c (finish_decltype_type): Add complain parm.
authorJason Merrill <jason@redhat.com>
Thu, 7 Apr 2011 21:46:57 +0000 (17:46 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 7 Apr 2011 21:46:57 +0000 (17:46 -0400)
* semantics.c (finish_decltype_type): Add complain parm.
* cp-tree.h: Adjust.
* parser.c (cp_parser_decltype): Adjust.
* pt.c (tsubst): Adjust.

From-SVN: r172139

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

index 5ffe1f5ed5fa9cb945028bcf49e5364a678258f9..b9c94ac331edb58ecbbaa230db73a07b972ff34b 100644 (file)
@@ -1,5 +1,10 @@
 2011-04-07  Jason Merrill  <jason@redhat.com>
 
+       * semantics.c (finish_decltype_type): Add complain parm.
+       * cp-tree.h: Adjust.
+       * parser.c (cp_parser_decltype): Adjust.
+       * pt.c (tsubst): Adjust.
+
        PR c++/48450
        * cvt.c (ocp_convert): Handle converting scoped enum to bool.
 
index 6ef6e6eb3ec77e612b8c4bef4882da9bb6ba48c6..06b0b3e89903c3d395f9c46da86bceab0faaa936 100644 (file)
@@ -5346,7 +5346,7 @@ extern tree baselink_for_fns                    (tree);
 extern void finish_static_assert                (tree, tree, location_t,
                                                  bool);
 extern tree describable_type                   (tree);
-extern tree finish_decltype_type                (tree, bool);
+extern tree finish_decltype_type                (tree, bool, tsubst_flags_t);
 extern tree finish_trait_expr                  (enum cp_trait_kind, tree, tree);
 extern tree build_lambda_expr                   (void);
 extern tree build_lambda_object                        (tree);
index 9ed3a1f7ec421b20b3e4c48a23e359b1dc30f0dd..607e9b8f3285784b5960fe36b5f2ad0cd602db69 100644 (file)
@@ -10197,7 +10197,8 @@ cp_parser_decltype (cp_parser *parser)
       return error_mark_node;
     }
 
-  return finish_decltype_type (expr, id_expression_or_member_access_p);
+  return finish_decltype_type (expr, id_expression_or_member_access_p,
+                              tf_warning_or_error);
 }
 
 /* Special member functions [gram.special] */
index 5960e4624b633ed9681bf99b52d4e298ec58b429..66db880acd5dd2204b9a77fe36345a3da197faa8 100644 (file)
@@ -11025,7 +11025,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          type = lambda_return_type (type);
        else
          type = finish_decltype_type
-           (type, DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t));
+           (type, DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t), complain);
        return cp_build_qualified_type_real (type,
                                             cp_type_quals (t)
                                             | cp_type_quals (type),
index a15740a81eef2d5c76675582863378b1a002bb40..80ec028b9b6824d34f9fbe23ebdee5609e6f02b6 100644 (file)
@@ -4785,7 +4785,8 @@ describable_type (tree expr)
    a full expression.  */
 
 tree
-finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
+finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
+                     tsubst_flags_t complain)
 {
   tree orig_expr = expr;
   tree type = NULL_TREE;
@@ -4798,7 +4799,8 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
       || (TREE_CODE (expr) == BIT_NOT_EXPR
          && TYPE_P (TREE_OPERAND (expr, 0))))
     {
-      error ("argument to decltype must be an expression");
+      if (complain & tf_error)
+       error ("argument to decltype must be an expression");
       return error_mark_node;
     }
 
@@ -4864,7 +4866,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
           if (OVL_CHAIN (expr)
              || TREE_CODE (OVL_FUNCTION (expr)) == TEMPLATE_DECL)
             {
-              error ("%qE refers to a set of overloaded functions", orig_expr);
+             if (complain & tf_error)
+               error ("%qE refers to a set of overloaded functions",
+                      orig_expr);
               return error_mark_node;
             }
           else
@@ -4916,7 +4920,8 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
         default:
          gcc_assert (TYPE_P (expr) || DECL_P (expr)
                      || TREE_CODE (expr) == SCOPE_REF);
-          error ("argument to decltype must be an expression");
+         if (complain & tf_error)
+           error ("argument to decltype must be an expression");
           return error_mark_node;
         }
     }
@@ -4954,7 +4959,8 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
 
   if (!type || type == unknown_type_node)
     {
-      error ("type of %qE is unknown", expr);
+      if (complain & tf_error)
+       error ("type of %qE is unknown", expr);
       return error_mark_node;
     }
 
index dabb816393ee7763734836a7e6414741c1f52bdb..9d5f63d1a179adad7942d7078bf5a209707061d6 100644 (file)
@@ -1,5 +1,7 @@
 2011-04-07  Jason Merrill  <jason@redhat.com>
 
+       * g++.dg/cpp0x/sfinae7.C: New.
+
        * g++.dg/cpp0x/enum9.C: New.
 
 2011-04-07  Mike Stump  <mikestump@comcast.net>
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae7.C b/gcc/testsuite/g++.dg/cpp0x/sfinae7.C
new file mode 100644 (file)
index 0000000..0a95a96
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-options -std=c++0x }
+
+struct A
+{
+  void f();
+  void f(int);
+  typedef int g;
+};
+
+template <class T> decltype (T::f) f();
+template <class T> void f();
+
+template <class T> decltype (T::g) g();
+template <class T> void g();
+
+int main()
+{
+  f<A>();
+  g<A>();
+}