re PR c++/17232 ([DR 1640] classes and class template specializations treated differe...
authorJason Merrill <jason@redhat.com>
Thu, 28 Mar 2013 18:21:06 +0000 (14:21 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 28 Mar 2013 18:21:06 +0000 (14:21 -0400)
PR c++/17232
PR c++/52748
* typeck2.c (abstract_virtuals_error_sfinae): Don't complete
the type if tf_decltype is set.
* pt.c (fn_type_unification): Add decltype_p parm.
(get_bindings): Adjust.
* cp-tree.h: Adjust.
* class.c (resolve_address_of_overloaded_function): Adjust.
* call.c (add_template_candidate_real, print_z_candidate): Adjust.

From-SVN: r197214

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

index 0709b66966f4bb628f0795f1ea664d981318675f..5375f01dda58c17af011af397fc3af4bf7f8c7d5 100644 (file)
@@ -1,5 +1,15 @@
 2013-03-28  Jason Merrill  <jason@redhat.com>
 
+       PR c++/17232
+       PR c++/52748
+       * typeck2.c (abstract_virtuals_error_sfinae): Don't complete
+       the type if tf_decltype is set.
+       * pt.c (fn_type_unification): Add decltype_p parm.
+       (get_bindings): Adjust.
+       * cp-tree.h: Adjust.
+       * class.c (resolve_address_of_overloaded_function): Adjust.
+       * call.c (add_template_candidate_real, print_z_candidate): Adjust.
+
        PR c++/56679
        * parser.c (cp_parser_sizeof_pack): Split out from...
        (cp_parser_sizeof_operand): ...here.  Require (id).
index d39124ddcabf2f43495cff412795f3485a00a9ee..4542500315f27a72bc934a580e94adccc541692b 100644 (file)
@@ -2905,7 +2905,8 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
   fn = fn_type_unification (tmpl, explicit_targs, targs,
                            args_without_in_chrg,
                            nargs_without_in_chrg,
-                           return_type, strict, flags, false);
+                           return_type, strict, flags, false,
+                           complain & tf_decltype);
 
   if (fn == error_mark_node)
     {
@@ -3221,7 +3222,7 @@ print_z_candidate (location_t loc, const char *msgstr,
                               r->u.template_unification.return_type,
                               r->u.template_unification.strict,
                               r->u.template_unification.flags,
-                              true);
+                              true, false);
          break;
        case rr_invalid_copy:
          inform (cloc,
index b48b353d596f868a6efb6194bc4c3241d255d6ad..956d5aa9e27d870bcbf7ae9dd7c107120c5b9e09 100644 (file)
@@ -7253,7 +7253,7 @@ resolve_address_of_overloaded_function (tree target_type,
          instantiation = fn_type_unification (fn, explicit_targs, targs, args,
                                              nargs, target_ret_type,
                                              DEDUCE_EXACT, LOOKUP_NORMAL,
-                                              false);
+                                              false, false);
          if (instantiation == error_mark_node)
            /* Instantiation failed.  */
            continue;
index e8e40ec4e05d4014f23c2ab977e651d61b64709e..e1677160ff9131f12be25e6e39152dd90cdbf2db 100644 (file)
@@ -5419,7 +5419,7 @@ extern tree instantiate_template          (tree, tree, tsubst_flags_t);
 extern tree fn_type_unification                        (tree, tree, tree,
                                                 const tree *, unsigned int,
                                                 tree, unification_kind_t, int,
-                                                bool);
+                                                bool, bool);
 extern void mark_decl_instantiated             (tree, int);
 extern int more_specialized_fn                 (tree, tree, int);
 extern void do_decl_instantiation              (tree, tree);
index 59ecdcb82b1bc62224533313e8ce3a0ebd237a5a..27e3ff8720495f29debf4daa039857b59520908d 100644 (file)
@@ -14935,7 +14935,8 @@ fn_type_unification (tree fn,
                     tree return_type,
                     unification_kind_t strict,
                     int flags,
-                    bool explain_p)
+                    bool explain_p,
+                    bool decltype_p)
 {
   tree parms;
   tree fntype;
@@ -14949,6 +14950,9 @@ fn_type_unification (tree fn,
   tree tinst;
   tree r = error_mark_node;
 
+  if (decltype_p)
+    complain |= tf_decltype;
+
   /* In C++0x, it's possible to have a function template whose type depends
      on itself recursively.  This is most obvious with decltype, but can also
      occur with enumeration scope (c++/48969).  So we need to catch infinite
@@ -17626,7 +17630,8 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
                           args, ix,
                           (check_rettype || DECL_CONV_FN_P (fn)
                            ? TREE_TYPE (decl_type) : NULL_TREE),
-                          DEDUCE_EXACT, LOOKUP_NORMAL, /*explain_p=*/false)
+                          DEDUCE_EXACT, LOOKUP_NORMAL, /*explain_p=*/false,
+                          /*decltype*/false)
       == error_mark_node)
     return NULL_TREE;
 
index 52bc4ec3b7f01417c411cce048764946baee15c4..cf42958193a84baa4a21d769194d17617c08ea64 100644 (file)
@@ -265,15 +265,15 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
     return 0;
   type = TYPE_MAIN_VARIANT (type);
 
-  /* In SFINAE context, force instantiation.  */
-  if (!(complain & tf_error))
+  /* In SFINAE, non-N3276 context, force instantiation.  */
+  if (!(complain & (tf_error|tf_decltype)))
     complete_type (type);
 
   /* If the type is incomplete, we register it within a hash table,
      so that we can check again once it is completed. This makes sense
      only for objects for which we have a declaration or at least a
      name.  */
-  if (!COMPLETE_TYPE_P (type))
+  if (!COMPLETE_TYPE_P (type) && (complain & tf_error))
     {
       void **slot;
       struct pending_abstract_type *pat;
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-call2.C b/gcc/testsuite/g++.dg/cpp0x/decltype-call2.C
new file mode 100644 (file)
index 0000000..ad23220
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/52748
+// We don't want to instantiate A<T> here.
+// { dg-require-effective-target c++11 }
+
+template <class T> struct A: T { };
+template <class T> A<T> f(T);
+decltype(f(42)) *p;