re PR c++/50958 ([C++0x] raw literal operator provides incorrect string for integer literal '0')
PR c++/50958 gcc/cp/ * parser.c (lookup_literal_operator): New. (cp_parser_userdef_char_literal): Use it. (cp_parser_userdef_numeric_literal): Use it. (cp_parser_userdef_string_literal): Use lookup_name. libcpp/ * expr.c (cpp_userdef_char_remove_type): Fix typo. From-SVN: r181595
This commit is contained in:
parent
f3fae478f4
commit
7e74ce3f94
@ -1,3 +1,11 @@
|
|||||||
|
2011-11-21 Ed Smith-Rowland <3dw4rd@verizon.net>
|
||||||
|
|
||||||
|
PR c++/50958
|
||||||
|
* parser.c (lookup_literal_operator): New.
|
||||||
|
(cp_parser_userdef_char_literal): Use it.
|
||||||
|
(cp_parser_userdef_numeric_literal): Use it.
|
||||||
|
(cp_parser_userdef_string_literal): Use lookup_name.
|
||||||
|
|
||||||
2011-11-20 Jason Merrill <jason@redhat.com>
|
2011-11-20 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
* pt.c (tsubst_pack_expansion): Fix SFINAE.
|
* pt.c (tsubst_pack_expansion): Fix SFINAE.
|
||||||
|
159
gcc/cp/parser.c
159
gcc/cp/parser.c
@ -3547,40 +3547,79 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Look up a literal operator with the name and the exact arguments. */
|
||||||
|
|
||||||
|
static tree
|
||||||
|
lookup_literal_operator (tree name, VEC(tree,gc) *args)
|
||||||
|
{
|
||||||
|
tree decl, fns;
|
||||||
|
decl = lookup_name (name);
|
||||||
|
if (!decl || decl == error_mark_node)
|
||||||
|
return error_mark_node;
|
||||||
|
|
||||||
|
for (fns = decl; fns; fns = OVL_NEXT (fns))
|
||||||
|
{
|
||||||
|
unsigned int ix;
|
||||||
|
bool found = true;
|
||||||
|
tree fn = OVL_CURRENT (fns);
|
||||||
|
tree argtypes = NULL_TREE;
|
||||||
|
argtypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
||||||
|
if (argtypes != NULL_TREE)
|
||||||
|
{
|
||||||
|
for (ix = 0; ix < VEC_length (tree, args) && argtypes != NULL_TREE;
|
||||||
|
++ix, argtypes = TREE_CHAIN (argtypes))
|
||||||
|
{
|
||||||
|
tree targ = TREE_VALUE (argtypes);
|
||||||
|
tree tparm = TREE_TYPE (VEC_index (tree, args, ix));
|
||||||
|
bool ptr = TREE_CODE (targ) == POINTER_TYPE;
|
||||||
|
bool arr = TREE_CODE (tparm) == ARRAY_TYPE;
|
||||||
|
if ((ptr || arr || !same_type_p (targ, tparm))
|
||||||
|
&& (!ptr || !arr
|
||||||
|
|| !same_type_p (TREE_TYPE (targ),
|
||||||
|
TREE_TYPE (tparm))))
|
||||||
|
found = false;
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error_mark_node;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse a user-defined char constant. Returns a call to a user-defined
|
/* Parse a user-defined char constant. Returns a call to a user-defined
|
||||||
literal operator taking the character as an argument. */
|
literal operator taking the character as an argument. */
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
cp_parser_userdef_char_literal (cp_parser *parser)
|
cp_parser_userdef_char_literal (cp_parser *parser)
|
||||||
{
|
{
|
||||||
cp_token *token = NULL;
|
cp_token *token = cp_lexer_consume_token (parser->lexer);
|
||||||
tree literal, suffix_id, value;
|
tree literal = token->u.value;
|
||||||
tree name, decl;
|
tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
|
||||||
tree result;
|
tree value = USERDEF_LITERAL_VALUE (literal);
|
||||||
VEC(tree,gc) *vec;
|
tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
|
||||||
|
tree decl, result;
|
||||||
token = cp_lexer_consume_token (parser->lexer);
|
|
||||||
literal = token->u.value;
|
|
||||||
suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
|
|
||||||
value = USERDEF_LITERAL_VALUE (literal);
|
|
||||||
name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
|
|
||||||
|
|
||||||
/* Build up a call to the user-defined operator */
|
/* Build up a call to the user-defined operator */
|
||||||
/* Lookup the name we got back from the id-expression. */
|
/* Lookup the name we got back from the id-expression. */
|
||||||
vec = make_tree_vector ();
|
VEC(tree,gc) *args = make_tree_vector ();
|
||||||
VEC_safe_push (tree, gc, vec, value);
|
VEC_safe_push (tree, gc, args, value);
|
||||||
decl = lookup_function_nonclass (name, vec, /*block_p=*/false);
|
decl = lookup_literal_operator (name, args);
|
||||||
if (!decl || decl == error_mark_node)
|
if (!decl || decl == error_mark_node)
|
||||||
{
|
{
|
||||||
error ("unable to find user-defined character literal operator %qD",
|
error ("unable to find character literal operator %qD with %qT argument",
|
||||||
name);
|
name, TREE_TYPE (value));
|
||||||
release_tree_vector (vec);
|
release_tree_vector (args);
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
result = finish_call_expr (decl, &vec, false, true, tf_warning_or_error);
|
result = finish_call_expr (decl, &args, false, true, tf_warning_or_error);
|
||||||
release_tree_vector (vec);
|
release_tree_vector (args);
|
||||||
|
if (result != error_mark_node)
|
||||||
|
return result;
|
||||||
|
|
||||||
return result;
|
error ("unable to find character literal operator %qD with %qT argument",
|
||||||
|
name, TREE_TYPE (value));
|
||||||
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A subroutine of cp_parser_userdef_numeric_literal to
|
/* A subroutine of cp_parser_userdef_numeric_literal to
|
||||||
@ -3615,26 +3654,20 @@ make_char_string_pack (tree value)
|
|||||||
static tree
|
static tree
|
||||||
cp_parser_userdef_numeric_literal (cp_parser *parser)
|
cp_parser_userdef_numeric_literal (cp_parser *parser)
|
||||||
{
|
{
|
||||||
cp_token *token = NULL;
|
cp_token *token = cp_lexer_consume_token (parser->lexer);
|
||||||
tree literal, suffix_id, value, num_string;
|
tree literal = token->u.value;
|
||||||
tree name, decl;
|
tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
|
||||||
tree result = error_mark_node;
|
tree value = USERDEF_LITERAL_VALUE (literal);
|
||||||
|
tree num_string = USERDEF_LITERAL_NUM_STRING (literal);
|
||||||
|
tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
|
||||||
|
tree decl, result;
|
||||||
VEC(tree,gc) *args;
|
VEC(tree,gc) *args;
|
||||||
|
|
||||||
token = cp_lexer_consume_token (parser->lexer);
|
/* Look for a literal operator taking the exact type of numeric argument
|
||||||
literal = token->u.value;
|
as the literal value. */
|
||||||
suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
|
|
||||||
value = USERDEF_LITERAL_VALUE (literal);
|
|
||||||
num_string = USERDEF_LITERAL_NUM_STRING (literal);
|
|
||||||
name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
|
|
||||||
|
|
||||||
/* 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 ();
|
args = make_tree_vector ();
|
||||||
VEC_safe_push (tree, gc, args, value);
|
VEC_safe_push (tree, gc, args, value);
|
||||||
decl = lookup_function_nonclass (name, args, /*block_p=*/false);
|
decl = lookup_literal_operator (name, args);
|
||||||
if (decl && decl != error_mark_node)
|
if (decl && decl != error_mark_node)
|
||||||
{
|
{
|
||||||
result = finish_call_expr (decl, &args, false, true, tf_none);
|
result = finish_call_expr (decl, &args, false, true, tf_none);
|
||||||
@ -3651,7 +3684,7 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
|
|||||||
in string format. */
|
in string format. */
|
||||||
args = make_tree_vector ();
|
args = make_tree_vector ();
|
||||||
VEC_safe_push (tree, gc, args, num_string);
|
VEC_safe_push (tree, gc, args, num_string);
|
||||||
decl = lookup_function_nonclass (name, args, /*block_p=*/false);
|
decl = lookup_literal_operator (name, args);
|
||||||
if (decl && decl != error_mark_node)
|
if (decl && decl != error_mark_node)
|
||||||
{
|
{
|
||||||
result = finish_call_expr (decl, &args, false, true, tf_none);
|
result = finish_call_expr (decl, &args, false, true, tf_none);
|
||||||
@ -3667,7 +3700,7 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
|
|||||||
function with parameter pack char.... Call the function with
|
function with parameter pack char.... Call the function with
|
||||||
template parameter characters representing the number. */
|
template parameter characters representing the number. */
|
||||||
args = make_tree_vector ();
|
args = make_tree_vector ();
|
||||||
decl = lookup_function_nonclass (name, args, /*block_p=*/false);
|
decl = lookup_literal_operator (name, args);
|
||||||
if (decl && decl != error_mark_node)
|
if (decl && decl != error_mark_node)
|
||||||
{
|
{
|
||||||
tree tmpl_args = make_char_string_pack (num_string);
|
tree tmpl_args = make_char_string_pack (num_string);
|
||||||
@ -3681,10 +3714,8 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
|
|||||||
}
|
}
|
||||||
release_tree_vector (args);
|
release_tree_vector (args);
|
||||||
|
|
||||||
if (result == error_mark_node)
|
error ("unable to find numeric literal operator %qD", name);
|
||||||
error ("unable to find user-defined numeric literal operator %qD", name);
|
return error_mark_node;
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse a user-defined string constant. Returns a call to a user-defined
|
/* Parse a user-defined string constant. Returns a call to a user-defined
|
||||||
@ -3694,38 +3725,34 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
|
|||||||
static tree
|
static tree
|
||||||
cp_parser_userdef_string_literal (cp_token *token)
|
cp_parser_userdef_string_literal (cp_token *token)
|
||||||
{
|
{
|
||||||
tree literal, suffix_id, value;
|
tree literal = token->u.value;
|
||||||
tree name, decl;
|
tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
|
||||||
tree result;
|
tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
|
||||||
VEC(tree,gc) *vec;
|
tree value = USERDEF_LITERAL_VALUE (literal);
|
||||||
int len;
|
int len = TREE_STRING_LENGTH (value)
|
||||||
|
|
||||||
literal = token->u.value;
|
|
||||||
suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
|
|
||||||
name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
|
|
||||||
value = USERDEF_LITERAL_VALUE (literal);
|
|
||||||
len = TREE_STRING_LENGTH (value)
|
|
||||||
/ TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value)))) - 1;
|
/ TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value)))) - 1;
|
||||||
|
tree decl, result;
|
||||||
|
|
||||||
/* Build up a call to the user-defined operator */
|
/* Build up a call to the user-defined operator */
|
||||||
/* Lookup the name we got back from the id-expression. */
|
/* Lookup the name we got back from the id-expression. */
|
||||||
vec = make_tree_vector ();
|
VEC(tree,gc) *args = make_tree_vector ();
|
||||||
VEC_safe_push (tree, gc, vec, value);
|
VEC_safe_push (tree, gc, args, value);
|
||||||
VEC_safe_push (tree, gc, vec, build_int_cst (size_type_node, len));
|
VEC_safe_push (tree, gc, args, 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)
|
if (!decl || decl == error_mark_node)
|
||||||
{
|
{
|
||||||
error ("unable to find user-defined string literal operator %qD", name);
|
error ("unable to find string literal operator %qD", name);
|
||||||
release_tree_vector (vec);
|
release_tree_vector (args);
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
result = finish_call_expr (decl, &vec, false, true, tf_none);
|
result = finish_call_expr (decl, &args, false, true, tf_none);
|
||||||
if (result == error_mark_node)
|
release_tree_vector (args);
|
||||||
error ("unable to find valid user-defined string literal operator %qD."
|
if (result != error_mark_node)
|
||||||
" Possible missing length argument in string literal operator.",
|
return result;
|
||||||
name);
|
|
||||||
release_tree_vector (vec);
|
|
||||||
|
|
||||||
return result;
|
error ("unable to find string literal operator %qD with %qT, %qT arguments",
|
||||||
|
name, TREE_TYPE (value), size_type_node);
|
||||||
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,3 +1,14 @@
|
|||||||
|
2011-11-21 Ed Smith-Rowland <3dw4rd@verizon.net>
|
||||||
|
|
||||||
|
PR c++/50958
|
||||||
|
* g++.dg/cpp0x/udlit-declare-neg.C: Adjust.
|
||||||
|
* g++.dg/cpp0x/udlit-implicit-conv-neg.C: New.
|
||||||
|
* g++.dg/cpp0x/udlit-member.C: Adjust.
|
||||||
|
* g++.dg/cpp0x/udlit-raw-length.C: New.
|
||||||
|
* g++.dg/cpp0x/udlit-raw-op-string-neg.C: Adjust.
|
||||||
|
* g++.dg/cpp0x/udlit-resolve.C: New.
|
||||||
|
* c-c++-common/dfp/pr33466.c: Adjust.
|
||||||
|
|
||||||
2011-11-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
2011-11-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||||
|
|
||||||
* lib/target-supports.exp
|
* lib/target-supports.exp
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
These are invalid for all targets, not just those that support
|
These are invalid for all targets, not just those that support
|
||||||
decimal float. */
|
decimal float. */
|
||||||
|
|
||||||
long double dF = 4.5dF; /* { dg-error "invalid suffix|user-defined" } */
|
long double dF = 4.5dF; /* { dg-error "invalid suffix|literal operator" } */
|
||||||
long double Df = 4.5Df; /* { dg-error "invalid suffix|user-defined" } */
|
long double Df = 4.5Df; /* { dg-error "invalid suffix|literal operator" } */
|
||||||
long double dD = 4.5dD; /* { dg-error "invalid suffix|user-defined" } */
|
long double dD = 4.5dD; /* { dg-error "invalid suffix|literal operator" } */
|
||||||
long double Dd = 4.5Dd; /* { dg-error "invalid suffix|user-defined" } */
|
long double Dd = 4.5Dd; /* { dg-error "invalid suffix|literal operator" } */
|
||||||
long double dL = 4.5dL; /* { dg-error "invalid suffix|user-defined" } */
|
long double dL = 4.5dL; /* { dg-error "invalid suffix|literal operator" } */
|
||||||
long double Dl = 4.5Dl; /* { dg-error "invalid suffix|user-defined" } */
|
long double Dl = 4.5Dl; /* { dg-error "invalid suffix|literal operator" } */
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
// Check that undeclared literal operator calls and literals give appropriate errors.
|
// Check that undeclared literal operator calls and literals give appropriate errors.
|
||||||
|
|
||||||
int i = operator"" _Bar('x'); // { dg-error "was not declared in this scope" }
|
int i = operator"" _Bar('x'); // { dg-error "was not declared in this scope" }
|
||||||
int j = 'x'_Bar; // { dg-error "unable to find user-defined character literal operator" }
|
int j = 'x'_Bar; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
|
||||||
int ii = operator"" _BarCharStr("Howdy, Pardner!"); // { dg-error "was not declared in this scope" }
|
int ii = operator"" _BarCharStr("Howdy, Pardner!"); // { dg-error "was not declared in this scope" }
|
||||||
int jj = "Howdy, Pardner!"_BarCharStr; // { dg-error "unable to find user-defined string literal operator" }
|
int jj = "Howdy, Pardner!"_BarCharStr; // { dg-error "unable to find string literal operator|Possible missing length argument" }
|
||||||
|
|
||||||
unsigned long long iULL = operator"" _BarULL(666ULL); // { dg-error "was not declared in this scope" }
|
unsigned long long iULL = operator"" _BarULL(666ULL); // { dg-error "was not declared in this scope" }
|
||||||
unsigned long long jULL = 666_BarULL; // { dg-error "unable to find user-defined numeric literal operator" }
|
unsigned long long jULL = 666_BarULL; // { dg-error "unable to find numeric literal operator" }
|
||||||
|
|
||||||
long double iLD = operator"" _BarLD(666.0L); // { dg-error "was not declared in this scope" }
|
long double iLD = operator"" _BarLD(666.0L); // { dg-error "was not declared in this scope" }
|
||||||
long double jLD = 666.0_BarLD; // { dg-error "unable to find user-defined numeric literal operator" }
|
long double jLD = 666.0_BarLD; // { dg-error "unable to find numeric literal operator" }
|
||||||
|
63
gcc/testsuite/g++.dg/cpp0x/udlit-implicit-conv-neg.C
Normal file
63
gcc/testsuite/g++.dg/cpp0x/udlit-implicit-conv-neg.C
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// { dg-options -std=c++0x }
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
int operator"" _bar (long double);
|
||||||
|
|
||||||
|
double operator"" _foo (long long unsigned);
|
||||||
|
|
||||||
|
int i = 12_bar; // { dg-error "unable to find numeric literal operator|with|argument" }
|
||||||
|
|
||||||
|
double d = 1.2_foo; // { dg-error "unable to find numeric literal operator|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 cwcx = 'c'_wchar_t; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
int cc16 = 'c'_char16_t; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
int cc32 = 'c'_char32_t; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
|
||||||
|
int wccx = L'c'_char; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
int wcc16 = L'c'_char16_t; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
int wcc32 = L'c'_char32_t; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
|
||||||
|
int c16c = u'c'_char; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
int c16wc = u'c'_wchar_t; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
int c16c32 = u'c'_char32_t; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
|
||||||
|
int c32c = U'c'_char; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
int c32wc = U'c'_wchar_t; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
int c32c16 = U'c'_char16_t; // { dg-error "unable to find character literal operator|with|argument" }
|
||||||
|
|
||||||
|
int operator"" _char_str(const char*, std::size_t);
|
||||||
|
|
||||||
|
int operator"" _wchar_t_str(const wchar_t*, std::size_t);
|
||||||
|
|
||||||
|
int operator"" _char16_t_str(const char16_t*, std::size_t);
|
||||||
|
|
||||||
|
int operator"" _char32_t_str(const char32_t*, std::size_t);
|
||||||
|
|
||||||
|
int strwstr = "str"_wchar_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
int strstr16 = "str"_char16_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
int strstr32 = "str"_char32_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
|
||||||
|
int str8wstr = u8"str"_wchar_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
int str8str16 = u8"str"_char16_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
int str8str32 = u8"str"_char32_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
|
||||||
|
int wstrstr = L"str"_char_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
int wstrstr16 = L"str"_char16_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
int wstrstr32 = L"str"_char32_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
|
||||||
|
int str16str = u"str"_char_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
int str16wstr = u"str"_wchar_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
int str16str32 = u"str"_char32_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
|
||||||
|
int str32str = U"str"_char_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
int str32wstr = U"str"_wchar_t_str; // { dg-error "unable to find string literal operator|with|arguments" }
|
||||||
|
int str32str16 = U"str"_char16_t_str; // { dg-error "unable to find string literal operator string operator|with|arguments" }
|
@ -8,7 +8,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
int i = operator"" _Bar(U'x'); // { dg-error "was not declared in this scope" }
|
int i = operator"" _Bar(U'x'); // { dg-error "was not declared in this scope" }
|
||||||
int j = U'x'_Bar; // { dg-error "unable to find user-defined character literal operator" }
|
int j = U'x'_Bar; // { dg-error "unable to find character literal operator" }
|
||||||
|
|
||||||
int
|
int
|
||||||
Foo::operator"" _Bar(char32_t) // { dg-error "must be a non-member function" }
|
Foo::operator"" _Bar(char32_t) // { dg-error "must be a non-member function" }
|
||||||
|
27
gcc/testsuite/g++.dg/cpp0x/udlit-raw-length.C
Normal file
27
gcc/testsuite/g++.dg/cpp0x/udlit-raw-length.C
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// { dg-options "-std=c++0x" }
|
||||||
|
// PR c++/50958
|
||||||
|
|
||||||
|
typedef decltype(sizeof(0)) size_type;
|
||||||
|
|
||||||
|
constexpr size_type
|
||||||
|
cstrlen_impl(const char* s, size_type i)
|
||||||
|
{
|
||||||
|
return s[i] ? cstrlen_impl(s, i + 1) : i;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_type
|
||||||
|
cstrlen(const char* s)
|
||||||
|
{
|
||||||
|
return s ? cstrlen_impl(s, 0) : throw 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_type
|
||||||
|
operator "" _lenraw(const char* digits)
|
||||||
|
{
|
||||||
|
return cstrlen(digits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(123_lenraw == 3, "Ouch");
|
||||||
|
static_assert(1_lenraw == 1, "Ouch");
|
||||||
|
static_assert(012_lenraw == 3, "Ouch");
|
||||||
|
static_assert(0_lenraw == 1, "Ouch");
|
@ -5,4 +5,4 @@
|
|||||||
int operator"" _embedraw(const char*)
|
int operator"" _embedraw(const char*)
|
||||||
{ return 41; };
|
{ return 41; };
|
||||||
|
|
||||||
int k = "Boo!"_embedraw; // { dg-error "unable to find valid user-defined string literal operator" }
|
int k = "Boo!"_embedraw; // { dg-error "unable to find string literal operator" }
|
||||||
|
40
gcc/testsuite/g++.dg/cpp0x/udlit-resolve.C
Normal file
40
gcc/testsuite/g++.dg/cpp0x/udlit-resolve.C
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// { dg-do run }
|
||||||
|
// { dg-options "-std=c++0x" }
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
int operator"" _foo(const char*) { return 0; }
|
||||||
|
int operator"" _foo(unsigned long long int) { return 1; }
|
||||||
|
int operator"" _foo(long double) { return 2; }
|
||||||
|
int operator"" _foo(char) { return 3; }
|
||||||
|
int operator"" _foo(wchar_t) { return 4; }
|
||||||
|
int operator"" _foo(char16_t) { return 5; }
|
||||||
|
int operator"" _foo(char32_t) { return 6; }
|
||||||
|
int operator"" _foo(const char*, std::size_t) { return 7; }
|
||||||
|
int operator"" _foo(const wchar_t*, std::size_t) { return 8; }
|
||||||
|
int operator"" _foo(const char16_t*, std::size_t) { return 9; }
|
||||||
|
int operator"" _foo(const char32_t*, std::size_t) { return 10; }
|
||||||
|
template<char...> int operator"" _foo2() { return 20; }
|
||||||
|
int operator"" _foo2(unsigned long long int) { return 21; }
|
||||||
|
|
||||||
|
namespace bar {
|
||||||
|
int operator"" _foo(unsigned long long int) { return 101; }
|
||||||
|
}
|
||||||
|
using namespace bar;
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
assert(123_foo == 101);
|
||||||
|
assert(0.123_foo == 2);
|
||||||
|
assert('c'_foo == 3);
|
||||||
|
assert(L'c'_foo == 4);
|
||||||
|
assert(u'c'_foo == 5);
|
||||||
|
assert(U'c'_foo == 6);
|
||||||
|
assert("abc"_foo == 7);
|
||||||
|
assert(L"abc"_foo == 8);
|
||||||
|
assert(u"abc"_foo == 9);
|
||||||
|
assert(U"abc"_foo == 10);
|
||||||
|
assert(123_foo2 == 21);
|
||||||
|
}
|
@ -1,3 +1,8 @@
|
|||||||
|
2011-11-21 Ed Smith-Rowland <3dw4rd@verizon.net>
|
||||||
|
|
||||||
|
PR c++/50958
|
||||||
|
* expr.c (cpp_userdef_char_remove_type): Fix typo.
|
||||||
|
|
||||||
2011-11-03 Michael Matz <matz@suse.de>
|
2011-11-03 Michael Matz <matz@suse.de>
|
||||||
|
|
||||||
PR bootstrap/50857
|
PR bootstrap/50857
|
||||||
|
@ -284,9 +284,9 @@ cpp_userdef_char_remove_type (enum cpp_ttype type)
|
|||||||
else if (type == CPP_WCHAR_USERDEF)
|
else if (type == CPP_WCHAR_USERDEF)
|
||||||
return CPP_WCHAR;
|
return CPP_WCHAR;
|
||||||
else if (type == CPP_CHAR16_USERDEF)
|
else if (type == CPP_CHAR16_USERDEF)
|
||||||
return CPP_STRING16;
|
return CPP_CHAR16;
|
||||||
else if (type == CPP_CHAR32_USERDEF)
|
else if (type == CPP_CHAR32_USERDEF)
|
||||||
return CPP_STRING32;
|
return CPP_CHAR32;
|
||||||
else
|
else
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user