PR c++/91809 - bit-field and ellipsis.
authorJason Merrill <jason@redhat.com>
Mon, 23 Sep 2019 17:48:00 +0000 (13:48 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 23 Sep 2019 17:48:00 +0000 (13:48 -0400)
decay_conversion converts a bit-field access to its declared type, which
isn't what we want here; it even has a comment that the caller is expected
to have already used default_conversion to perform integral promotion.  This
function handles arithmetic promotion differently, but we still don't want
to call decay_conversion before that happens.

* call.c (convert_arg_to_ellipsis): Don't call decay_conversion for
arithmetic arguments.

From-SVN: r276059

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/g++.dg/overload/ellipsis4.C [new file with mode: 0644]

index 7ccc7cd..541d018 100644 (file)
@@ -1,3 +1,9 @@
+2019-09-23  Jason Merrill  <jason@redhat.com>
+
+       PR c++/91809 - bit-field and ellipsis.
+       * call.c (convert_arg_to_ellipsis): Don't call decay_conversion for
+       arithmetic arguments.
+
 2019-09-23  Marek Polacek  <polacek@redhat.com>
 
        PR c++/91844 - Implement CWG 2352, Similar types and reference binding.
index 28b3f33..77f10a9 100644 (file)
@@ -7485,17 +7485,11 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
 tree
 convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
 {
-  tree arg_type;
+  tree arg_type = TREE_TYPE (arg);
   location_t loc = cp_expr_loc_or_input_loc (arg);
 
   /* [expr.call]
 
-     The lvalue-to-rvalue, array-to-pointer, and function-to-pointer
-     standard conversions are performed.  */
-  arg = decay_conversion (arg, complain);
-  arg_type = TREE_TYPE (arg);
-  /* [expr.call]
-
      If the argument has integral or enumeration type that is subject
      to the integral promotions (_conv.prom_), or a floating-point
      type that is subject to the floating-point promotion
@@ -7536,6 +7530,12 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
       else
        arg = cp_perform_integral_promotions (arg, complain);
     }
+  else
+    /* [expr.call]
+
+       The lvalue-to-rvalue, array-to-pointer, and function-to-pointer
+       standard conversions are performed.  */
+    arg = decay_conversion (arg, complain);
 
   arg = require_complete_type_sfinae (arg, complain);
   arg_type = TREE_TYPE (arg);
diff --git a/gcc/testsuite/g++.dg/overload/ellipsis4.C b/gcc/testsuite/g++.dg/overload/ellipsis4.C
new file mode 100644 (file)
index 0000000..9bade5a
--- /dev/null
@@ -0,0 +1,12 @@
+// { dg-additional-options "-Wformat" }
+
+extern "C" int printf (const char *, ...);
+
+struct X {
+  unsigned long long a: 1;
+} x;
+
+void foo()
+{
+  printf("%d", x.a);
+}