On 10/26/2011 03:38 PM, Jason Merrill wrote:
On 10/26/2011 02:00 AM, Ed Smith-Rowland wrote:
The patch was bootstrapped and regtested on x86_64-linux-gnu.

Really? I ran into a warning about the unused "suffix" parameter to interpret_integer. So I've fixed that error. I also added a couple of comments, and implemented the change to check_literal_operator_args that I wondered about a while back. And checked it all in.

But we aren't quite done, I think: I notice that the lookup of operators doesn't match what's in 2.14.8. For instance, I don't think this should be accepted:

double operator"" _foo (long long unsigned);
double d = 1.2_foo;

The lookup described in 2.14.8 involves looking through the overload set for a particular signature before doing normal overload resolution.

Also, we don't need to worry about argument-dependent lookup for these operators, since none of the arguments can have associated namespaces. So I think we can use lookup_name rather than lookup_function_nonclass, only look it up once in cp_userdef_numeric_literal, and then only build one call depending on the contents of the overload set.

Jason
Jason,

Here is a patch that prevents the conversions outlined above and also for char types.
I also changed the name lookup to use the simpler and correct lookup_name().
There is a new testcase.

Now for the weirdness. When I try to make test cases with char16_t or char32_t it's like the u or U prefix is ignored and the character argument is of type char. I don't really use these character widths so my test cases could be wonky.

char16_t operator"" _rot(char16_t c) { return 127 - c; }

char16_t c = u'x'_rot;

$ char16.cpp:6:14: error: unable to find operator ‘operator"" _rot’ with ‘char’ argument

Ideas? I'll try and see if there is a lexing error somewhere.

Ed

Index: gcc/testsuite/g++.dg/cpp0x/udlit-implicit-conv-neg.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/udlit-implicit-conv-neg.C        (revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/udlit-implicit-conv-neg.C        (revision 0)
@@ -0,0 +1,33 @@
+// { dg-options -std=c++0x }
+
+int operator"" _bar (long double);
+
+double operator"" _foo (long long unsigned);
+
+int i = 12_bar; // { dg-error "unable to find|with|argument" }
+
+double d = 1.2_foo; // { dg-error "unable to find|with|argument" }
+
+int operator"" _char(char);
+
+int operator"" _wchar_t(wchar_t);
+
+int operator"" _char16_t(char16_t);
+
+int operator"" _char32_t(char32_t);
+
+int cwc = 'c'_wchar_t; // { dg-error "unable to find|with|argument" }
+int cc16 = 'c'_char16_t; // { dg-error "unable to find|with|argument" }
+int cc32 = 'c'_char32_t; // { dg-error "unable to find|with|argument" }
+
+int wcc = L'c'_char; // { dg-error "unable to find|with|argument" }
+int wcc16 = L'c'_char16_t; // { dg-error "unable to find|with|argument" }
+int wcc32 = L'c'_char32_t; // { dg-error "unable to find|with|argument" }
+
+int c16c = u'c'_char; // { dg-error "unable to find|with|argument" }
+int c16wc = u'c'_wchar_t; // { dg-error "unable to find|with|argument" }
+int c16c32 = u'c'_char32_t; // { dg-error "unable to find|with|argument" }
+
+int c32c = U'c'_char; // { dg-error "unable to find|with|argument" }
+int c32wc = U'c'_wchar_t; // { dg-error "unable to find|with|argument" }
+int c32c16 = U'c'_char16_t; // { dg-error "unable to find|with|argument" }
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c     (revision 180556)
+++ gcc/cp/parser.c     (working copy)
@@ -3532,7 +3532,7 @@
 {
   cp_token *token = NULL;
   tree literal, suffix_id, value;
-  tree name, decl;
+  tree name, decl, argtypes = NULL_TREE;
   tree result;
   VEC(tree,gc) *vec;
 
@@ -3546,7 +3546,7 @@
   /* Lookup the name we got back from the id-expression.  */
   vec = make_tree_vector ();
   VEC_safe_push (tree, gc, vec, value);
-  decl = lookup_function_nonclass (name, vec, /*block_p=*/false);
+  decl = lookup_name (name);
   if (!decl || decl == error_mark_node)
     {
       error ("unable to find user-defined character literal operator %qD",
@@ -3554,6 +3554,17 @@
       release_tree_vector (vec);
       return error_mark_node;
     }
+
+  if (TREE_CODE (TREE_TYPE (decl)) != LANG_TYPE)
+    argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
+  if (argtypes != NULL_TREE
+      && TREE_VALUE (argtypes) != TREE_TYPE (value))
+    {
+      error ("unable to find operator %qD with %qT argument",
+            name, TREE_TYPE (value));
+      return error_mark_node;
+    }
+
   result = finish_call_expr (decl, &vec, false, true, tf_warning_or_error);
   release_tree_vector (vec);
 
@@ -3594,7 +3605,7 @@
 {
   cp_token *token = NULL;
   tree literal, suffix_id, value, num_string;
-  tree name, decl;
+  tree name, decl, argtypes = NULL_TREE;
   tree result = error_mark_node;
   VEC(tree,gc) *args;
 
@@ -3605,21 +3616,47 @@
   num_string = USERDEF_LITERAL_NUM_STRING (literal);
   name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
 
+  decl = lookup_name (name);
+  if (!decl || decl == error_mark_node)
+    {
+      error ("unable to find user-defined numeric literal operator %qD", name);
+      return error_mark_node;
+    }
+
+  if (TREE_CODE (TREE_TYPE (decl)) != LANG_TYPE)
+    argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
+
+  if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE)
+    {
+      if (argtypes != NULL_TREE
+         && TREE_CODE (TREE_VALUE (argtypes)) == REAL_TYPE)
+       {
+         error ("unable to find %qD with %<unsigned long long int%> argument",
+                name);
+         return error_mark_node;
+       }
+    }
+  else if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE)
+    {
+      if (argtypes != NULL_TREE
+         && TREE_CODE (TREE_VALUE (argtypes)) == INTEGER_TYPE)
+       {
+         error ("unable to find %qD with %<long double%> argument", name);
+         return error_mark_node;
+       }
+    }
+
   /* Build up a call to the user-defined operator  */
   /* Lookup the name we got back from the id-expression.  */
   /* Try to find the literal operator by finishing the call expression
      with the numeric argument.  */
   args = make_tree_vector ();
   VEC_safe_push (tree, gc, args, value);
-  decl = lookup_function_nonclass (name, args, /*block_p=*/false);
-  if (decl && decl != error_mark_node)
+  result = finish_call_expr (decl, &args, false, true, tf_none);
+  if (result != error_mark_node)
     {
-      result = finish_call_expr (decl, &args, false, true, tf_none);
-      if (result != error_mark_node)
-       {
-         release_tree_vector (args);
-         return result;
-       }
+      release_tree_vector (args);
+      return result;
     }
   release_tree_vector (args);
 
@@ -3628,15 +3665,11 @@
      in string format.  */
   args = make_tree_vector ();
   VEC_safe_push (tree, gc, args, num_string);
-  decl = lookup_function_nonclass (name, args, /*block_p=*/false);
-  if (decl && decl != error_mark_node)
+  result = finish_call_expr (decl, &args, false, true, tf_none);
+  if (result != error_mark_node)
     {
-      result = finish_call_expr (decl, &args, false, true, tf_none);
-      if (result != error_mark_node)
-       {
-         release_tree_vector (args);
-         return result;
-       }
+      release_tree_vector (args);
+      return result;
     }
   release_tree_vector (args);
 
@@ -3644,17 +3677,13 @@
      function with parameter pack char....  Call the function with
      template parameter characters representing the number.  */
   args = make_tree_vector ();
-  decl = lookup_function_nonclass (name, args, /*block_p=*/false);
-  if (decl && decl != error_mark_node)
+  tree tmpl_args = make_char_string_pack (num_string);
+  decl = lookup_template_function (decl, tmpl_args);
+  result = finish_call_expr (decl, &args, false, true, tf_none);
+  if (result != error_mark_node)
     {
-      tree tmpl_args = make_char_string_pack (num_string);
-      decl = lookup_template_function (decl, tmpl_args);
-      result = finish_call_expr (decl, &args, false, true, tf_none);
-      if (result != error_mark_node)
-       {
-         release_tree_vector (args);
-         return result;
-       }
+      release_tree_vector (args);
+      return result;
     }
   release_tree_vector (args);
 
@@ -3688,7 +3717,7 @@
   vec = make_tree_vector ();
   VEC_safe_push (tree, gc, vec, value);
   VEC_safe_push (tree, gc, vec, build_int_cst (size_type_node, len));
-  decl = lookup_function_nonclass (name, vec, /*block_p=*/false);
+  decl = lookup_name (name);
   if (!decl || decl == error_mark_node)
     {
       error ("unable to find user-defined string literal operator %qD", name);

Reply via email to