This is the mail archive of the
gdb-prs@sourceware.org
mailing list for the GDB project.
[Bug macros/9777] Variable may be used uninitialized in maybe_expand()
- From: "pedro at codesourcery dot com" <sourceware-bugzilla at sourceware dot org>
- To: gdb-prs at sourceware dot org
- Date: 28 Jan 2009 19:56:40 -0000
- Subject: [Bug macros/9777] Variable may be used uninitialized in maybe_expand()
- References: <20090123022739.9777.d.g.gorbachev@gmail.com>
- Reply-to: sourceware-bugzilla at sourceware dot org
------- Additional Comments From pedro at codesourcery dot com 2009-01-28 19:56 -------
Subject: Re: Variable may be used uninitialized in maybe_expand()
On Wednesday 28 January 2009 19:48:01, tromey at redhat dot com wrote:
>
> ------- Additional Comments From tromey at redhat dot com 2009-01-28 19:48 -------
> Confirmed.
> I see other -O3 build failures as well, with --enable-targets=all.
> A workaround is to use -O2, not -O3.
I this over the weekend, but forgot to mention it. It fixes the
reported issue, plus all the others I could find with a regular native linux
build. I had to import gcc's CONST_CAST to fix a few. I didn't
try --enable-targets=all though.
(this particular issue was solved by removing the `is_varargs' argument,
and using va_arg_name == NULL or != NULL to mean the same thing).
WDYT?
---
gdb/defs.h | 26 ++++++++++++++++++++++++++
gdb/elfread.c | 4 ++--
gdb/macroexp.c | 54 +++++++++++++++++++++++++-----------------------------
gdb/macrotab.c | 15 ++++++++-------
4 files changed, 61 insertions(+), 38 deletions(-)
Index: src/gdb/defs.h
===================================================================
--- src.orig/gdb/defs.h 2009-01-23 14:13:08.000000000 +0000
+++ src/gdb/defs.h 2009-01-23 14:16:11.000000000 +0000
@@ -139,6 +139,32 @@ typedef bfd_vma CORE_ADDR;
#define max(a, b) ((a) > (b) ? (a) : (b))
#endif
+/* This macro allows casting away const-ness to pass -Wcast-qual
+ warnings. DO NOT USE THIS UNLESS YOU REALLY HAVE TO! It should
+ only be used in certain specific cases. One valid case is where
+ the C standard definitions or prototypes force you to. E.g. if you
+ need to free a const object, or if you pass a const string to
+ execv, et al. Another valid use would be in an allocation function
+ that creates const objects that need to be initialized. In some
+ cases we have non-const functions that return the argument. Rather
+ than create const shadow functions, we can cast away const-ness in
+ calling these interfaces if we're careful to verify that the called
+ function does indeed not modify its argument and the return value
+ is only used in a const context. (This can be somewhat dangerous
+ as these assumptions can change after the fact). Beyond these
+ uses, most other cases of using this macro should be viewed with
+ extreme caution. */
+
+#if defined(__GNUC__) && GCC_VERSION > 4000
+/* GCC 4.0.x has a bug where it may ICE on this expression,
+ so does GCC 3.4.x (PR17436). */
+#define CONST_CAST2(TOTYPE,FROMTYPE,X) \
+ ((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq)
+#else
+#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((TOTYPE)(FROMTYPE)(X))
+#endif
+#define CONST_CAST(TYPE,X) CONST_CAST2(TYPE, const TYPE, (X))
+
/* Check if a character is one of the commonly used C++ marker characters. */
extern int is_cplus_marker (int);
Index: src/gdb/elfread.c
===================================================================
--- src.orig/gdb/elfread.c 2009-01-23 14:13:08.000000000 +0000
+++ src/gdb/elfread.c 2009-01-23 14:16:11.000000000 +0000
@@ -162,7 +162,7 @@ elf_locate_sections (bfd *ignore_abfd, a
}
static struct minimal_symbol *
-record_minimal_symbol (char *name, CORE_ADDR address,
+record_minimal_symbol (const char *name, CORE_ADDR address,
enum minimal_symbol_type ms_type,
asection *bfd_section, struct objfile *objfile)
{
@@ -287,7 +287,7 @@ elf_symtab_read (struct objfile *objfile
symaddr += ANOFFSET (objfile->section_offsets, sect->index);
msym = record_minimal_symbol
- ((char *) sym->name, symaddr, mst_solib_trampoline, sect, objfile);
+ (sym->name, symaddr, mst_solib_trampoline, sect, objfile);
if (msym != NULL)
msym->filename = filesymname;
continue;
Index: src/gdb/macroexp.c
===================================================================
--- src.orig/gdb/macroexp.c 2009-01-23 14:13:08.000000000 +0000
+++ src/gdb/macroexp.c 2009-01-23 14:16:11.000000000 +0000
@@ -93,9 +93,9 @@ init_buffer (struct macro_buffer *b, int
/* Set the macro buffer *BUF to refer to the LEN bytes at ADDR, as a
shared substring. */
static void
-init_shared_buffer (struct macro_buffer *buf, char *addr, int len)
+init_shared_buffer (struct macro_buffer *buf, const char *addr, int len)
{
- buf->text = addr;
+ buf->text = CONST_CAST (char *, addr);
buf->len = len;
buf->shared = 1;
buf->size = 0;
@@ -875,17 +875,16 @@ static void scan (struct macro_buffer *d
/* A helper function for substitute_args.
ARGV is a vector of all the arguments; ARGC is the number of
- arguments. IS_VARARGS is true if the macro being substituted is a
- varargs macro; in this case VA_ARG_NAME is the name of the
- "variable" argument. VA_ARG_NAME is ignored if IS_VARARGS is
- false.
+ arguments. VA_ARG_NAME is non-NULL if the macro being substituted
+ is a varargs macro; in this case VA_ARG_NAME is the name of the
+ "variable" argument. VA_ARG_NAME is ignored if IS_VARARGS is NULL.
If the token TOK is the name of a parameter, return the parameter's
index. If TOK is not an argument, return -1. */
static int
find_parameter (const struct macro_buffer *tok,
- int is_varargs, const struct macro_buffer *va_arg_name,
+ const struct macro_buffer *va_arg_name,
int argc, const char * const *argv)
{
int i;
@@ -897,7 +896,7 @@ find_parameter (const struct macro_buffe
if (tok->len == strlen (argv[i]) && ! memcmp (tok->text, argv[i], tok->len))
return i;
- if (is_varargs && tok->len == va_arg_name->len
+ if (va_arg_name != NULL && tok->len == va_arg_name->len
&& ! memcmp (tok->text, va_arg_name->text, tok->len))
return argc - 1;
@@ -908,11 +907,10 @@ find_parameter (const struct macro_buffe
arguments given by ARGC and ARGV, substitute the arguments into the
replacement list, and store the result in DEST.
- IS_VARARGS should be true if DEF is a varargs macro. In this case,
- VA_ARG_NAME should be the name of the "variable" argument -- either
- __VA_ARGS__ for c99-style varargs, or the final argument name, for
- GNU-style varargs. If IS_VARARGS is false, this parameter is
- ignored.
+ VA_ARG_NAME should be non-null if DEF is a varargs macro. In this
+ case, VA_ARG_NAME should be the name of the "variable" argument --
+ either __VA_ARGS__ for c99-style varargs, or the final argument
+ name, for GNU-style varargs.
If it is necessary to expand macro invocations in one of the
arguments, use LOOKUP_FUNC and LOOKUP_BATON to find the macro
@@ -922,7 +920,7 @@ find_parameter (const struct macro_buffe
static void
substitute_args (struct macro_buffer *dest,
struct macro_definition *def,
- int is_varargs, const struct macro_buffer *va_arg_name,
+ const struct macro_buffer *va_arg_name,
int argc, struct macro_buffer *argv,
struct macro_name_list *no_loop,
macro_lookup_ftype *lookup_func,
@@ -942,7 +940,7 @@ substitute_args (struct macro_buffer *de
lexed. */
char *lookahead_rl_start;
- init_shared_buffer (&replacement_list, (char *) def->replacement,
+ init_shared_buffer (&replacement_list, def->replacement,
strlen (def->replacement));
gdb_assert (dest->len == 0);
@@ -973,8 +971,7 @@ substitute_args (struct macro_buffer *de
if (!lookahead_valid)
error (_("Stringification operator requires an argument."));
- arg = find_parameter (&lookahead, is_varargs, va_arg_name,
- def->argc, def->argv);
+ arg = find_parameter (&lookahead, va_arg_name, def->argc, def->argv);
if (arg == -1)
error (_("Argument to stringification operator must name "
"a macro parameter."));
@@ -1009,7 +1006,7 @@ substitute_args (struct macro_buffer *de
prev_was_comma = 1;
else
{
- int arg = find_parameter (&tok, is_varargs, va_arg_name,
+ int arg = find_parameter (&tok, va_arg_name,
def->argc, def->argv);
if (arg != -1)
appendmem (dest, argv[arg].text, argv[arg].len);
@@ -1034,7 +1031,7 @@ substitute_args (struct macro_buffer *de
simply insert the comma. */
if (prev_was_comma)
{
- if (! (is_varargs
+ if (! (va_arg_name != NULL
&& tok.len == va_arg_name->len
&& !memcmp (tok.text, va_arg_name->text, tok.len)
&& argv[argc - 1].len == 0))
@@ -1048,7 +1045,7 @@ substitute_args (struct macro_buffer *de
prev_was_comma = 1;
else
{
- int arg = find_parameter (&tok, is_varargs, va_arg_name,
+ int arg = find_parameter (&tok, va_arg_name,
def->argc, def->argv);
if (arg != -1)
appendmem (dest, argv[arg].text, argv[arg].len);
@@ -1092,8 +1089,7 @@ substitute_args (struct macro_buffer *de
{
/* Is this token an identifier? */
int substituted = 0;
- int arg = find_parameter (&tok, is_varargs, va_arg_name,
- def->argc, def->argv);
+ int arg = find_parameter (&tok, va_arg_name, def->argc, def->argv);
if (arg != -1)
{
@@ -1172,7 +1168,7 @@ expand (const char *id,
struct macro_buffer *argv = NULL;
struct macro_buffer substituted;
struct macro_buffer substituted_src;
- struct macro_buffer va_arg_name;
+ struct macro_buffer *va_arg_name = NULL;
int is_varargs = 0;
if (def->argc >= 1)
@@ -1181,9 +1177,9 @@ expand (const char *id,
{
/* In C99-style varargs, substitution is done using
__VA_ARGS__. */
- init_shared_buffer (&va_arg_name, "__VA_ARGS__",
+ va_arg_name = alloca (sizeof (struct macro_buffer));
+ init_shared_buffer (va_arg_name, "__VA_ARGS__",
strlen ("__VA_ARGS__"));
- is_varargs = 1;
}
else
{
@@ -1194,10 +1190,10 @@ expand (const char *id,
/* In GNU-style varargs, the name of the
substitution parameter is the name of the formal
argument without the "...". */
- init_shared_buffer (&va_arg_name,
+ va_arg_name = alloca (sizeof (struct macro_buffer));
+ init_shared_buffer (va_arg_name,
(char *) def->argv[def->argc - 1],
len - 3);
- is_varargs = 1;
}
}
}
@@ -1218,7 +1214,7 @@ expand (const char *id,
this macro. */
if (argc != def->argc)
{
- if (is_varargs && argc >= def->argc - 1)
+ if (va_arg_name != NULL && argc >= def->argc - 1)
{
/* Ok. */
}
@@ -1241,7 +1237,7 @@ expand (const char *id,
expand an argument until we see how it's being used. */
init_buffer (&substituted, 0);
make_cleanup (cleanup_macro_buffer, &substituted);
- substitute_args (&substituted, def, is_varargs, &va_arg_name,
+ substitute_args (&substituted, def, va_arg_name,
argc, argv, no_loop, lookup_func, lookup_baton);
/* Now `substituted' is the macro's replacement list, with all
Index: src/gdb/macrotab.c
===================================================================
--- src.orig/gdb/macrotab.c 2009-01-23 14:13:08.000000000 +0000
+++ src/gdb/macrotab.c 2009-01-23 14:16:11.000000000 +0000
@@ -364,7 +364,7 @@ macro_tree_delete_key (void *untyped_key
{
struct macro_key *key = (struct macro_key *) untyped_key;
- macro_bcache_free (key->table, (char *) key->name);
+ macro_bcache_free (key->table, CONST_CAST (char *, key->name));
macro_free (key, key->table);
}
@@ -389,7 +389,6 @@ new_source_file (struct macro_table *t,
return f;
}
-
/* Free a source file, and all the source files it #included. */
static void
free_macro_source_file (struct macro_source_file *src)
@@ -403,7 +402,7 @@ free_macro_source_file (struct macro_sou
free_macro_source_file (child);
}
- macro_bcache_free (src->table, (char *) src->filename);
+ macro_bcache_free (src->table, CONST_CAST (char *, src->filename));
macro_free (src, src->table);
}
@@ -611,11 +610,13 @@ macro_tree_delete_value (void *untyped_d
int i;
for (i = 0; i < d->argc; i++)
- macro_bcache_free (t, (char *) d->argv[i]);
- macro_bcache_free (t, (char **) d->argv);
+ macro_bcache_free (t, CONST_CAST (char *, d->argv[i]));
+ macro_bcache_free (t, CONST_CAST2 (char **,
+ const char * const *,
+ d->argv));
}
-
- macro_bcache_free (t, (char *) d->replacement);
+
+ macro_bcache_free (t, CONST_CAST (char *, d->replacement));
macro_free (d, t);
}
------- Additional Comments From pedro at codesourcery dot com 2009-01-28 19:56 -------
Created an attachment (id=3695)
--> (http://sourceware.org/bugzilla/attachment.cgi?id=3695&action=view)
--
http://sourceware.org/bugzilla/show_bug.cgi?id=9777
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.