aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJoseph Myers <jsm28@cam.ac.uk>2000-09-18 17:27:16 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2000-09-18 17:27:16 +0100
commit99303ae4ccc37e6c90d94c0adace40e7e36d5b75 (patch)
tree2979203819616393d8ac201db842b482368091eb /gcc
parent9231abf2edf23048f7f8e2e5028cc60f378e8de6 (diff)
downloadgcc-99303ae4ccc37e6c90d94c0adace40e7e36d5b75.zip
gcc-99303ae4ccc37e6c90d94c0adace40e7e36d5b75.tar.gz
gcc-99303ae4ccc37e6c90d94c0adace40e7e36d5b75.tar.bz2
c-common.c (check_format_types): Reorganise and clean up...
* c-common.c (check_format_types): Reorganise and clean up, checking earlier for ERROR_MARKs and making cur_type into its TYPE_MAIN_VARIANT where convenient. From-SVN: r36490
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/c-common.c189
2 files changed, 106 insertions, 89 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8656764..7de3edd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2000-09-18 Joseph S. Myers <jsm28@cam.ac.uk>
+ * c-common.c (check_format_types): Reorganise and clean up,
+ checking earlier for ERROR_MARKs and making cur_type into its
+ TYPE_MAIN_VARIANT where convenient.
+
+2000-09-18 Joseph S. Myers <jsm28@cam.ac.uk>
+
* gcc.c (cpp_options): Add specs for __STDC_HOSTED__.
2000-09-18 Bernd Schmidt <bernds@redhat.co.uk>
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 54335dd..292d946 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -2514,16 +2514,25 @@ check_format_types (types)
{
tree cur_param;
tree cur_type;
+ tree orig_cur_type;
tree wanted_type;
int arg_num;
int i;
int char_type_flag;
cur_param = types->param;
cur_type = TREE_TYPE (cur_param);
+ if (TREE_CODE (cur_type) == ERROR_MARK)
+ continue;
char_type_flag = 0;
wanted_type = types->wanted_type;
arg_num = types->arg_num;
+ /* The following should not occur here. */
+ if (wanted_type == 0)
+ abort ();
+ if (wanted_type == void_type_node && types->pointer_count == 0)
+ abort ();
+
STRIP_NOPS (cur_param);
/* Check the types of any additional pointer arguments
@@ -2533,6 +2542,8 @@ check_format_types (types)
if (TREE_CODE (cur_type) == POINTER_TYPE)
{
cur_type = TREE_TYPE (cur_type);
+ if (TREE_CODE (cur_type) == ERROR_MARK)
+ break;
if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
cur_param = TREE_OPERAND (cur_param, 0);
@@ -2546,7 +2557,6 @@ check_format_types (types)
const void ** is simply passing an incompatible type. */
if (types->writing_in_flag
&& i == 0
- && TREE_CODE (cur_type) != ERROR_MARK
&& (TYPE_READONLY (cur_type)
|| (cur_param != 0
&& (TREE_CODE_CLASS (TREE_CODE (cur_param)) == 'c'
@@ -2559,117 +2569,118 @@ check_format_types (types)
incompatible. */
if (i > 0
&& pedantic
- && TREE_CODE (cur_type) != ERROR_MARK
&& (TYPE_READONLY (cur_type)
|| TYPE_VOLATILE (cur_type)
|| TYPE_RESTRICT (cur_type)))
warning ("extra type qualifiers in format argument (arg %d)",
arg_num);
- continue;
}
- if (TREE_CODE (cur_type) != ERROR_MARK)
+ else
{
if (types->pointer_count == 1)
warning ("format argument is not a pointer (arg %d)", arg_num);
else
warning ("format argument is not a pointer to a pointer (arg %d)", arg_num);
+ break;
}
- break;
}
+ if (i < types->pointer_count)
+ continue;
+
+ orig_cur_type = cur_type;
+ cur_type = TYPE_MAIN_VARIANT (cur_type);
+
/* Check whether the argument type is a character type. This leniency
only applies to certain formats, flagged with 'c'.
*/
- if (TREE_CODE (cur_type) != ERROR_MARK && types->char_lenient_flag)
- char_type_flag = (TYPE_MAIN_VARIANT (cur_type) == char_type_node
- || TYPE_MAIN_VARIANT (cur_type) == signed_char_type_node
- || TYPE_MAIN_VARIANT (cur_type) == unsigned_char_type_node);
+ if (types->char_lenient_flag)
+ char_type_flag = (cur_type == char_type_node
+ || cur_type == signed_char_type_node
+ || cur_type == unsigned_char_type_node);
/* Check the type of the "real" argument, if there's a type we want. */
- if (i == types->pointer_count && wanted_type != 0
- && TREE_CODE (cur_type) != ERROR_MARK
- && wanted_type != TYPE_MAIN_VARIANT (cur_type)
- /* If we want `void *', allow any pointer type.
- (Anything else would already have got a warning.)
- With -pedantic, only allow pointers to void and to character
- types.
- */
- && ! (wanted_type == void_type_node
- && types->pointer_count > 0
- && (! pedantic
- || TYPE_MAIN_VARIANT (cur_type) == void_type_node
- || (i == 1 && char_type_flag)))
- /* Don't warn about differences merely in signedness, unless
- -pedantic. With -pedantic, warn if the type is a pointer
- target and not a character type, and for character types at
- a second level of indirection.
- */
- && !(TREE_CODE (wanted_type) == INTEGER_TYPE
- && TREE_CODE (TYPE_MAIN_VARIANT (cur_type)) == INTEGER_TYPE
- && (! pedantic || i == 0 || (i == 1 && char_type_flag))
- && (TREE_UNSIGNED (wanted_type)
- ? wanted_type == (cur_type = unsigned_type (cur_type))
- : wanted_type == (cur_type = signed_type (cur_type))))
- /* Likewise, "signed char", "unsigned char" and "char" are
- equivalent but the above test won't consider them equivalent. */
- && ! (wanted_type == char_type_node
- && (! pedantic || i < 2)
- && char_type_flag))
- {
- register const char *this;
- register const char *that;
-
- this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type)));
- that = 0;
- if (TREE_CODE (cur_type) != ERROR_MARK
- && TYPE_NAME (cur_type) != 0
- && TREE_CODE (cur_type) != INTEGER_TYPE
- && !(TREE_CODE (cur_type) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (cur_type)) == INTEGER_TYPE))
- {
- if (TREE_CODE (TYPE_NAME (cur_type)) == TYPE_DECL
- && DECL_NAME (TYPE_NAME (cur_type)) != 0)
- that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (cur_type)));
- else
- that = IDENTIFIER_POINTER (TYPE_NAME (cur_type));
- }
+ if (wanted_type == cur_type)
+ continue;
+ /* If we want `void *', allow any pointer type.
+ (Anything else would already have got a warning.)
+ With -pedantic, only allow pointers to void and to character
+ types. */
+ if (wanted_type == void_type_node
+ && (!pedantic || (i == 1 && char_type_flag)))
+ continue;
+ /* Don't warn about differences merely in signedness, unless
+ -pedantic. With -pedantic, warn if the type is a pointer
+ target and not a character type, and for character types at
+ a second level of indirection. */
+ if (TREE_CODE (wanted_type) == INTEGER_TYPE
+ && TREE_CODE (cur_type) == INTEGER_TYPE
+ && (! pedantic || i == 0 || (i == 1 && char_type_flag))
+ && (TREE_UNSIGNED (wanted_type)
+ ? wanted_type == unsigned_type (cur_type)
+ : wanted_type == signed_type (cur_type)))
+ continue;
+ /* Likewise, "signed char", "unsigned char" and "char" are
+ equivalent but the above test won't consider them equivalent. */
+ if (wanted_type == char_type_node
+ && (! pedantic || i < 2)
+ && char_type_flag)
+ continue;
+ /* Now we have a type mismatch. */
+ {
+ register const char *this;
+ register const char *that;
+
+ this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type)));
+ that = 0;
+ if (TYPE_NAME (orig_cur_type) != 0
+ && TREE_CODE (orig_cur_type) != INTEGER_TYPE
+ && !(TREE_CODE (orig_cur_type) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (orig_cur_type)) == INTEGER_TYPE))
+ {
+ if (TREE_CODE (TYPE_NAME (orig_cur_type)) == TYPE_DECL
+ && DECL_NAME (TYPE_NAME (orig_cur_type)) != 0)
+ that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (orig_cur_type)));
+ else
+ that = IDENTIFIER_POINTER (TYPE_NAME (orig_cur_type));
+ }
- /* A nameless type can't possibly match what the format wants.
- So there will be a warning for it.
- Make up a string to describe vaguely what it is. */
- if (that == 0)
- {
- if (TREE_CODE (cur_type) == POINTER_TYPE)
- that = "pointer";
- else
- that = "different type";
- }
+ /* A nameless type can't possibly match what the format wants.
+ So there will be a warning for it.
+ Make up a string to describe vaguely what it is. */
+ if (that == 0)
+ {
+ if (TREE_CODE (orig_cur_type) == POINTER_TYPE)
+ that = "pointer";
+ else
+ that = "different type";
+ }
- /* Make the warning better in case of mismatch of int vs long. */
- if (TREE_CODE (cur_type) == INTEGER_TYPE
- && TREE_CODE (wanted_type) == INTEGER_TYPE
- && TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type)
- && TYPE_NAME (cur_type) != 0
- && TREE_CODE (TYPE_NAME (cur_type)) == TYPE_DECL)
- that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (cur_type)));
+ /* Make the warning better in case of mismatch of int vs long. */
+ if (TREE_CODE (orig_cur_type) == INTEGER_TYPE
+ && TREE_CODE (wanted_type) == INTEGER_TYPE
+ && TYPE_PRECISION (orig_cur_type) == TYPE_PRECISION (wanted_type)
+ && TYPE_NAME (orig_cur_type) != 0
+ && TREE_CODE (TYPE_NAME (orig_cur_type)) == TYPE_DECL)
+ that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (orig_cur_type)));
- if (strcmp (this, that) != 0)
- {
- /* There may be a better name for the format, e.g. size_t,
- but we should allow for programs with a perverse typedef
- making size_t something other than what the compiler
- thinks. */
- if (types->wanted_type_name != 0
- && strcmp (types->wanted_type_name, that) != 0)
- this = types->wanted_type_name;
- if (types->name != 0)
- warning ("%s is not type %s (arg %d)", types->name, this,
- arg_num);
- else
- warning ("%s format, %s arg (arg %d)", this, that, arg_num);
- }
- }
+ if (strcmp (this, that) != 0)
+ {
+ /* There may be a better name for the format, e.g. size_t,
+ but we should allow for programs with a perverse typedef
+ making size_t something other than what the compiler
+ thinks. */
+ if (types->wanted_type_name != 0
+ && strcmp (types->wanted_type_name, that) != 0)
+ this = types->wanted_type_name;
+ if (types->name != 0)
+ warning ("%s is not type %s (arg %d)", types->name, this,
+ arg_num);
+ else
+ warning ("%s format, %s arg (arg %d)", this, that, arg_num);
+ }
+ }
}
}