]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/68926 (decltype and sfinae to check for template instance availability...
authorJason Merrill <jason@redhat.com>
Wed, 10 Feb 2016 19:12:32 +0000 (14:12 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 10 Feb 2016 19:12:32 +0000 (14:12 -0500)
PR c++/68926

* pt.c (resolve_nondeduced_context): Add complain parm.
(do_auto_deduction): Pass it.
* cvt.c (convert_to_void): Likewise.
* decl.c (cp_finish_decl): Likewise.
* init.c (build_new): Likewise.
* rtti.c (get_tinfo_decl_dynamic): Likewise.
* semantics.c (finish_decltype_type): Likewise.
* typeck.c (decay_conversion): Likewise.
* cp-tree.h: Adjust declaration.
* call.c (standard_conversion): Add complain parm, pass it along.
(implicit_conversion): Pass it.

From-SVN: r233304

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/cpp0x/sfinae56.C [new file with mode: 0644]

index 628f4d1ecf968ff49c21e8efa664f39a5cb55f08..3c2858423d332efa5a477839ea21282af70f5989 100644 (file)
@@ -1,5 +1,18 @@
 2016-02-10  Jason Merrill  <jason@redhat.com>
 
+       PR c++/68926
+       * pt.c (resolve_nondeduced_context): Add complain parm.
+       (do_auto_deduction): Pass it.
+       * cvt.c (convert_to_void): Likewise.
+       * decl.c (cp_finish_decl): Likewise.
+       * init.c (build_new): Likewise.
+       * rtti.c (get_tinfo_decl_dynamic): Likewise.
+       * semantics.c (finish_decltype_type): Likewise.
+       * typeck.c (decay_conversion): Likewise.
+       * cp-tree.h: Adjust declaration.
+       * call.c (standard_conversion): Add complain parm, pass it along.
+       (implicit_conversion): Pass it.
+
        PR c++/69657
        * name-lookup.c (ambiguous_decl): Call remove_hidden_names.
        (lookup_name_real_1): Likewise.
index ce87be72c14f572748174a65d725b62e072771a5..cb71176c6ca148ecaf49b24f2e16238d3653685a 100644 (file)
@@ -190,7 +190,6 @@ static struct z_candidate *add_function_candidate
         tree, int, tsubst_flags_t);
 static conversion *implicit_conversion (tree, tree, tree, bool, int,
                                        tsubst_flags_t);
-static conversion *standard_conversion (tree, tree, tree, bool, int);
 static conversion *reference_binding (tree, tree, tree, bool, int,
                                      tsubst_flags_t);
 static conversion *build_conv (conversion_kind, tree, conversion *);
@@ -1080,7 +1079,7 @@ strip_top_quals (tree t)
 
 static conversion *
 standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
-                    int flags)
+                    int flags, tsubst_flags_t complain)
 {
   enum tree_code fcode, tcode;
   conversion *conv;
@@ -1110,7 +1109,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
       else if (TREE_CODE (to) == BOOLEAN_TYPE)
        {
          /* Necessary for eg, TEMPLATE_ID_EXPRs (c++/50961).  */
-         expr = resolve_nondeduced_context (expr);
+         expr = resolve_nondeduced_context (expr, complain);
          from = TREE_TYPE (expr);
        }
     }
@@ -1149,7 +1148,8 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
         the standard conversion sequence to perform componentwise
         conversion.  */
       conversion *part_conv = standard_conversion
-       (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags);
+       (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags,
+        complain);
 
       if (part_conv)
        {
@@ -1799,7 +1799,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
   if (TREE_CODE (to) == REFERENCE_TYPE)
     conv = reference_binding (to, from, expr, c_cast_p, flags, complain);
   else
-    conv = standard_conversion (to, from, expr, c_cast_p, flags);
+    conv = standard_conversion (to, from, expr, c_cast_p, flags, complain);
 
   if (conv)
     return conv;
index ead017edab2ad3a8ad211a464d75fa6075c6ab8d..3b91089f50d08645519305b797c6616b767bec79 100644 (file)
@@ -6180,7 +6180,7 @@ extern tree get_template_parms_at_level (tree, int);
 extern tree get_template_innermost_arguments   (const_tree);
 extern tree get_template_argument_pack_elems   (const_tree);
 extern tree get_function_template_decl         (const_tree);
-extern tree resolve_nondeduced_context         (tree);
+extern tree resolve_nondeduced_context         (tree, tsubst_flags_t);
 extern hashval_t iterative_hash_template_arg (tree arg, hashval_t val);
 extern tree coerce_template_parms               (tree, tree, tree);
 extern tree coerce_template_parms               (tree, tree, tree, tsubst_flags_t);
index 60362fd73c4989b8e847958d633e5b9f16c7fdaf..0d1048cd7fe4259cfc4f7a29420ae8f98f833c1c 100644 (file)
@@ -1253,7 +1253,7 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
 
     default:;
     }
-  expr = resolve_nondeduced_context (expr);
+  expr = resolve_nondeduced_context (expr, complain);
   {
     tree probe = expr;
 
index 11f7ce615a490463b841985d7bc67d43bca9e7f6..09bd512313b6f70c0f12177d64bde900189634f1 100644 (file)
@@ -6575,7 +6575,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
       if (TREE_CODE (d_init) == TREE_LIST)
        d_init = build_x_compound_expr_from_list (d_init, ELK_INIT,
                                                  tf_warning_or_error);
-      d_init = resolve_nondeduced_context (d_init);
+      d_init = resolve_nondeduced_context (d_init, tf_warning_or_error);
       type = TREE_TYPE (decl) = do_auto_deduction (type, d_init,
                                                   auto_node,
                                                    tf_warning_or_error,
index cb2e852fdfc5e42458d9a48b2cfd8c4f876adf25..338f85e2c7de5acc5d846fbb0cc5d3b0fcba2a88 100644 (file)
@@ -3364,7 +3364,7 @@ build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
       if (auto_node)
        {
          tree d_init = (**init)[0];
-         d_init = resolve_nondeduced_context (d_init);
+         d_init = resolve_nondeduced_context (d_init, complain);
          type = do_auto_deduction (type, d_init, auto_node);
        }
     }
index 76a6019a29e9fef35b57d65e1ec316aba42f1be5..a215aa78b4c1ade430fe634880106d34f4ca9ada 100644 (file)
@@ -18575,7 +18575,7 @@ resolve_overloaded_unification (tree tparms,
    lvalue for the function template specialization.  */
 
 tree
-resolve_nondeduced_context (tree orig_expr)
+resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain)
 {
   tree expr, offset, baselink;
   bool addr;
@@ -18658,16 +18658,16 @@ resolve_nondeduced_context (tree orig_expr)
            {
              tree base
                = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (offset, 0)));
-             expr = build_offset_ref (base, expr, addr, tf_warning_or_error);
+             expr = build_offset_ref (base, expr, addr, complain);
            }
          if (addr)
-           expr = cp_build_addr_expr (expr, tf_warning_or_error);
+           expr = cp_build_addr_expr (expr, complain);
          return expr;
        }
-      else if (good == 0 && badargs)
+      else if (good == 0 && badargs && (complain & tf_error))
        /* There were no good options and at least one bad one, so let the
           user know what the problem is.  */
-       instantiate_template (badfn, badargs, tf_warning_or_error);
+       instantiate_template (badfn, badargs, complain);
     }
   return orig_expr;
 }
@@ -23880,7 +23880,7 @@ do_auto_deduction (tree type, tree init, tree auto_node,
   if (type == error_mark_node)
     return error_mark_node;
 
-  init = resolve_nondeduced_context (init);
+  init = resolve_nondeduced_context (init, complain);
 
   if (AUTO_IS_DECLTYPE (auto_node))
     {
index a43ff85b8caf8ba36512206e0846b45eb199e723..69c39055d8b64dea628c4441dc77be738f854728 100644 (file)
@@ -242,7 +242,7 @@ get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain)
   if (error_operand_p (exp))
     return error_mark_node;
 
-  exp = resolve_nondeduced_context (exp);
+  exp = resolve_nondeduced_context (exp, complain);
 
   /* peel back references, so they match.  */
   type = non_reference (TREE_TYPE (exp));
index c9f9db4d4108063cef461d1fc9c30267b5817598..0cf5f930b1e987d60e4bcd92d1881c12715e74f2 100644 (file)
@@ -8699,7 +8699,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
 
   /* The type denoted by decltype(e) is defined as follows:  */
 
-  expr = resolve_nondeduced_context (expr);
+  expr = resolve_nondeduced_context (expr, complain);
 
   if (invalid_nonstatic_memfn_p (input_location, expr, complain))
     return error_mark_node;
index d2c23f42df2f1f8249c71814285f52f554e89491..c9fa11290088da425b27813198e6455d07b27428 100644 (file)
@@ -1932,7 +1932,7 @@ decay_conversion (tree exp,
   if (type == error_mark_node)
     return error_mark_node;
 
-  exp = resolve_nondeduced_context (exp);
+  exp = resolve_nondeduced_context (exp, complain);
   if (type_unknown_p (exp))
     {
       if (complain & tf_error)
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae56.C b/gcc/testsuite/g++.dg/cpp0x/sfinae56.C
new file mode 100644 (file)
index 0000000..0f95432
--- /dev/null
@@ -0,0 +1,26 @@
+// PR c++/68926
+// { dg-do compile { target c++11 } }
+
+struct true_type { static constexpr bool value = true; };
+struct false_type { static constexpr bool value = false; };
+
+template<bool Cond> struct enable_if { using type = void; };
+template<> struct enable_if<false> { };
+
+template<typename T, typename U> struct is_same : false_type { };
+template<typename T> struct is_same<T, T> : true_type { };
+
+template<typename T>
+typename enable_if<is_same<int, T>::value>::type
+func();
+
+template<typename T, typename = decltype(func<T>)>
+true_type test(T);
+
+false_type test(...);
+
+int main()
+{
+   decltype(test(0))::value;   // ok
+   decltype(test(0.f))::value; // error
+}