This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR c/6343 (was: Re: GCC 3.1 Prerelease)


On Thursday 25 April 2002 21:54, Jason Merrill wrote:
> >>>>> "Franz" == Franz Sirl <Franz.Sirl-kernel@lauterbach.com> writes:
> >
> > On Wednesday 24 April 2002 22:01, Jason Merrill wrote:
> >> The latter.  We don't want to warn about the C++ frontend's internal
> >> trickery with DECL_WEAK.
> >
> > What kind of trickery? Can I detect that in declare_weak?
>
> In the C++ frontend, in general an entity with vague linkage (such as a
> template instantion) has DECL_EXTERNAL set until EOF, at which point we
> decide what to do with it.  If we can't tell whether or not this is the One
> True translation unit for the entity, we mark it weak/comdat and emit it as
> needed.

OK, I added TREE_STATIC to the warning check and this killed the regression.

> >> I'd prefer to omit the warning entirely on the branch.
> >
> > Well, I prefer overzealous warnings over no warning at all in the same
> > way I prefer ICEs over miscompiled code :-). Besides that extra warning,
> > I'm really satisfied now with my patch otherwise and unless you think
> > it's overly complicated to get rid of it, I would like to fix it even for
> > the branch.
>
> The warning should only apply to weak externs; the address of a weak
> definition is never 0.  That should fix the C++ case above.

Ah, there's the forest :-). This cuts down the cases to warn about. I moved 
the check to a separate merge_weak function so I can check both OLDDECL and 
NEWDECL.

Bootstrapped without regressions on powerpc-linux-gnu and x86-linux-gnu.

OK to commit to mainline and branch?

Franz.

	PR c/6343
	* c-decl.c (duplicate_decls): Call merge_weak.
	* c-pragma.c (apply_pragma_weak): Warn about misuse.
	* output.h (merge_weak): Prototype merge_weak.
	* varasm.c (merge_weak): New function.
	(declare_weak): Make sure we don't give an error on VAR_DECLs.
	Mark RTL with SYMBOL_REF_WEAK.

cp:
	* decl.c (duplicate_decls): Call merge_weak.

testsuite:
	* gcc.dg/weak-[2-7].c: New tests.




Attachment: gcc-weaksym-7.patch
Description: Text document

/* { dg-do compile } */
/* { dg-options "-fno-common" } */

/* COFF does not support weak, and dg doesn't support UNSUPPORTED.  */
/* { dg-do compile { xfail *-*-coff i?86-pc-cygwin h8300-*-hms } } */

/* { dg-final { global target_triplet } } */
/* { dg-final { if [string match h8300-*-hms $target_triplet ] {return} } } */
/* { dg-final { if [string match i?86-pc-cygwin $target_triplet ] {return} } } */
/* { dg-final { if [string match *-*-coff $target_triplet ] {return} } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1a" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1b" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1c" } } */
/* { dg-final { scan-assembler-not "weak\[^ \t\]*\[ \t\]ffoo1d" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1e" } } */

/* test function addresses with #pragma weak */

#pragma weak ffoo1a
extern void * ffoo1a (void);
void * foo1a (void)
{
  return (void *)ffoo1a;
}

extern void * ffoo1b (void);
#pragma weak ffoo1b
void * foo1b (void)
{
  return (void *)ffoo1b;
}

extern void * ffoo1c (void);  /* { dg-warning "applying #pragma weak" "applying #pragma weak" } */
void * foo1c (void)
{
  return (void *)ffoo1c;
}
#pragma weak ffoo1c


int ffoo1d (void);
#pragma weak ffoo1d


extern void * ffoo1e (void);
#pragma weak ffoo1e
void * foo1e (void)
{
  if (ffoo1e)
    ffoo1e ();
  return 0;
}

/* { dg-do compile } */
/* { dg-options "-fno-common" } */

/* COFF does not support weak, and dg doesn't support UNSUPPORTED.  */
/* { dg-do compile { xfail *-*-coff i?86-pc-cygwin h8300-*-hms } } */

/* { dg-final { global target_triplet } } */
/* { dg-final { if [string match h8300-*-hms $target_triplet ] {return} } } */
/* { dg-final { if [string match i?86-pc-cygwin $target_triplet ] {return} } } */
/* { dg-final { if [string match *-*-coff $target_triplet ] {return} } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1a" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1b" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1c" } } */
/* { dg-final { scan-assembler-not "weak\[^ \t\]*\[ \t\]ffoo1d" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1e" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1f" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]ffoo1g" } } */

/* test function addresses with __attribute__((weak)) */

extern void * ffoo1a (void) __attribute__((weak));
extern void * ffoo1a (void);
void * foo1a (void)
{
  return (void *)ffoo1a;
}


extern void * ffoo1b (void);
extern void * ffoo1b (void) __attribute__((weak));
void * foo1b (void)
{
  return (void *)ffoo1b;
}


extern void * ffoo1c (void);  /* { dg-warning "weak declaration" "weak declaration" } */
void * foo1c (void)
{
  return (void *)ffoo1c;
}
extern void * ffoo1c (void) __attribute__((weak));


int ffoo1d (void);
int ffoo1d (void) __attribute__((weak));


extern void * ffoo1e (void);
extern void * ffoo1e (void)  __attribute__((weak));
void * foo1e (void)
{
  if (ffoo1e)
    ffoo1e ();
  return 0;
}


extern void * ffoo1f (void);    /* { dg-warning "weak declaration" "weak declaration" } */
extern void * ffoox1f (void);
void * foo1f (void)
{
  if (ffoo1f)
    ffoo1f ();
  return 0;
}
extern void * ffoo1f (void)  __attribute__((weak, alias ("ffoox1f")));


extern void * ffoo1g (void);
extern void * ffoox1g (void);
extern void * ffoo1g (void)  __attribute__((weak, alias ("ffoox1g")));
void * foo1g (void)
{
  if (ffoo1g)
    ffoo1g ();
  return 0;
}
/* { dg-do compile } */
/* { dg-options "-fno-common" } */

/* COFF does not support weak, and dg doesn't support UNSUPPORTED.  */
/* { dg-do compile { xfail *-*-coff i?86-pc-cygwin h8300-*-hms } } */

/* { dg-final { global target_triplet } } */
/* { dg-final { if [string match h8300-*-hms $target_triplet ] {return} } } */
/* { dg-final { if [string match i?86-pc-cygwin $target_triplet ] {return} } } */
/* { dg-final { if [string match *-*-coff $target_triplet ] {return} } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1a" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1b" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1c" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1d" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1e" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1f" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1g" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1h" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1i" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1j" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1k" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1l" } } */

/* test variable addresses with __attribute__ ((weak)) */

extern int vfoo1a __attribute__((weak));
extern int vfoo1a;
void * foo1a (void)
{
  return (void *)&vfoo1a;
}


extern int vfoo1b;
extern int vfoo1b __attribute__((weak));
void * foo1b (void)
{
  return (void *)&vfoo1b;
}


extern int vfoo1c;  /* { dg-warning "weak declaration" "weak declaration" } */
void * foo1c (void)
{
  return (void *)&vfoo1c;
}
extern int vfoo1c __attribute__((weak));


extern int vfoo1d __attribute__((weak));
int vfoo1d;
void * foo1d (void)
{
  return (void *)&vfoo1d;
}


int vfoo1e;
extern int vfoo1e __attribute__((weak));
void * foo1e (void)
{
  return (void *)&vfoo1e;
}


int vfoo1f;
void * foo1f (void)
{
  return (void *)&vfoo1f;
}
extern int vfoo1f __attribute__((weak));


extern int vfoo1g;
void * foo1g (void)
{
  return (void *)&vfoo1g;
}
int vfoo1g __attribute__((weak));


extern int vfoo1h __attribute__((weak));
void * foo1h (void)
{
  return (void *)&vfoo1h;
}
extern int vfoo1h __attribute__((weak));
int vfoo1h;


extern int vfoo1i __attribute__((weak));
void * foo1i (void)
{
  return (void *)&vfoo1i;
}
extern int vfoo1i __attribute__((weak));
extern int vfoo1i;


extern int vfoo1j __attribute__((weak));
void * foo1j (void)
{
  return (void *)&vfoo1j;
}
extern int vfoo1j;
extern int vfoo1j __attribute__((weak));


extern int vfoo1k __attribute__((weak));
int vfoo1k = 1;


int vfoox1l = 1;
extern int vfoo1l __attribute__((alias ("vfoox1l")));
extern int vfoo1l __attribute__((weak, alias ("vfoox1l")));

/* { dg-do compile } */
/* { dg-options "-fno-common" } */

/* COFF does not support weak, and dg doesn't support UNSUPPORTED.  */
/* { dg-do compile { xfail *-*-coff i?86-pc-cygwin h8300-*-hms } } */

/* { dg-final { global target_triplet } } */
/* { dg-final { if [string match h8300-*-hms $target_triplet ] {return} } } */
/* { dg-final { if [string match i?86-pc-cygwin $target_triplet ] {return} } } */
/* { dg-final { if [string match *-*-coff $target_triplet ] {return} } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1a" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1b" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1c" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1d" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1e" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1f" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1g" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1h" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1i" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1j" } } */
/* { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]vfoo1k" } } */

/* test variable addresses with #pragma weak */

#pragma weak vfoo1a
extern int vfoo1a;
void * foo1a (void)
{
  return (void *)&vfoo1a;
}


extern int vfoo1b;
#pragma weak vfoo1b
void * foo1b (void)
{
  return (void *)&vfoo1b;
}


extern int vfoo1c;  /* { dg-warning "applying #pragma weak" "applying #pragma weak" } */
void * foo1c (void)
{
  return (void *)&vfoo1c;
}
#pragma weak vfoo1c


#pragma weak vfoo1d
int vfoo1d;
void * foo1d (void)
{
  return (void *)&vfoo1d;
}


int vfoo1e;
#pragma weak vfoo1e
void * foo1e (void)
{
  return (void *)&vfoo1e;
}


int vfoo1f;
void * foo1f (void)
{
  return (void *)&vfoo1f;
}
#pragma weak vfoo1f


extern int vfoo1g;  /* { dg-warning "applying #pragma weak" "applying #pragma weak" } */
void * foo1g (void)
{
  return (void *)&vfoo1g;
}
#pragma weak vfoo1g
int vfoo1g;


extern int vfoo1h;
void * foo1h (void)
{
  return (void *)&vfoo1h;
}
int vfoo1h;
#pragma weak vfoo1h


int vfoo1i;
extern int vfoo1i;
void * foo1i (void)
{
  return (void *)&vfoo1i;
}
#pragma weak vfoo1i


extern int vfoo1j;
int vfoo1j;
void * foo1j (void)
{
  return (void *)&vfoo1j;
}
#pragma weak vfoo1j


#pragma weak vfoo1k
int vfoo1k = 1;

/* { dg-do compile } */

extern void * foo (void);
void * foo (void) { return (void *)foo; } /* { dg-error "precede" } */

#pragma weak foo
/* { dg-do compile } */

extern void * foo (void);
void * foo (void) { return (void *)foo; } /* { dg-error "precede" } */

extern void * foo (void) __attribute__((weak));

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]