From: jsm28 Date: Sat, 12 Jun 2010 00:12:12 +0000 (+0000) Subject: * opts-common.c: Include options.h. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=06907f2532ec470c983b61c93bf8d35c786a73db;p=thirdparty%2Fgcc.git * opts-common.c: Include options.h. (integral_argument): Move from opts.c. (decode_cmdline_option): New. Based on read_cmdline_option. * opts.c (integral_argument): Move to opts-common.c. (read_cmdline_option): Move most contents to decode_cmdline_option. Use %qs in diagnostics. * opts.h (CL_ERR_DISABLED, CL_ERR_MISSING_ARG, CL_ERR_WRONG_LANG, CL_ERR_UINT_ARG, struct cl_decoded_option, integral_argument, decode_cmdline_option): New. testsuite: * gcc.dg/funroll-loops-all.c: Update expected error. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160639 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7b5980b39acb..a2e6acecd157 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2010-06-11 Joseph Myers + + * opts-common.c: Include options.h. + (integral_argument): Move from opts.c. + (decode_cmdline_option): New. Based on read_cmdline_option. + * opts.c (integral_argument): Move to opts-common.c. + (read_cmdline_option): Move most contents to + decode_cmdline_option. Use %qs in diagnostics. + * opts.h (CL_ERR_DISABLED, CL_ERR_MISSING_ARG, CL_ERR_WRONG_LANG, + CL_ERR_UINT_ARG, struct cl_decoded_option, integral_argument, + decode_cmdline_option): New. + 2010-06-11 Uros Bizjak PR target/44481 diff --git a/gcc/opts-common.c b/gcc/opts-common.c index d9368d50f14a..513a766e520d 100644 --- a/gcc/opts-common.c +++ b/gcc/opts-common.c @@ -1,5 +1,5 @@ /* Command line option handling. - Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2006, 2007, 2008, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "coretypes.h" #include "opts.h" +#include "options.h" /* Perform a binary search to find which option the command-line INPUT matches. Returns its index in the option array, and N_OPTS @@ -107,6 +108,138 @@ find_opt (const char *input, int lang_mask) return match_wrong_lang; } +/* If ARG is a non-negative integer made up solely of digits, return its + value, otherwise return -1. */ + +int +integral_argument (const char *arg) +{ + const char *p = arg; + + while (*p && ISDIGIT (*p)) + p++; + + if (*p == '\0') + return atoi (arg); + + return -1; +} + +/* Decode the switch beginning at ARGV for the language indicated by + LANG_MASK, into the structure *DECODED. Returns the number of + switches consumed. */ + +unsigned int +decode_cmdline_option (const char **argv, unsigned int lang_mask, + struct cl_decoded_option *decoded) +{ + size_t opt_index; + const char *opt, *arg = 0; + char *dup = 0; + int value = 1; + unsigned int result = 1; + const struct cl_option *option; + int errors = 0; + + opt = argv[0]; + + opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET); + if (opt_index == cl_options_count + && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm') + && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-') + { + /* Drop the "no-" from negative switches. */ + size_t len = strlen (opt) - 3; + + dup = XNEWVEC (char, len + 1); + dup[0] = '-'; + dup[1] = opt[1]; + memcpy (dup + 2, opt + 5, len - 2 + 1); + opt = dup; + value = 0; + opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET); + } + + if (opt_index == cl_options_count) + goto done; + + option = &cl_options[opt_index]; + + /* Reject negative form of switches that don't take negatives as + unrecognized. */ + if (!value && (option->flags & CL_REJECT_NEGATIVE)) + { + opt_index = cl_options_count; + goto done; + } + + /* Check to see if the option is disabled for this configuration. */ + if (option->flags & CL_DISABLED) + errors |= CL_ERR_DISABLED; + + /* Sort out any argument the switch takes. */ + if (option->flags & CL_JOINED) + { + /* Have arg point to the original switch. This is because + some code, such as disable_builtin_function, expects its + argument to be persistent until the program exits. */ + arg = argv[0] + cl_options[opt_index].opt_len + 1; + if (!value) + arg += strlen ("no-"); + + if (*arg == '\0' && !(option->flags & CL_MISSING_OK)) + { + if (option->flags & CL_SEPARATE) + { + arg = argv[1]; + result = 2; + if (arg == NULL) + result = 1; + } + else + /* Missing argument. */ + arg = NULL; + } + } + else if (option->flags & CL_SEPARATE) + { + arg = argv[1]; + result = 2; + if (arg == NULL) + result = 1; + } + + /* Check if this is a switch for a different front end. */ + if (!(option->flags & (lang_mask | CL_COMMON | CL_TARGET))) + errors |= CL_ERR_WRONG_LANG; + else if ((option->flags & CL_TARGET) + && (option->flags & CL_LANG_ALL) + && !(option->flags & lang_mask)) + /* Complain for target flag language mismatches if any languages + are specified. */ + errors |= CL_ERR_WRONG_LANG; + + if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE))) + errors |= CL_ERR_MISSING_ARG; + + /* If the switch takes an integer, convert it. */ + if (arg && (option->flags & CL_UINTEGER)) + { + value = integral_argument (arg); + if (value == -1) + errors |= CL_ERR_UINT_ARG; + } + + done: + if (dup) + free (dup); + decoded->opt_index = opt_index; + decoded->arg = arg; + decoded->value = value; + decoded->errors = errors; + return result; +} + /* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the next one is the same as ORIG_NEXT_OPT_IDX. */ diff --git a/gcc/opts.c b/gcc/opts.c index e304ce5c94be..d5fe326bced1 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -381,22 +381,6 @@ static void complain_wrong_lang (const char *, const struct cl_option *, static void set_debug_level (enum debug_info_type type, int extended, const char *arg); -/* If ARG is a non-negative integer made up solely of digits, return its - value, otherwise return -1. */ -static int -integral_argument (const char *arg) -{ - const char *p = arg; - - while (*p && ISDIGIT (*p)) - p++; - - if (*p == '\0') - return atoi (arg); - - return -1; -} - /* Return a malloced slash-separated list of languages in MASK. */ static char * write_langs (unsigned int mask) @@ -536,131 +520,61 @@ handle_option (int opt_index, int value, const char *arg, static unsigned int read_cmdline_option (const char **argv, unsigned int lang_mask) { - size_t opt_index; - const char *opt, *arg = 0; - char *dup = 0; - int value = 1; - unsigned int result = 0; + struct cl_decoded_option decoded; + unsigned int result; + const char *opt; const struct cl_option *option; opt = argv[0]; - opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET); - if (opt_index == cl_options_count - && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm') - && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-') + result = decode_cmdline_option (argv, lang_mask, &decoded); + if (decoded.opt_index == cl_options_count) { - /* Drop the "no-" from negative switches. */ - size_t len = strlen (opt) - 3; - - dup = XNEWVEC (char, len + 1); - dup[0] = '-'; - dup[1] = opt[1]; - memcpy (dup + 2, opt + 5, len - 2 + 1); - opt = dup; - value = 0; - opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET); - if (opt_index == cl_options_count && opt[1] == 'W') - { - /* We don't generate warnings for unknown -Wno-* options - unless we issue diagnostics. */ + if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-') + /* We don't generate warnings for unknown -Wno-* options + unless we issue diagnostics. */ postpone_unknown_option_warning (argv[0]); - result = 1; - goto done; - } + else + error ("unrecognized command line option %qs", opt); + return result; } - if (opt_index == cl_options_count) - goto done; - - option = &cl_options[opt_index]; - - /* Reject negative form of switches that don't take negatives as - unrecognized. */ - if (!value && (option->flags & CL_REJECT_NEGATIVE)) - goto done; - - /* We've recognized this switch. */ - result = 1; + option = &cl_options[decoded.opt_index]; - /* Check to see if the option is disabled for this configuration. */ - if (option->flags & CL_DISABLED) + if (decoded.errors & CL_ERR_DISABLED) { error ("command line option %qs" " is not supported by this configuration", opt); goto done; } - /* Sort out any argument the switch takes. */ - if (option->flags & CL_JOINED) - { - /* Have arg point to the original switch. This is because - some code, such as disable_builtin_function, expects its - argument to be persistent until the program exits. */ - arg = argv[0] + cl_options[opt_index].opt_len + 1; - if (!value) - arg += strlen ("no-"); - - if (*arg == '\0' && !(option->flags & CL_MISSING_OK)) - { - if (option->flags & CL_SEPARATE) - { - arg = argv[1]; - result = 2; - } - else - /* Missing argument. */ - arg = NULL; - } - } - else if (option->flags & CL_SEPARATE) - { - arg = argv[1]; - result = 2; - } - - /* Now we've swallowed any potential argument, complain if this - is a switch for a different front end. */ - if (!(option->flags & (lang_mask | CL_COMMON | CL_TARGET))) + if (decoded.errors & CL_ERR_WRONG_LANG) { complain_wrong_lang (argv[0], option, lang_mask); goto done; } - else if ((option->flags & CL_TARGET) - && (option->flags & CL_LANG_ALL) - && !(option->flags & lang_mask)) + + if (decoded.errors & CL_ERR_MISSING_ARG) { - /* Complain for target flag language mismatches if any languages - are specified. */ - complain_wrong_lang (argv[0], option, lang_mask); + if (!lang_hooks.missing_argument (opt, decoded.opt_index)) + error ("missing argument to %qs", opt); goto done; } - if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE))) + if (decoded.errors & CL_ERR_UINT_ARG) { - if (!lang_hooks.missing_argument (opt, opt_index)) - error ("missing argument to \"%s\"", opt); + error ("argument to %qs should be a non-negative integer", + option->opt_text); goto done; } - /* If the switch takes an integer, convert it. */ - if (arg && (option->flags & CL_UINTEGER)) - { - value = integral_argument (arg); - if (value == -1) - { - error ("argument to \"%s\" should be a non-negative integer", - option->opt_text); - goto done; - } - } + gcc_assert (!decoded.errors); - if (!handle_option (opt_index, value, arg, lang_mask, DK_UNSPECIFIED)) - result = 0; + if (!handle_option (decoded.opt_index, decoded.value, decoded.arg, + lang_mask, DK_UNSPECIFIED)) + error ("unrecognized command line option %qs", opt); done: - if (dup) - free (dup); return result; } @@ -780,12 +694,6 @@ read_cmdline_options (unsigned int argc, const char **argv, unsigned int lang_ma } n = read_cmdline_option (argv + i, lang_mask); - - if (!n) - { - n = 1; - error ("unrecognized command line option \"%s\"", opt); - } } } diff --git a/gcc/opts.h b/gcc/opts.h index af3c6e2abe63..c50cbca1c1e6 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -1,5 +1,5 @@ /* Command line option handling. - Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008 + Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -90,6 +90,34 @@ extern const unsigned int cl_lang_count; #define CL_UINTEGER (1 << 29) /* Argument is an integer >=0. */ #define CL_UNDOCUMENTED (1 << 30) /* Do not output with --help. */ +/* Possible ways in which a command-line option may be erroneous. + These do not include not being known at all; an option index of + cl_options_count is used for that. */ + +#define CL_ERR_DISABLED (1 << 0) /* Disabled in this configuration. */ +#define CL_ERR_MISSING_ARG (1 << 1) /* Argument required but missing. */ +#define CL_ERR_WRONG_LANG (1 << 2) /* Option for wrong language. */ +#define CL_ERR_UINT_ARG (1 << 3) /* Bad unsigned integer argument. */ + +/* Structure describing the result of decoding an option. */ + +struct cl_decoded_option +{ + /* The index of this option, or cl_options_count if not known. */ + size_t opt_index; + + /* The string argument, or NULL if none. */ + const char *arg; + + /* For a boolean option, 1 for the true case and 0 for the "no-" + case. For an unsigned integer option, the value of the + argument. 1 in all other cases. */ + int value; + + /* Any flags describing errors detected in this option. */ + int errors; +}; + /* Input file names. */ extern const char **in_fnames; @@ -99,6 +127,10 @@ extern const char **in_fnames; extern unsigned num_in_fnames; size_t find_opt (const char *input, int lang_mask); +extern int integral_argument (const char *arg); +extern unsigned int decode_cmdline_option (const char **argv, + unsigned int lang_mask, + struct cl_decoded_option *decoded); extern void prune_options (int *argcp, char ***argvp); extern void decode_options (unsigned int argc, const char **argv); extern int option_enabled (int opt_idx); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 885f215b9213..b6d4be9b5e22 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-06-11 Joseph Myers + + * gcc.dg/funroll-loops-all.c: Update expected error. + 2010-06-11 Uros Bizjak PR target/44481 diff --git a/gcc/testsuite/gcc.dg/funroll-loops-all.c b/gcc/testsuite/gcc.dg/funroll-loops-all.c index c6276759e6c0..9cdc90172557 100644 --- a/gcc/testsuite/gcc.dg/funroll-loops-all.c +++ b/gcc/testsuite/gcc.dg/funroll-loops-all.c @@ -1,4 +1,4 @@ /* PR 17594 */ /* { dg-do compile } */ /* { dg-options "-funroll-loops-all" } */ -/* { dg-error "unrecognized command line option \"-funroll-loops-all\"" "" { target *-*-* } 0 } */ +/* { dg-error "unrecognized command line option '-funroll-loops-all'" "" { target *-*-* } 0 } */