Restore ancient -Waddress for weak symbols [PR33925].
Resolves: PR c/33925 - gcc -Waddress lost some useful warnings PR c/102867 - -Waddress from macro expansion in readelf.c gcc/c-family/ChangeLog: PR c++/33925 PR c/102867 * c-common.c (decl_with_nonnull_addr_p): Call maybe_nonzero_address and improve handling tof defined symbols. gcc/c/ChangeLog: PR c++/33925 PR c/102867 * c-typeck.c (maybe_warn_for_null_address): Suppress warnings for code resulting from macro expansion. gcc/cp/ChangeLog: PR c++/33925 PR c/102867 * typeck.c (warn_for_null_address): Suppress warnings for code resulting from macro expansion. gcc/ChangeLog: PR c++/33925 PR c/102867 * doc/invoke.texi (-Waddress): Update. gcc/testsuite/ChangeLog: PR c++/33925 PR c/102867 * g++.dg/warn/Walways-true-2.C: Adjust to avoid a valid warning. * c-c++-common/Waddress-5.c: New test. * c-c++-common/Waddress-6.c: New test. * g++.dg/warn/Waddress-7.C: New test. * gcc.dg/Walways-true-2.c: Adjust to avoid a valid warning. * gcc.dg/weak/weak-3.c: Expect a warning.
This commit is contained in:
parent
ee448a523d
commit
16137fbb92
10 changed files with 288 additions and 11 deletions
|
@ -3413,16 +3413,43 @@ c_wrap_maybe_const (tree expr, bool non_const)
|
|||
|
||||
/* Return whether EXPR is a declaration whose address can never be NULL.
|
||||
The address of the first struct member could be NULL only if it were
|
||||
accessed through a NULL pointer, and such an access would be invalid. */
|
||||
accessed through a NULL pointer, and such an access would be invalid.
|
||||
The address of a weak symbol may be null unless it has a definition. */
|
||||
|
||||
bool
|
||||
decl_with_nonnull_addr_p (const_tree expr)
|
||||
{
|
||||
return (DECL_P (expr)
|
||||
&& (TREE_CODE (expr) == FIELD_DECL
|
||||
|| TREE_CODE (expr) == PARM_DECL
|
||||
|| TREE_CODE (expr) == LABEL_DECL
|
||||
|| !DECL_WEAK (expr)));
|
||||
if (!DECL_P (expr))
|
||||
return false;
|
||||
|
||||
if (TREE_CODE (expr) == FIELD_DECL
|
||||
|| TREE_CODE (expr) == PARM_DECL
|
||||
|| TREE_CODE (expr) == LABEL_DECL)
|
||||
return true;
|
||||
|
||||
if (!VAR_OR_FUNCTION_DECL_P (expr))
|
||||
return false;
|
||||
|
||||
if (!DECL_WEAK (expr))
|
||||
/* Ordinary (non-weak) symbols have nonnull addresses. */
|
||||
return true;
|
||||
|
||||
if (DECL_INITIAL (expr) && DECL_INITIAL (expr) != error_mark_node)
|
||||
/* Initialized weak symbols have nonnull addresses. */
|
||||
return true;
|
||||
|
||||
if (DECL_EXTERNAL (expr) || !TREE_STATIC (expr))
|
||||
/* Uninitialized extern weak symbols and weak symbols with no
|
||||
allocated storage might have a null address. */
|
||||
return false;
|
||||
|
||||
tree attribs = DECL_ATTRIBUTES (expr);
|
||||
if (lookup_attribute ("weakref", attribs))
|
||||
/* Weakref symbols might have a null address unless their referent
|
||||
is known not to. Don't bother following weakref targets here. */
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
|
||||
|
|
|
@ -11588,7 +11588,10 @@ build_vec_cmp (tree_code code, tree type,
|
|||
static void
|
||||
maybe_warn_for_null_address (location_t loc, tree op, tree_code code)
|
||||
{
|
||||
if (!warn_address || warning_suppressed_p (op, OPT_Waddress))
|
||||
/* Prevent warnings issued for macro expansion. */
|
||||
if (!warn_address
|
||||
|| warning_suppressed_p (op, OPT_Waddress)
|
||||
|| from_macro_expansion_at (loc))
|
||||
return;
|
||||
|
||||
if (TREE_CODE (op) == NOP_EXPR)
|
||||
|
|
|
@ -4594,9 +4594,11 @@ build_vec_cmp (tree_code code, tree type,
|
|||
static void
|
||||
warn_for_null_address (location_t location, tree op, tsubst_flags_t complain)
|
||||
{
|
||||
/* Prevent warnings issued for macro expansion. */
|
||||
if (!warn_address
|
||||
|| (complain & tf_warning) == 0
|
||||
|| c_inhibit_evaluation_warnings != 0
|
||||
|| from_macro_expansion_at (location)
|
||||
|| warning_suppressed_p (op, OPT_Waddress))
|
||||
return;
|
||||
|
||||
|
|
|
@ -8689,6 +8689,8 @@ suppressed by casting the pointer operand to an integer type such
|
|||
as @code{inptr_t} or @code{uinptr_t}.
|
||||
Comparisons against string literals result in unspecified behavior
|
||||
and are not portable, and suggest the intent was to call @code{strcmp}.
|
||||
The warning is suppressed if the suspicious expression is the result
|
||||
of macro expansion.
|
||||
@option{-Waddress} warning is enabled by @option{-Wall}.
|
||||
|
||||
@item -Wno-address-of-packed-member
|
||||
|
|
133
gcc/testsuite/c-c++-common/Waddress-5.c
Normal file
133
gcc/testsuite/c-c++-common/Waddress-5.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* PR c/33925 - missing -Waddress with the address of an inline function
|
||||
{ dg-do compile }
|
||||
{ dg-options "-Wall" }
|
||||
{ dg-require-weak "" } */
|
||||
|
||||
extern inline int eifn (void);
|
||||
extern inline int eifn_def (void) { return 0; }
|
||||
|
||||
static inline int sifn (void);
|
||||
static inline int sifn_def (void) { return 0; }
|
||||
|
||||
inline int ifn (void);
|
||||
inline int ifn_def (void) { return 0; }
|
||||
|
||||
extern __attribute__ ((weak)) int ewfn (void);
|
||||
extern __attribute__ ((weak)) int ewfn_def (void) { return 0; }
|
||||
|
||||
__attribute__ ((weak)) int wfn (void);
|
||||
__attribute__ ((weak)) int wfn_def (void) { return 0; }
|
||||
|
||||
static __attribute__((weakref ("ewfn"))) int swrfn (void);
|
||||
|
||||
void test_function_eqz (int *p)
|
||||
{
|
||||
*p++ = eifn == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = eifn_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = sifn == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = sifn_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = ifn == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = ifn_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = ewfn == 0;
|
||||
*p++ = ewfn_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = wfn == 0;
|
||||
*p++ = wfn_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = swrfn == 0;
|
||||
}
|
||||
|
||||
|
||||
int test_function_if (int i)
|
||||
{
|
||||
if (eifn) // { dg-warning "-Waddress" }
|
||||
i++;
|
||||
if (eifn_def) // { dg-warning "-Waddress" }
|
||||
i++;
|
||||
if (sifn) // { dg-warning "-Waddress" }
|
||||
i++;
|
||||
if (sifn_def) // { dg-warning "-Waddress" }
|
||||
i++;
|
||||
if (ifn) // { dg-warning "-Waddress" }
|
||||
i++;
|
||||
if (ifn_def) // { dg-warning "-Waddress" }
|
||||
i++;
|
||||
if (ewfn)
|
||||
i++;
|
||||
if (ewfn_def) // { dg-warning "-Waddress" }
|
||||
i++;
|
||||
if (wfn)
|
||||
i++;
|
||||
if(wfn_def) // { dg-warning "-Waddress" }
|
||||
i++;
|
||||
if (swrfn)
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
extern int ei;
|
||||
extern int ei_def = 1;
|
||||
|
||||
static int si;
|
||||
static int si_def = 1;
|
||||
|
||||
int i;
|
||||
int i_def = 1;
|
||||
|
||||
extern __attribute__ ((weak)) int ewi; // declaration (may be null)
|
||||
extern __attribute__ ((weak)) int ewi_def = 1;
|
||||
|
||||
__attribute__ ((weak)) int wi; // definition (cannot be bull)
|
||||
__attribute__ ((weak)) int wi_def = 1;
|
||||
|
||||
static __attribute__((weakref ("ewi"))) int swri;
|
||||
|
||||
void test_scalar (int *p)
|
||||
{
|
||||
*p++ = &ei == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = &ei_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = &si == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = &si_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = &i == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = &i_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = &ewi == 0;
|
||||
*p++ = &ewi_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = &wi == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = &wi_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = &swri == 0;
|
||||
}
|
||||
|
||||
|
||||
extern int eia[];
|
||||
extern int eia_def[] = { 1 };
|
||||
|
||||
static int sia[1];
|
||||
static int sia_def[1] = { 1 };
|
||||
|
||||
int ia[1];
|
||||
int ia_def[] = { 1 };
|
||||
|
||||
extern __attribute__ ((weak)) int ewia[];
|
||||
extern __attribute__ ((weak)) int ewia_def[] = { 1 };
|
||||
|
||||
__attribute__ ((weak)) int wia[1]; // definition (cannot be null)
|
||||
__attribute__ ((weak)) int wia_def[] = { 1 };
|
||||
|
||||
static __attribute__((weakref ("ewia"))) int swria[1];
|
||||
|
||||
void test_array (int *p)
|
||||
{
|
||||
*p++ = eia == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = eia_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = sia == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = sia_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = ia == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = ia_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = ewia == 0;
|
||||
*p++ = ewia_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = wia == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = wia_def == 0; // { dg-warning "-Waddress" }
|
||||
*p++ = swria == 0;
|
||||
}
|
||||
|
||||
/* { dg-prune-output "never defined" }
|
||||
{ dg-prune-output "initialized and declared 'extern'" } */
|
32
gcc/testsuite/c-c++-common/Waddress-6.c
Normal file
32
gcc/testsuite/c-c++-common/Waddress-6.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* PR c/102867 - -Waddress from macro expansion in readelf.c
|
||||
{ dg-do compile }
|
||||
{ dg-options "-Wall" } */
|
||||
|
||||
#define F(x) ((&x) != 0)
|
||||
|
||||
int warn_nomacro (int *p, int i)
|
||||
{
|
||||
return &p[i] != 0; // { dg-warning "-Waddress" }
|
||||
}
|
||||
|
||||
int nowarn_macro_expansion (int *p, int i)
|
||||
{
|
||||
// Verify that -Waddress isn't issued for code from macro expansion.
|
||||
return F (p[i]); // { dg-bogus "-Waddress" }
|
||||
}
|
||||
|
||||
#define G(x, i) ((&x) + i)
|
||||
|
||||
int warn_function_macro_expansion (int *p, int i)
|
||||
{
|
||||
/* Verify that -Waddress is issued for code involving macro expansion
|
||||
where the comparison takes place outside the macro. */
|
||||
return G (*p, i) != 0; // { dg-warning "-Waddress" }
|
||||
}
|
||||
|
||||
#define malloc __builtin_malloc
|
||||
|
||||
int warn_object_macro_expansion (int *p, int i)
|
||||
{
|
||||
return malloc != 0; // { dg-warning "-Waddress" }
|
||||
}
|
76
gcc/testsuite/g++.dg/warn/Waddress-7.C
Normal file
76
gcc/testsuite/g++.dg/warn/Waddress-7.C
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* PR c/33925 - missing -Waddress with the address of an inline function
|
||||
{ dg-do compile }
|
||||
{ dg-options "-Wall" } */
|
||||
|
||||
struct A
|
||||
{
|
||||
int mf ();
|
||||
int mf_def () { return 0; }
|
||||
|
||||
static int smf ();
|
||||
static int smf_def () { return 0; }
|
||||
|
||||
int mi;
|
||||
static int smi;
|
||||
static int smi_def;
|
||||
|
||||
__attribute__ ((weak)) static int wsmi;
|
||||
__attribute__ ((weak)) static int wsmi_def;
|
||||
|
||||
int mia[];
|
||||
static int smia[];
|
||||
static int smia_def[];
|
||||
|
||||
__attribute__ ((weak)) static int wsmia[];
|
||||
__attribute__ ((weak)) static int wsmia_def[];
|
||||
|
||||
void test_waddress (bool*);
|
||||
};
|
||||
|
||||
|
||||
/* __attribute__ ((weak)) static */ int A::smi_def = 0;
|
||||
/* __attribute__ ((weak)) static */ int A::smia_def[] = { 0 };
|
||||
|
||||
/* __attribute__ ((weak)) static */ int A::wsmi_def = 0;
|
||||
/* __attribute__ ((weak)) static */ int A::wsmia_def[] = { 0 };
|
||||
|
||||
|
||||
|
||||
void A::test_waddress (bool *p)
|
||||
{
|
||||
if (mf) // { dg-error "cannot convert" }
|
||||
p++;
|
||||
if (mf_def) // { dg-error "cannot convert" }
|
||||
p++;
|
||||
|
||||
if (smf) // { dg-warning "-Waddress" }
|
||||
p++;
|
||||
if (smf_def) // { dg-warning "-Waddress" }
|
||||
p++;
|
||||
|
||||
if (&mi) // { dg-warning "-Waddress" }
|
||||
p++;
|
||||
if (&smi) // { dg-warning "-Waddress" }
|
||||
p++;
|
||||
if (&smi_def) // { dg-warning "-Waddress" }
|
||||
p++;
|
||||
|
||||
if (&wsmi)
|
||||
p++;
|
||||
|
||||
if (&wsmi_def) // { dg-warning "-Waddress" }
|
||||
p++;
|
||||
|
||||
if (mia) // { dg-warning "-Waddress" }
|
||||
p++;
|
||||
if (smia) // { dg-warning "-Waddress" }
|
||||
p++;
|
||||
if (smia_def) // { dg-warning "-Waddress" }
|
||||
p++;
|
||||
|
||||
if (wsmia)
|
||||
p++;
|
||||
|
||||
if (wsmia_def) // { dg-warning "-Waddress" }
|
||||
p++;
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
extern int foo (int) __attribute__ ((weak));
|
||||
|
||||
int i __attribute__ ((weak));
|
||||
extern int i __attribute__ ((weak));
|
||||
|
||||
void
|
||||
bar (int a)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
extern int foo (int) __attribute__ ((weak));
|
||||
|
||||
int i __attribute__ ((weak));
|
||||
extern int i __attribute__ ((weak));
|
||||
|
||||
void
|
||||
bar (int a)
|
||||
|
|
|
@ -55,7 +55,7 @@ void * foo1e (void)
|
|||
extern void * ffoo1f (void);
|
||||
void * foo1f (void)
|
||||
{
|
||||
if (ffoo1f) /* { dg-warning "" } */
|
||||
if (ffoo1f) /* { dg-warning "-Waddress" } */
|
||||
ffoo1f ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -68,7 +68,9 @@ void * ffoox1g (void) { return (void *)0; }
|
|||
extern void * ffoo1g (void) __attribute__((weak, alias ("ffoox1g")));
|
||||
void * foo1g (void)
|
||||
{
|
||||
if (ffoo1g)
|
||||
/* ffoo1g is a weak alias for a symbol defined in this file, expect
|
||||
a -Waddress for the test (which is folded to true). */
|
||||
if (ffoo1g) // { dg-warning "-Waddress" }
|
||||
ffoo1g ();
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue