diff mbox

[C++-11] User defined literals

Message ID 4EA861C1.8080703@redhat.com
State New
Headers show

Commit Message

Jason Merrill Oct. 26, 2011, 7:38 p.m. UTC
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

Comments

Ed Smith-Rowland Oct. 27, 2011, 6:06 p.m. UTC | #1
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;
I'm on it.
It looks like these incorrectly pass too:

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;
int cc16 = 'c'_char16_t;
int cc32 = 'c'_char32_t;

int wcc = L'c'_char;
int wcc16 = L'c'_char16_t;
int wcc31 = L'c'_char32_t;

etc.

I'm guessing pointer conversion errors would prevent something similar 
happening to raw and string operators but I'll check and repair.
>
> 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
diff mbox

Patch

commit d083a0d7f94fb0fe3605d499366b1b637e169c17
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Oct 26 12:37:32 2011 -0400

    	* typeck.c (check_literal_operator_args): Avoid building types.

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 59e1357..ec14934 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8405,12 +8405,6 @@  check_literal_operator_args (const_tree decl,
       bool found_string_p = false;
       bool maybe_raw_p = false;
       bool found_size_p = false;
-      tree const_wchar_ptr_type_node
-	   = build_pointer_type (build_type_variant (wchar_type_node, 1, 0));
-      tree const_char16_ptr_type_node
-	   = build_pointer_type (build_type_variant (char16_type_node, 1, 0));
-      tree const_char32_ptr_type_node
-	   = build_pointer_type (build_type_variant (char32_type_node, 1, 0));
 
       *long_long_unsigned_p = false;
       *long_double_p = false;
@@ -8423,17 +8417,26 @@  check_literal_operator_args (const_tree decl,
 	  tree t = TREE_VALUE (argtype);
 	  ++arity;
 
-	  if (same_type_p (t, const_string_type_node))
+	  if (TREE_CODE (t) == POINTER_TYPE)
 	    {
-	      found_string_p = true;
-	      maybe_raw_p = true;
+	      t = TREE_TYPE (t);
+	      if (cp_type_quals (t) != TYPE_QUAL_CONST)
+		return false;
+	      t = TYPE_MAIN_VARIANT (t);
+	      if (same_type_p (t, char_type_node))
+		{
+		  found_string_p = true;
+		  maybe_raw_p = true;
+		}
+	      else if (same_type_p (t, wchar_type_node))
+		found_string_p = true;
+	      else if (same_type_p (t, char16_type_node))
+		found_string_p = true;
+	      else if (same_type_p (t, char32_type_node))
+		found_string_p = true;
+	      else
+		return false;
 	    }
-	  else if (same_type_p (t, const_wchar_ptr_type_node))
-	    found_string_p = true;
-	  else if (same_type_p (t, const_char16_ptr_type_node))
-	    found_string_p = true;
-	  else if (same_type_p (t, const_char32_ptr_type_node))
-	    found_string_p = true;
 	  else if (same_type_p (t, size_type_node))
 	    {
 	      if (!found_string_p)