diff mbox

[C++11] DR1479 - Literal operators and default arguments

Message ID 549A1583.1020201@verizon.net
State New
Headers show

Commit Message

Ed Smith-Rowland Dec. 24, 2014, 1:23 a.m. UTC
And now with a patch...

I tried this patch a year ago and, as pointed out by NightStrike, got 
lost in the shuffle.

The idea is that default arguments in literal operators would lead to 
ambiguities and might not act like the uthor intends.

The earlier patch errors out.  This time I just warn.  I'm not sure what 
we want here actually so some feedback would be nice.
I could alternatively error and add a note about default argument.

Builds and tests clean on x86_64-linux.

OK?

Ed
cp:

2014-12-23  Edward Smith-Rowland  <3dw4rd@verizon.net>

	DR1479: Literal operators and default arguments
	* cp-tree.h (check_literal_operator_args): Add new variable.
	* decl.c (grokfndecl): Adjust call.  Report extra error.
	* typeck.c (check_literal_operator_args): Add and set new return
	argument indicating defaulted operator argument.
	of character and build parm pack with correct type and chars.


testsuite:

2014-12-23  Edward Smith-Rowland  <3dw4rd@verizon.net>

	DR1479: Literal operators and default arguments
	* testsuite/g++.dg/cpp0x/udlit-default-arg-neg.C: New.
diff mbox

Patch

Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 218988)
+++ cp/cp-tree.h	(working copy)
@@ -6286,7 +6286,7 @@ 
                                                  tsubst_flags_t);
 extern void check_template_keyword		(tree);
 extern bool check_raw_literal_operator		(const_tree decl);
-extern bool check_literal_operator_args		(const_tree, bool *, bool *);
+extern bool check_literal_operator_args		(const_tree, bool *, bool *, bool *);
 extern void maybe_warn_about_useless_cast       (tree, tree, tsubst_flags_t);
 extern tree cp_perform_integral_promotions      (tree, tsubst_flags_t);
 
Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 218988)
+++ cp/decl.c	(working copy)
@@ -7849,6 +7849,7 @@ 
     return NULL_TREE;
   else if (UDLIT_OPER_P (DECL_NAME (decl)))
     {
+      bool default_arg_p;
       bool long_long_unsigned_p;
       bool long_double_p;
       const char *suffix = NULL;
@@ -7861,12 +7862,15 @@ 
 
       if (DECL_NAMESPACE_SCOPE_P (decl))
 	{
-	  if (!check_literal_operator_args (decl, &long_long_unsigned_p,
+	  if (!check_literal_operator_args (decl, &default_arg_p,
+					    &long_long_unsigned_p,
 					    &long_double_p))
 	    {
 	      error ("%qD has invalid argument list", decl);
 	      return NULL_TREE;
 	    }
+	  if (default_arg_p)
+	    warning (0, "%qD has default argument(s)", decl);
 
 	  suffix = UDLIT_OP_SUFFIX (DECL_NAME (decl));
 	  if (long_long_unsigned_p)
Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 218988)
+++ cp/typeck.c	(working copy)
@@ -9204,15 +9204,21 @@ 
    argument types.  */
 
 bool
-check_literal_operator_args (const_tree decl,
+check_literal_operator_args (const_tree decl, bool *default_arg_p,
 			     bool *long_long_unsigned_p, bool *long_double_p)
 {
   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
 
+  *default_arg_p = false;
   *long_long_unsigned_p = false;
   *long_double_p = false;
   if (processing_template_decl || processing_specialization)
-    return argtypes == void_list_node;
+    {
+      if (argtypes && argtypes != void_list_node && TREE_PURPOSE (argtypes))
+	*default_arg_p = true;
+
+      return argtypes == void_list_node;
+    }
   else
     {
       tree argtype;
@@ -9224,6 +9230,9 @@ 
 	   argtype && argtype != void_list_node;
 	   argtype = TREE_CHAIN (argtype))
 	{
+	  if (TREE_PURPOSE (argtype))
+	    *default_arg_p = true;
+
 	  tree t = TREE_VALUE (argtype);
 	  ++arity;
 
@@ -9242,6 +9251,8 @@ 
 		  argtype = TREE_CHAIN (argtype);
 		  if (!argtype)
 		    return false;
+		  if (TREE_PURPOSE (argtype))
+		    *default_arg_p = true;
 		  t = TREE_VALUE (argtype);
 		  if (maybe_raw_p && argtype == void_list_node)
 		    return true;
@@ -9278,6 +9289,9 @@ 
       if (!argtype)
 	return false; /* Found ellipsis.  */
 
+      if (*default_arg_p)
+	return false;
+
       if (arity != max_arity)
 	return false;
 
Index: testsuite/g++.dg/cpp0x/udlit-default-arg-neg.C
===================================================================
--- testsuite/g++.dg/cpp0x/udlit-default-arg-neg.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/udlit-default-arg-neg.C	(working copy)
@@ -0,0 +1,22 @@ 
+// { dg-options -std=c++11 }
+
+#include <cstddef>
+
+int
+operator""_a(const char *, std::size_t = 0) // { dg-warning "has invalid argument list" }
+{
+  return 1;
+}
+
+int
+operator""_a(const char *)
+{
+  return 2;
+}
+
+int
+main()
+{
+  int i = 123_a; // OK, raw literal, not ambiguous.
+  int j = operator""_a("123"); // OK, raw literal, not ambiguous.
+}