OSDN Git Service

PR c++/40944
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Nov 2009 17:11:18 +0000 (17:11 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Nov 2009 17:11:18 +0000 (17:11 +0000)
* call.c (initialize_reference): Add complain parm.
* typeck.c (convert_for_initialization): Pass it.
* decl.c (grok_reference_init): Likewise.
* cp-tree.h: Declare it.

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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/sfinae15.C [new file with mode: 0644]

index 6c7bdc6..1b87b04 100644 (file)
@@ -1,5 +1,11 @@
 2009-11-03  Jason Merrill  <jason@redhat.com>
 
+       PR c++/40944
+       * call.c (initialize_reference): Add complain parm.
+       * typeck.c (convert_for_initialization): Pass it.
+       * decl.c (grok_reference_init): Likewise.
+       * cp-tree.h: Declare it.
+
        PR c++/40687
        * pt.c (do_auto_deduction): Diagnose inconsistent deduction.
 
index 463257c..674e59d 100644 (file)
@@ -7617,7 +7617,8 @@ set_up_extended_ref_temp (tree decl, tree expr, tree *cleanup, tree *initp)
    Return the converted expression.  */
 
 tree
-initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
+initialize_reference (tree type, tree expr, tree decl, tree *cleanup,
+                     tsubst_flags_t complain)
 {
   conversion *conv;
   void *p;
@@ -7632,16 +7633,19 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
                            LOOKUP_NORMAL);
   if (!conv || conv->bad_p)
     {
-      if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST)
-         && !TYPE_REF_IS_RVALUE (type)
-         && !real_lvalue_p (expr))
-       error ("invalid initialization of non-const reference of "
-              "type %qT from an rvalue of type %qT",
-              type, TREE_TYPE (expr));
-      else
-       error ("invalid initialization of reference of type "
-              "%qT from expression of type %qT", type,
-              TREE_TYPE (expr));
+      if (complain & tf_error)
+       {
+         if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST)
+             && !TYPE_REF_IS_RVALUE (type)
+             && !real_lvalue_p (expr))
+           error ("invalid initialization of non-const reference of "
+                  "type %qT from an rvalue of type %qT",
+                  type, TREE_TYPE (expr));
+         else
+           error ("invalid initialization of reference of type "
+                  "%qT from expression of type %qT", type,
+                  TREE_TYPE (expr));
+       }
       return error_mark_node;
     }
 
index 7965514..c4b088b 100644 (file)
@@ -4429,7 +4429,7 @@ extern tree type_passed_as                        (tree);
 extern tree convert_for_arg_passing            (tree, tree);
 extern bool is_properly_derived_from           (tree, tree);
 extern tree set_up_extended_ref_temp           (tree, tree, tree *, tree *);
-extern tree initialize_reference               (tree, tree, tree, tree *);
+extern tree initialize_reference               (tree, tree, tree, tree *, tsubst_flags_t);
 extern tree make_temporary_var_for_ref_to_temp (tree, tree);
 extern tree strip_top_quals                    (tree);
 extern bool reference_related_p                        (tree, tree);
index de29d0b..97f1ac1 100644 (file)
@@ -4390,7 +4390,7 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
      DECL_INITIAL for local references (instead assigning to them
      explicitly); we need to allow the temporary to be initialized
      first.  */
-  tmp = initialize_reference (type, init, decl, cleanup);
+  tmp = initialize_reference (type, init, decl, cleanup, tf_warning_or_error);
 
   if (tmp == error_mark_node)
     return NULL_TREE;
index 25c257f..5b8523d 100644 (file)
@@ -6879,7 +6879,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags,
       if (fndecl)
        savew = warningcount, savee = errorcount;
       rhs = initialize_reference (type, rhs, /*decl=*/NULL_TREE,
-                                 /*cleanup=*/NULL);
+                                 /*cleanup=*/NULL, complain);
       if (fndecl)
        {
          if (warningcount > savew)
index ab594d7..8898d92 100644 (file)
@@ -1,5 +1,8 @@
 2009-11-03  Jason Merrill  <jason@redhat.com>
 
+       PR c++/40944
+       * g++.dg/template/sfinae15.C: New.
+
        PR c++/40687
        * g++.dg/cpp0x/auto3.C: Remove xfail.
 
diff --git a/gcc/testsuite/g++.dg/template/sfinae15.C b/gcc/testsuite/g++.dg/template/sfinae15.C
new file mode 100644 (file)
index 0000000..27bce25
--- /dev/null
@@ -0,0 +1,23 @@
+// PR c++/40944
+// { dg-options -std=c++0x }
+// { dg-do run }
+
+template<typename T>
+struct make { static T&& it(); };
+
+void (*pf)(int&) = 0;
+
+template< typename T >
+int bar(T const& x,
+        decltype( pf(make<T const&>::it()) )* = 0 // SFINAE!
+        ) {
+    return 1;
+}
+
+int bar(...) {
+    return 0;
+}
+
+int main() {
+    return bar(42);
+}