diff options
-rw-r--r-- | gcc/c-common.c | 9 | ||||
-rw-r--r-- | gcc/c-decl.c | 6 | ||||
-rw-r--r-- | gcc/c-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/cp/call.c | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 10 | ||||
-rw-r--r-- | gcc/cp/decl.c | 5 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 11 | ||||
-rw-r--r-- | gcc/cp/lang-options.h | 2 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 40 |
10 files changed, 97 insertions, 15 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index 9e45067..8916958 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -298,7 +298,6 @@ combine_strings (strings) value = make_node (STRING_CST); TREE_STRING_POINTER (value) = p; TREE_STRING_LENGTH (value) = length; - TREE_CONSTANT (value) = 1; } else { @@ -313,8 +312,9 @@ combine_strings (strings) /* Create the array type for the string constant. -Wwrite-strings says make the string constant an array of const char - so that copying it to a non-const pointer will get a warning. */ - if (warn_write_strings + so that copying it to a non-const pointer will get a warning. + For C++, this is the standard behavior. */ + if (flag_const_strings && (! flag_traditional && ! flag_writable_strings)) { tree elements @@ -328,7 +328,8 @@ combine_strings (strings) TREE_TYPE (value) = build_array_type (wide_flag ? wchar_type_node : char_type_node, build_index_type (build_int_2 (nchars - 1, 0))); - TREE_CONSTANT (value) = 1; + + TREE_READONLY (value) = TREE_CONSTANT (value) = ! flag_writable_strings; TREE_STATIC (value) = 1; return value; } diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 1b040b1..9f880c3 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -498,7 +498,7 @@ int mesg_implicit_function_declaration; to get extra warnings from them. These warnings will be too numerous to be useful, except in thoroughly ANSIfied programs. */ -int warn_write_strings; +int flag_const_strings; /* Nonzero means warn about pointer casts that can drop a type qualifier from the pointer target type. */ @@ -713,9 +713,9 @@ c_decode_option (argc, argv) else if (!strcmp (p, "-Wno-long-long")) warn_long_long = 0; else if (!strcmp (p, "-Wwrite-strings")) - warn_write_strings = 1; + flag_const_strings = 1; else if (!strcmp (p, "-Wno-write-strings")) - warn_write_strings = 0; + flag_const_strings = 0; else if (!strcmp (p, "-Wcast-qual")) warn_cast_qual = 1; else if (!strcmp (p, "-Wno-cast-qual")) diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 7605cfe..6635fd1 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -430,7 +430,7 @@ extern int warn_implicit; to get extra warnings from them. These warnings will be too numerous to be useful, except in thoroughly ANSIfied programs. */ -extern int warn_write_strings; +extern int flag_const_strings; /* Nonzero means warn about sizeof (function) or addition/subtraction of function pointers. */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1941f15..19db217 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,22 @@ +1998-08-24 Jason Merrill <jason@yorick.cygnus.com> + + * tree.c (lvalue_type): Fix for arrays. + * typeck.c (string_conv_p): New fn. + (convert_for_assignment): Use it. + (build_unary_op): Use lvalue_type. + * call.c (standard_conversion, convert_like): Use string_conv_p. + (add_function_candidate): Use lvalue_type. + * cvt.c (convert_to_reference): Likewise. + * decl2.c (lang_decode_option): Ignore -traditional. + * decl.c (init_decl_processing): flag_writable_strings inhibits + flag_const_strings. + +1998-08-24 Andrew MacLeod <amacleod@cygnus.com> + + * lang-options.h (lang_options): Add fconst-strings to the list + of valid options. + * decl2.c (lang_f_options, lang_decode_option): Likewise. + 1998-08-24 Nathan Sidwell <nathan@acm.org> * lex.c (real_yylex): Don't warn about long long constants if diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 3eb0817..7c1e683 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -883,6 +883,9 @@ standard_conversion (to, from, expr) /* OK */; else if (comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from))) conv = build_conv (QUAL_CONV, to, conv); + else if (expr && string_conv_p (to, expr, 0)) + /* converting from string constant to char *. */ + conv = build_conv (QUAL_CONV, to, conv); else if (ptr_reasonably_similar (TREE_TYPE (to), TREE_TYPE (from))) { conv = build_conv (PTR_CONV, to, conv); @@ -3172,6 +3175,11 @@ convert_like (convs, expr) case LVALUE_CONV: return decay_conversion (expr); + case QUAL_CONV: + /* Warn about deprecated conversion if appropriate. */ + string_conv_p (TREE_TYPE (convs), expr, 1); + break; + default: break; } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 82dc430b..26e39a9 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -342,9 +342,13 @@ extern int warn_ctor_dtor_privacy; extern int warn_return_type; -/* Nonzero means give string constants the type `const char *' - to get extra warnings from them. These warnings will be too numerous - to be useful, except in thoroughly ANSIfied programs. */ +/* Nonzero means give string constants the type `const char *', as mandated + by the standard. */ + +extern int flag_const_strings; + +/* Nonzero means warn about deprecated conversion from string constant to + `char *'. */ extern int warn_write_strings; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 4942b5d..8c3a32b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6200,6 +6200,11 @@ init_decl_processing () print_error_function = lang_print_error_function; lang_get_alias_set = &c_get_alias_set; + + /* Maintain consistency. Perhaps we should just complain if they + say -fwritable-strings? */ + if (flag_writable_strings) + flag_const_strings = 0; } /* Function to print any language-specific context for an error message. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 8d923be..9333d8d 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -211,9 +211,13 @@ int flag_use_repository; int flag_optional_diags = 1; -/* Nonzero means give string constants the type `const char *' - to get extra warnings from them. These warnings will be too numerous - to be useful, except in thoroughly ANSIfied programs. */ +/* Nonzero means give string constants the type `const char *', as mandated + by the standard. */ + +int flag_const_strings = 1; + +/* Nonzero means warn about deprecated conversion from string constant to + `char *'. */ int warn_write_strings; @@ -482,6 +486,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] = {"builtin", &flag_no_builtin, 0}, {"ident", &flag_no_ident, 0}, {"labels-ok", &flag_labels_ok, 1}, + {"const-strings", &flag_const_strings, 1}, {"stats", &flag_detailed_statistics, 1}, {"this-is-variable", &flag_this_is_variable, 1}, {"strict-prototype", &flag_strict_prototype, 1}, diff --git a/gcc/cp/lang-options.h b/gcc/cp/lang-options.h index dc39d28..3c2aee9 100644 --- a/gcc/cp/lang-options.h +++ b/gcc/cp/lang-options.h @@ -38,6 +38,8 @@ DEFINE_LANG_NAME ("C++") { "-fno-check-new", "" }, { "-fconserve-space", "Reduce size of object files" }, { "-fno-conserve-space", "" }, + { "-fconst-strings", "" }, + { "-fno-const-strings", "Make string literals `char[]' instead of `const char[]'" }, { "-fdefault-inline", "" }, { "-fno-default-inline", "Do not inline mmeber functions be default"}, { "-frtti", "" }, diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 3f79953..61ebe18 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1757,6 +1757,42 @@ inline_conversion (exp) } return exp; } + +/* Returns nonzero iff exp is a STRING_CST or the result of applying + decay_conversion to one. */ + +int +string_conv_p (totype, exp, warn) + tree totype, exp; + int warn; +{ + tree t; + + if (! flag_const_strings || TREE_CODE (totype) != POINTER_TYPE) + return 0; + + t = TREE_TYPE (totype); + if (! comptypes (t, char_type_node, 1) + && ! comptypes (t, wchar_type_node, 1)) + return 0; + + if (TREE_CODE (exp) != STRING_CST) + { + t = build_pointer_type (build_type_variant (t, 1, 0)); + if (! comptypes (TREE_TYPE (exp), t, 1)) + return 0; + STRIP_NOPS (exp); + if (TREE_CODE (exp) != ADDR_EXPR + || TREE_CODE (TREE_OPERAND (exp, 0)) != STRING_CST) + return 0; + } + + /* This warning is not very useful, as it complains about printf. */ + if (warn && warn_write_strings) + cp_warning ("deprecated conversion from string constant to `char *'"); + + return 1; +} tree build_object_ref (datum, basetype, field) @@ -6799,7 +6835,9 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) } else if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) { - if (fndecl) + if (string_conv_p (type, rhs, 1)) + /* converting from string constant to char *, OK. */; + else if (fndecl) cp_pedwarn ("passing `%T' as argument %P of `%D' discards const", rhstype, parmnum, fndecl); else |