diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 25 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 4 | ||||
-rw-r--r-- | gcc/cp/lex.c | 2 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 4 | ||||
-rw-r--r-- | gcc/cp/parser.c | 16 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 2 | ||||
-rw-r--r-- | gcc/cp/tree.c | 1 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 4 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 57 |
11 files changed, 85 insertions, 32 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 82412a7..5d0ef12 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,28 @@ +2019-01-14 Tom Honermann <tom@honermann.net> + + Implement P0482R5, char8_t: A type for UTF-8 characters and strings + * cvt.c (type_promotes_to): Handle char8_t promotion. + * decl.c (grokdeclarator): Handle invalid type specifier + combinations involving char8_t. + * lex.c (init_reswords): Add char8_t as a reserved word. + * mangle.c (write_builtin_type): Add name mangling for char8_t (Du). + * parser.c (cp_keyword_starts_decl_specifier_p) + (cp_parser_simple_type_specifier): Recognize char8_t as a simple + type specifier. + (cp_parser_string_literal): Use char8_array_type_node for the type + of CPP_UTF8STRING. + (cp_parser_set_decl_spec_type): Tolerate char8_t typedefs in system + headers. + * rtti.c (emit_support_tinfos): type_info support for char8_t. + * tree.c (char_type_p): Recognize char8_t as a character type. + * typeck.c (string_conv_p): Handle conversions of u8 string + literals of char8_t type. + (check_literal_operator_args): Handle UDLs with u8 string literals + of char8_t type. + * typeck2.c (ordinary_char_type_p): New. + (digest_init_r): Disallow initializing a char array with a u8 string + literal. + 2019-01-14 Martin Liska <mliska@suse.cz> PR gcov-profile/88263 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5648946..6a20043 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7488,6 +7488,7 @@ extern tree store_init_value (tree, tree, vec<tree, va_gc>**, int); extern tree split_nonconstant_init (tree, tree); extern bool check_narrowing (tree, tree, tsubst_flags_t, bool = false); +extern bool ordinary_char_type_p (tree); extern tree digest_init (tree, tree, tsubst_flags_t); extern tree digest_init_flags (tree, tree, int, tsubst_flags_t); extern tree digest_nsdmi_init (tree, tree, tsubst_flags_t); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 449ce50..9142811 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -1877,6 +1877,7 @@ type_promotes_to (tree type) wider. Scoped enums don't promote, but pretend they do for backward ABI bug compatibility wrt varargs. */ else if (TREE_CODE (type) == ENUMERAL_TYPE + || type == char8_type_node || type == char16_type_node || type == char32_type_node || type == wchar_type_node) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6e75c3d..41972aa 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10770,7 +10770,9 @@ grokdeclarator (const cp_declarator *declarator, error_at (&richloc, "%<long%> and %<short%> specified together"); } else if (TREE_CODE (type) != INTEGER_TYPE - || type == char16_type_node || type == char32_type_node + || type == char8_type_node + || type == char16_type_node + || type == char32_type_node || ((long_p || short_p) && (explicit_char || explicit_intN))) error_at (loc, "%qs specified with %qT", key, type); diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 36ffa37..369ecc0 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -233,6 +233,8 @@ init_reswords (void) mask |= D_CXX_CONCEPTS; if (!flag_tm) mask |= D_TRANSMEM; + if (!flag_char8_t) + mask |= D_CXX_CHAR8_T; if (flag_no_asm) mask |= D_ASM | D_EXT; if (flag_no_gnu_keywords) diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 919f7b3..00bde4e 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2473,10 +2473,12 @@ write_builtin_type (tree type) break; case INTEGER_TYPE: - /* TYPE may still be wchar_t, char16_t, or char32_t, since that + /* TYPE may still be wchar_t, char8_t, char16_t, or char32_t, since that isn't in integer_type_nodes. */ if (type == wchar_type_node) write_char ('w'); + else if (type == char8_type_node) + write_string ("Du"); else if (type == char16_type_node) write_string ("Ds"); else if (type == char32_type_node) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index be669f2..7d7b029 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -948,6 +948,7 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword) case RID_TYPENAME: /* Simple type specifiers. */ case RID_CHAR: + case RID_CHAR8: case RID_CHAR16: case RID_CHAR32: case RID_WCHAR: @@ -4235,9 +4236,14 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok, { default: case CPP_STRING: - case CPP_UTF8STRING: TREE_TYPE (value) = char_array_type_node; break; + case CPP_UTF8STRING: + if (flag_char8_t) + TREE_TYPE (value) = char8_array_type_node; + else + TREE_TYPE (value) = char_array_type_node; + break; case CPP_STRING16: TREE_TYPE (value) = char16_array_type_node; break; @@ -17504,6 +17510,9 @@ cp_parser_simple_type_specifier (cp_parser* parser, decl_specs->explicit_char_p = true; type = char_type_node; break; + case RID_CHAR8: + type = char8_type_node; + break; case RID_CHAR16: type = char16_type_node; break; @@ -28919,14 +28928,15 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs, { decl_specs->any_specifiers_p = true; - /* If the user tries to redeclare bool, char16_t, char32_t, or wchar_t - (with, for example, in "typedef int wchar_t;") we remember that + /* If the user tries to redeclare bool, char8_t, char16_t, char32_t, or + wchar_t (with, for example, in "typedef int wchar_t;") we remember that this is what happened. In system headers, we ignore these declarations so that G++ can work with system headers that are not C++-safe. */ if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef) && !type_definition_p && (type_spec == boolean_type_node + || type_spec == char8_type_node || type_spec == char16_type_node || type_spec == char32_type_node || type_spec == wchar_type_node) diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index a6d32b9..c4aabea 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -1539,7 +1539,7 @@ emit_support_tinfos (void) { &void_type_node, &boolean_type_node, - &wchar_type_node, &char16_type_node, &char32_type_node, + &wchar_type_node, &char8_type_node, &char16_type_node, &char32_type_node, &char_type_node, &signed_char_type_node, &unsigned_char_type_node, &short_integer_type_node, &short_unsigned_type_node, &integer_type_node, &unsigned_type_node, diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 4db89a4..5000216 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -5022,6 +5022,7 @@ char_type_p (tree type) return (same_type_p (type, char_type_node) || same_type_p (type, unsigned_char_type_node) || same_type_p (type, signed_char_type_node) + || same_type_p (type, char8_type_node) || same_type_p (type, char16_type_node) || same_type_p (type, char32_type_node) || same_type_p (type, wchar_type_node)); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 43d2899..88e2cd6 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2216,6 +2216,7 @@ string_conv_p (const_tree totype, const_tree exp, int warn) t = TREE_TYPE (totype); if (!same_type_p (t, char_type_node) + && !same_type_p (t, char8_type_node) && !same_type_p (t, char16_type_node) && !same_type_p (t, char32_type_node) && !same_type_p (t, wchar_type_node)) @@ -10288,6 +10289,7 @@ check_literal_operator_args (const_tree decl, t = TYPE_MAIN_VARIANT (t); if ((maybe_raw_p = same_type_p (t, char_type_node)) || same_type_p (t, wchar_type_node) + || same_type_p (t, char8_type_node) || same_type_p (t, char16_type_node) || same_type_p (t, char32_type_node)) { @@ -10320,6 +10322,8 @@ check_literal_operator_args (const_tree decl, max_arity = 1; else if (same_type_p (t, wchar_type_node)) max_arity = 1; + else if (same_type_p (t, char8_type_node)) + max_arity = 1; else if (same_type_p (t, char16_type_node)) max_arity = 1; else if (same_type_p (t, char32_type_node)) diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index ecc313b..cd43132 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1026,6 +1026,17 @@ check_narrowing (tree type, tree init, tsubst_flags_t complain, bool const_only) return ok; } +/* True iff TYPE is a C++2a "ordinary" character type. */ + +bool +ordinary_char_type_p (tree type) +{ + type = TYPE_MAIN_VARIANT (type); + return (type == char_type_node + || type == signed_char_type_node + || type == unsigned_char_type_node); +} + /* Process the initializer INIT for a variable of type TYPE, emitting diagnostics for invalid initializers and converting the initializer as appropriate. @@ -1091,36 +1102,30 @@ digest_init_r (tree type, tree init, int nested, int flags, && TREE_CODE (stripped_init) == STRING_CST) { tree char_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init))); + bool incompat_string_cst = false; - if (TYPE_PRECISION (typ1) == BITS_PER_UNIT) + if (typ1 != char_type) { - if (char_type != char_type_node - && char_type != signed_char_type_node - && char_type != unsigned_char_type_node) - { - if (complain & tf_error) - error_at (loc, "char-array initialized from wide string"); - return error_mark_node; - } + /* The array element type does not match the initializing string + literal element type; this is only allowed when both types are + ordinary character type. There are no string literals of + signed or unsigned char type in the language, but we can get + them internally from converting braced-init-lists to + STRING_CST. */ + if (ordinary_char_type_p (typ1) + && ordinary_char_type_p (char_type)) + /* OK */; + else + incompat_string_cst = true; } - else + + if (incompat_string_cst) { - if (char_type == char_type_node - || char_type == signed_char_type_node - || char_type == unsigned_char_type_node) - { - if (complain & tf_error) - error_at (loc, - "int-array initialized from non-wide string"); - return error_mark_node; - } - else if (char_type != typ1) - { - if (complain & tf_error) - error_at (loc, "int-array initialized from incompatible " - "wide string"); - return error_mark_node; - } + if (complain & tf_error) + error_at (loc, "cannot initialize array of %qT from " + "a string literal with type array of %qT", + typ1, char_type); + return error_mark_node; } if (nested == 2 && !TYPE_DOMAIN (type)) |