diff options
author | Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org> | 2012-10-10 01:40:27 +0159 |
---|---|---|
committer | Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org> | 2012-10-10 01:40:27 +0159 |
commit | ee2ec6d2e2197bcd87b135f48ae82c209a83da9a (patch) | |
tree | f5386154f2fa284cbcff35e5857049ffc458f952 /gcc/testsuite/g++.dg/torture | |
parent | 0b642ae1fa9a3e65eb826c1964482f975b33f5cd (diff) | |
download | gcc-aarch64-ee2ec6d2e2197bcd87b135f48ae82c209a83da9a.tar.gz |
Sync with svn rev. 192243
Signed-off-by: Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>
Diffstat (limited to 'gcc/testsuite/g++.dg/torture')
-rw-r--r-- | gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C | 702 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C | 716 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr54735.C | 179 |
3 files changed, 1597 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C new file mode 100644 index 000000000..c57096cc0 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C @@ -0,0 +1,702 @@ +// Test -Wsizeof-pointer-memaccess warnings. +// { dg-do compile } +// { dg-options "-Wall" } +// Test just twice, once with -O0 non-fortified, once with -O2 fortified. +// { dg-skip-if "" { *-*-* } { "*" } { "-O0" "-O2" } } +// { dg-skip-if "" { *-*-* } { "-flto" } { "" } } + +extern "C" { + +typedef __SIZE_TYPE__ size_t; +extern void *memset (void *, int, size_t); +extern void *memcpy (void *__restrict, const void *__restrict, size_t); +extern void *memmove (void *__restrict, const void *__restrict, size_t); +extern int memcmp (const void *, const void *, size_t); +extern char *strncpy (char *__restrict, const char *__restrict, size_t); +extern char *strncat (char *__restrict, const char *__restrict, size_t); +extern char *strndup (const char *, size_t); +extern int strncmp (const char *, const char *, size_t); +extern int strncasecmp (const char *, const char *, size_t); + +#ifdef __OPTIMIZE__ +# define bos(ptr) __builtin_object_size (ptr, 1) +# define bos0(ptr) __builtin_object_size (ptr, 0) + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline void * +memset (void *dest, int c, size_t len) +{ + return __builtin___memset_chk (dest, c, len, bos0 (dest)); +} + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline void * +memcpy (void *__restrict dest, const void *__restrict src, size_t len) +{ + return __builtin___memcpy_chk (dest, src, len, bos0 (dest)); +} + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline void * +memmove (void *dest, const void *src, size_t len) +{ + return __builtin___memmove_chk (dest, src, len, bos0 (dest)); +} + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline char * +strncpy (char *__restrict dest, const char *__restrict src, size_t len) +{ + return __builtin___strncpy_chk (dest, src, len, bos (dest)); +} + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline char * +strncat (char *dest, const char *src, size_t len) +{ + return __builtin___strncat_chk (dest, src, len, bos (dest)); +} +#endif + +} + +struct A { short a, b; int c, d; long e, f; }; +typedef struct A TA; +typedef struct A *PA; +typedef TA *PTA; +struct B {}; +typedef struct B TB; +typedef struct B *PB; +typedef TB *PTB; +typedef int X[3][3][3]; + +int +f1 (void *x, int z) +{ + struct A a, *pa1 = &a; + TA *pa2 = &a; + PA pa3 = &a; + PTA pa4 = &a; + memset (&a, 0, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memset (pa1, 0, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pa2, 0, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pa3, 0, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pa4, 0, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pa1, 0, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memset (pa2, 0, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memset (pa3, 0, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memset (pa4, 0, sizeof (__typeof (pa4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + memcpy (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memcpy (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pa1, x, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memcpy (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memcpy (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memcpy (pa4, x, sizeof (__typeof (pa4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + memcpy (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + memcpy (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pa1, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memcpy (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memcpy (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memcpy (x, pa4, sizeof (__typeof (pa4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + + memmove (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memmove (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pa1, x, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memmove (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memmove (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memmove (pa4, x, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + memmove (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + memmove (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pa1, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memmove (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memmove (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memmove (x, pa4, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + + z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + + // These are correct, no warning. + memset (&a, 0, sizeof a); + memset (&a, 0, sizeof (a)); + memset (&a, 0, sizeof (struct A)); + memset (&a, 0, sizeof (const struct A)); + memset (&a, 0, sizeof (volatile struct A)); + memset (&a, 0, sizeof (volatile const struct A)); + memset (&a, 0, sizeof (TA)); + memset (&a, 0, sizeof (__typeof (*&a))); + memset (pa1, 0, sizeof (*pa1)); + memset (pa2, 0, sizeof (*pa3)); + memset (pa3, 0, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + memset ((void *) &a, 0, sizeof (&a)); + memset ((char *) &a, 0, sizeof (&a)); + memset (&a, 0, sizeof (&a) + 0); + memset (&a, 0, 0 + sizeof (&a)); + + // These are correct, no warning. + memcpy (&a, x, sizeof a); + memcpy (&a, x, sizeof (a)); + memcpy (&a, x, sizeof (struct A)); + memcpy (&a, x, sizeof (const struct A)); + memcpy (&a, x, sizeof (volatile struct A)); + memcpy (&a, x, sizeof (volatile const struct A)); + memcpy (&a, x, sizeof (TA)); + memcpy (&a, x, sizeof (__typeof (*&a))); + memcpy (pa1, x, sizeof (*pa1)); + memcpy (pa2, x, sizeof (*pa3)); + memcpy (pa3, x, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + memcpy ((void *) &a, x, sizeof (&a)); + memcpy ((char *) &a, x, sizeof (&a)); + memcpy (&a, x, sizeof (&a) + 0); + memcpy (&a, x, 0 + sizeof (&a)); + + // These are correct, no warning. + memcpy (x, &a, sizeof a); + memcpy (x, &a, sizeof (a)); + memcpy (x, &a, sizeof (struct A)); + memcpy (x, &a, sizeof (const struct A)); + memcpy (x, &a, sizeof (volatile struct A)); + memcpy (x, &a, sizeof (volatile const struct A)); + memcpy (x, &a, sizeof (TA)); + memcpy (x, &a, sizeof (__typeof (*&a))); + memcpy (x, pa1, sizeof (*pa1)); + memcpy (x, pa2, sizeof (*pa3)); + memcpy (x, pa3, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + memcpy (x, (void *) &a, sizeof (&a)); + memcpy (x, (char *) &a, sizeof (&a)); + memcpy (x, &a, sizeof (&a) + 0); + memcpy (x, &a, 0 + sizeof (&a)); + + // These are correct, no warning. + memmove (&a, x, sizeof a); + memmove (&a, x, sizeof (a)); + memmove (&a, x, sizeof (struct A)); + memmove (&a, x, sizeof (const struct A)); + memmove (&a, x, sizeof (volatile struct A)); + memmove (&a, x, sizeof (volatile const struct A)); + memmove (&a, x, sizeof (TA)); + memmove (&a, x, sizeof (__typeof (*&a))); + memmove (pa1, x, sizeof (*pa1)); + memmove (pa2, x, sizeof (*pa3)); + memmove (pa3, x, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + memmove ((void *) &a, x, sizeof (&a)); + memmove ((char *) &a, x, sizeof (&a)); + memmove (&a, x, sizeof (&a) + 0); + memmove (&a, x, 0 + sizeof (&a)); + + // These are correct, no warning. + memmove (x, &a, sizeof a); + memmove (x, &a, sizeof (a)); + memmove (x, &a, sizeof (struct A)); + memmove (x, &a, sizeof (const struct A)); + memmove (x, &a, sizeof (volatile struct A)); + memmove (x, &a, sizeof (volatile const struct A)); + memmove (x, &a, sizeof (TA)); + memmove (x, &a, sizeof (__typeof (*&a))); + memmove (x, pa1, sizeof (*pa1)); + memmove (x, pa2, sizeof (*pa3)); + memmove (x, pa3, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + memmove (x, (void *) &a, sizeof (&a)); + memmove (x, (char *) &a, sizeof (&a)); + memmove (x, &a, sizeof (&a) + 0); + memmove (x, &a, 0 + sizeof (&a)); + + // These are correct, no warning. + z += memcmp (&a, x, sizeof a); + z += memcmp (&a, x, sizeof (a)); + z += memcmp (&a, x, sizeof (struct A)); + z += memcmp (&a, x, sizeof (const struct A)); + z += memcmp (&a, x, sizeof (volatile struct A)); + z += memcmp (&a, x, sizeof (volatile const struct A)); + z += memcmp (&a, x, sizeof (TA)); + z += memcmp (&a, x, sizeof (__typeof (*&a))); + z += memcmp (pa1, x, sizeof (*pa1)); + z += memcmp (pa2, x, sizeof (*pa3)); + z += memcmp (pa3, x, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + z += memcmp ((void *) &a, x, sizeof (&a)); + z += memcmp ((char *) &a, x, sizeof (&a)); + z += memcmp (&a, x, sizeof (&a) + 0); + z += memcmp (&a, x, 0 + sizeof (&a)); + + // These are correct, no warning. + z += memcmp (x, &a, sizeof a); + z += memcmp (x, &a, sizeof (a)); + z += memcmp (x, &a, sizeof (struct A)); + z += memcmp (x, &a, sizeof (const struct A)); + z += memcmp (x, &a, sizeof (volatile struct A)); + z += memcmp (x, &a, sizeof (volatile const struct A)); + z += memcmp (x, &a, sizeof (TA)); + z += memcmp (x, &a, sizeof (__typeof (*&a))); + z += memcmp (x, pa1, sizeof (*pa1)); + z += memcmp (x, pa2, sizeof (*pa3)); + z += memcmp (x, pa3, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + z += memcmp (x, (void *) &a, sizeof (&a)); + z += memcmp (x, (char *) &a, sizeof (&a)); + z += memcmp (x, &a, sizeof (&a) + 0); + z += memcmp (x, &a, 0 + sizeof (&a)); + + return z; +} + +int +f2 (void *x, int z) +{ + struct B b, *pb1 = &b; + TB *pb2 = &b; + PB pb3 = &b; + PTB pb4 = &b; + memset (&b, 0, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memset (pb1, 0, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pb2, 0, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pb3, 0, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pb4, 0, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pb1, 0, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memset (pb2, 0, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memset (pb3, 0, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memset (pb4, 0, sizeof (__typeof (pb4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + memcpy (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memcpy (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pb1, x, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memcpy (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memcpy (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memcpy (pb4, x, sizeof (__typeof (pb4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + memcpy (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + memcpy (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pb1, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memcpy (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memcpy (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memcpy (x, pb4, sizeof (__typeof (pb4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + + memmove (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memmove (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pb1, x, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memmove (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memmove (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memmove (pb4, x, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + memmove (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + memmove (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pb1, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memmove (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memmove (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memmove (x, pb4, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + + z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + + // These are correct, no warning. + memset (&b, 0, sizeof b); + memset (&b, 0, sizeof (b)); + memset (&b, 0, sizeof (struct B)); + memset (&b, 0, sizeof (const struct B)); + memset (&b, 0, sizeof (volatile struct B)); + memset (&b, 0, sizeof (volatile const struct B)); + memset (&b, 0, sizeof (TB)); + memset (&b, 0, sizeof (__typeof (*&b))); + memset (pb1, 0, sizeof (*pb1)); + memset (pb2, 0, sizeof (*pb3)); + memset (pb3, 0, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + memset ((void *) &b, 0, sizeof (&b)); + memset ((char *) &b, 0, sizeof (&b)); + memset (&b, 0, sizeof (&b) + 0); + memset (&b, 0, 0 + sizeof (&b)); + + // These are correct, no warning. + memcpy (&b, x, sizeof b); + memcpy (&b, x, sizeof (b)); + memcpy (&b, x, sizeof (struct B)); + memcpy (&b, x, sizeof (const struct B)); + memcpy (&b, x, sizeof (volatile struct B)); + memcpy (&b, x, sizeof (volatile const struct B)); + memcpy (&b, x, sizeof (TB)); + memcpy (&b, x, sizeof (__typeof (*&b))); + memcpy (pb1, x, sizeof (*pb1)); + memcpy (pb2, x, sizeof (*pb3)); + memcpy (pb3, x, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + memcpy ((void *) &b, x, sizeof (&b)); + memcpy ((char *) &b, x, sizeof (&b)); + memcpy (&b, x, sizeof (&b) + 0); + memcpy (&b, x, 0 + sizeof (&b)); + + // These are correct, no warning. + memcpy (x, &b, sizeof b); + memcpy (x, &b, sizeof (b)); + memcpy (x, &b, sizeof (struct B)); + memcpy (x, &b, sizeof (const struct B)); + memcpy (x, &b, sizeof (volatile struct B)); + memcpy (x, &b, sizeof (volatile const struct B)); + memcpy (x, &b, sizeof (TB)); + memcpy (x, &b, sizeof (__typeof (*&b))); + memcpy (x, pb1, sizeof (*pb1)); + memcpy (x, pb2, sizeof (*pb3)); + memcpy (x, pb3, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + memcpy (x, (void *) &b, sizeof (&b)); + memcpy (x, (char *) &b, sizeof (&b)); + memcpy (x, &b, sizeof (&b) + 0); + memcpy (x, &b, 0 + sizeof (&b)); + + // These are correct, no warning. + memmove (&b, x, sizeof b); + memmove (&b, x, sizeof (b)); + memmove (&b, x, sizeof (struct B)); + memmove (&b, x, sizeof (const struct B)); + memmove (&b, x, sizeof (volatile struct B)); + memmove (&b, x, sizeof (volatile const struct B)); + memmove (&b, x, sizeof (TB)); + memmove (&b, x, sizeof (__typeof (*&b))); + memmove (pb1, x, sizeof (*pb1)); + memmove (pb2, x, sizeof (*pb3)); + memmove (pb3, x, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + memmove ((void *) &b, x, sizeof (&b)); + memmove ((char *) &b, x, sizeof (&b)); + memmove (&b, x, sizeof (&b) + 0); + memmove (&b, x, 0 + sizeof (&b)); + + // These are correct, no warning. + memmove (x, &b, sizeof b); + memmove (x, &b, sizeof (b)); + memmove (x, &b, sizeof (struct B)); + memmove (x, &b, sizeof (const struct B)); + memmove (x, &b, sizeof (volatile struct B)); + memmove (x, &b, sizeof (volatile const struct B)); + memmove (x, &b, sizeof (TB)); + memmove (x, &b, sizeof (__typeof (*&b))); + memmove (x, pb1, sizeof (*pb1)); + memmove (x, pb2, sizeof (*pb3)); + memmove (x, pb3, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + memmove (x, (void *) &b, sizeof (&b)); + memmove (x, (char *) &b, sizeof (&b)); + memmove (x, &b, sizeof (&b) + 0); + memmove (x, &b, 0 + sizeof (&b)); + + // These are correct, no warning. + z += memcmp (&b, x, sizeof b); + z += memcmp (&b, x, sizeof (b)); + z += memcmp (&b, x, sizeof (struct B)); + z += memcmp (&b, x, sizeof (const struct B)); + z += memcmp (&b, x, sizeof (volatile struct B)); + z += memcmp (&b, x, sizeof (volatile const struct B)); + z += memcmp (&b, x, sizeof (TB)); + z += memcmp (&b, x, sizeof (__typeof (*&b))); + z += memcmp (pb1, x, sizeof (*pb1)); + z += memcmp (pb2, x, sizeof (*pb3)); + z += memcmp (pb3, x, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + z += memcmp ((void *) &b, x, sizeof (&b)); + z += memcmp ((char *) &b, x, sizeof (&b)); + z += memcmp (&b, x, sizeof (&b) + 0); + z += memcmp (&b, x, 0 + sizeof (&b)); + + // These are correct, no warning. + z += memcmp (x, &b, sizeof b); + z += memcmp (x, &b, sizeof (b)); + z += memcmp (x, &b, sizeof (struct B)); + z += memcmp (x, &b, sizeof (const struct B)); + z += memcmp (x, &b, sizeof (volatile struct B)); + z += memcmp (x, &b, sizeof (volatile const struct B)); + z += memcmp (x, &b, sizeof (TB)); + z += memcmp (x, &b, sizeof (__typeof (*&b))); + z += memcmp (x, pb1, sizeof (*pb1)); + z += memcmp (x, pb2, sizeof (*pb3)); + z += memcmp (x, pb3, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + z += memcmp (x, (void *) &b, sizeof (&b)); + z += memcmp (x, (char *) &b, sizeof (&b)); + z += memcmp (x, &b, sizeof (&b) + 0); + z += memcmp (x, &b, 0 + sizeof (&b)); + + return z; +} + +int +f3 (void *x, char *y, int z, X w) +{ + unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16); + char buf1[7]; + signed char buf2[z + 32]; + long buf3[17]; + int *buf4[9]; + signed char *y2 = buf2; + char c; + char *y3; + memset (y, 0, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memset (y1, 0, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memset (y2, 0, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memset (&c, 0, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memset (w, 0, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + + memcpy (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memcpy (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memcpy (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memcpy (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memcpy (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + + memcpy (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + memcpy (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + memcpy (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + memcpy (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + memcpy (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + + memmove (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memmove (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memmove (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memmove (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memmove (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + + memmove (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + memmove (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + memmove (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + memmove (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + memmove (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + + z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + + z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + + // These are correct, no warning. + memset (y, 0, sizeof (*y)); + memset (y1, 0, sizeof (*y2)); + memset (buf1, 0, sizeof buf1); + memset (buf3, 0, sizeof (buf3)); + memset (&buf3[0], 0, sizeof (buf3)); + memset (&buf4[0], 0, sizeof (buf4)); + memset (w, 0, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + memset ((void *) y, 0, sizeof (y)); + memset ((char *) y1, 0, sizeof (y2)); + memset (y, 0, sizeof (y) + 0); + memset (y1, 0, 0 + sizeof (y2)); + memset ((void *) &c, 0, sizeof (&c)); + memset ((signed char *) &c, 0, sizeof (&c)); + memset (&c, 0, sizeof (&c) + 0); + memset (&c, 0, 0 + sizeof (&c)); + + // These are correct, no warning. + memcpy (y, x, sizeof (*y)); + memcpy (y1, x, sizeof (*y2)); + memcpy (buf1, x, sizeof buf1); + memcpy (buf3, x, sizeof (buf3)); + memcpy (&buf3[0], x, sizeof (buf3)); + memcpy (&buf4[0], x, sizeof (buf4)); + memcpy (&y3, y, sizeof (y3)); + memcpy ((char *) &y3, y, sizeof (y3)); + memcpy (w, x, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + memcpy ((void *) y, x, sizeof (y)); + memcpy ((char *) y1, x, sizeof (y2)); + memcpy (y, x, sizeof (y) + 0); + memcpy (y1, x, 0 + sizeof (y2)); + memcpy ((void *) &c, x, sizeof (&c)); + memcpy ((signed char *) &c, x, sizeof (&c)); + memcpy (&c, x, sizeof (&c) + 0); + memcpy (&c, x, 0 + sizeof (&c)); + + // These are correct, no warning. + memcpy (x, y, sizeof (*y)); + memcpy (x, y1, sizeof (*y2)); + memcpy (x, buf1, sizeof buf1); + memcpy (x, buf3, sizeof (buf3)); + memcpy (x, &buf3[0], sizeof (buf3)); + memcpy (x, &buf4[0], sizeof (buf4)); + memcpy (y, &y3, sizeof (y3)); + memcpy (y, (char *) &y3, sizeof (y3)); + memcpy (x, w, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + memcpy (x, (void *) y, sizeof (y)); + memcpy (x, (char *) y1, sizeof (y2)); + memcpy (x, y, sizeof (y) + 0); + memcpy (x, y1, 0 + sizeof (y2)); + memcpy (x, (void *) &c, sizeof (&c)); + memcpy (x, (signed char *) &c, sizeof (&c)); + memcpy (x, &c, sizeof (&c) + 0); + memcpy (x, &c, 0 + sizeof (&c)); + + // These are correct, no warning. + memmove (y, x, sizeof (*y)); + memmove (y1, x, sizeof (*y2)); + memmove (buf1, x, sizeof buf1); + memmove (buf3, x, sizeof (buf3)); + memmove (&buf3[0], x, sizeof (buf3)); + memmove (&buf4[0], x, sizeof (buf4)); + memmove (&y3, y, sizeof (y3)); + memmove ((char *) &y3, y, sizeof (y3)); + memmove (w, x, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + memmove ((void *) y, x, sizeof (y)); + memmove ((char *) y1, x, sizeof (y2)); + memmove (y, x, sizeof (y) + 0); + memmove (y1, x, 0 + sizeof (y2)); + memmove ((void *) &c, x, sizeof (&c)); + memmove ((signed char *) &c, x, sizeof (&c)); + memmove (&c, x, sizeof (&c) + 0); + memmove (&c, x, 0 + sizeof (&c)); + + // These are correct, no warning. + memmove (x, y, sizeof (*y)); + memmove (x, y1, sizeof (*y2)); + memmove (x, buf1, sizeof buf1); + memmove (x, buf3, sizeof (buf3)); + memmove (x, &buf3[0], sizeof (buf3)); + memmove (x, &buf4[0], sizeof (buf4)); + memmove (y, &y3, sizeof (y3)); + memmove (y, (char *) &y3, sizeof (y3)); + memmove (x, w, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + memmove (x, (void *) y, sizeof (y)); + memmove (x, (char *) y1, sizeof (y2)); + memmove (x, y, sizeof (y) + 0); + memmove (x, y1, 0 + sizeof (y2)); + memmove (x, (void *) &c, sizeof (&c)); + memmove (x, (signed char *) &c, sizeof (&c)); + memmove (x, &c, sizeof (&c) + 0); + memmove (x, &c, 0 + sizeof (&c)); + + // These are correct, no warning. + z += memcmp (y, x, sizeof (*y)); + z += memcmp (y1, x, sizeof (*y2)); + z += memcmp (buf1, x, sizeof buf1); + z += memcmp (buf3, x, sizeof (buf3)); + z += memcmp (&buf3[0], x, sizeof (buf3)); + z += memcmp (&buf4[0], x, sizeof (buf4)); + z += memcmp (&y3, y, sizeof (y3)); + z += memcmp ((char *) &y3, y, sizeof (y3)); + z += memcmp (w, x, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + z += memcmp ((void *) y, x, sizeof (y)); + z += memcmp ((char *) y1, x, sizeof (y2)); + z += memcmp (y, x, sizeof (y) + 0); + z += memcmp (y1, x, 0 + sizeof (y2)); + z += memcmp ((void *) &c, x, sizeof (&c)); + z += memcmp ((signed char *) &c, x, sizeof (&c)); + z += memcmp (&c, x, sizeof (&c) + 0); + z += memcmp (&c, x, 0 + sizeof (&c)); + + // These are correct, no warning. + z += memcmp (x, y, sizeof (*y)); + z += memcmp (x, y1, sizeof (*y2)); + z += memcmp (x, buf1, sizeof buf1); + z += memcmp (x, buf3, sizeof (buf3)); + z += memcmp (x, &buf3[0], sizeof (buf3)); + z += memcmp (x, &buf4[0], sizeof (buf4)); + z += memcmp (y, &y3, sizeof (y3)); + z += memcmp (y, (char *) &y3, sizeof (y3)); + z += memcmp (x, w, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + z += memcmp (x, (void *) y, sizeof (y)); + z += memcmp (x, (char *) y1, sizeof (y2)); + z += memcmp (x, y, sizeof (y) + 0); + z += memcmp (x, y1, 0 + sizeof (y2)); + z += memcmp (x, (void *) &c, sizeof (&c)); + z += memcmp (x, (signed char *) &c, sizeof (&c)); + z += memcmp (x, &c, sizeof (&c) + 0); + z += memcmp (x, &c, 0 + sizeof (&c)); + + return z; +} + +int +f4 (char *x, char **y, int z) +{ + const char *s1 = "foobarbaz"; + const char *s2 = "abcde12345678"; + strncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + strncat (x, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + y[0] = strndup (s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + + // These are correct, no warning. + const char s3[] = "foobarbaz"; + const char s4[] = "abcde12345678"; + strncpy (x, s3, sizeof (s3)); + strncat (x, s4, sizeof (s4)); + y[1] = strndup (s3, sizeof (s3)); + z += strncmp (s3, s4, sizeof (s3)); + z += strncmp (s3, s4, sizeof (s4)); + z += strncasecmp (s3, s4, sizeof (s3)); + z += strncasecmp (s3, s4, sizeof (s4)); + + return z; +} + +// { dg-prune-output "\[\n\r\]*will always overflow\[\n\r\]*" } diff --git a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C new file mode 100644 index 000000000..d5a29d8f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C @@ -0,0 +1,716 @@ +// Test -Wsizeof-pointer-memaccess warnings. +// { dg-do compile } +// { dg-options "-Wall" } +// Test just twice, once with -O0 non-fortified, once with -O2 fortified. +// { dg-skip-if "" { *-*-* } { "*" } { "-O0" "-O2" } } +// { dg-skip-if "" { *-*-* } { "-flto" } { "" } } + +extern "C" { + +typedef __SIZE_TYPE__ size_t; +extern void *memset (void *, int, size_t); +extern void *memcpy (void *__restrict, const void *__restrict, size_t); +extern void *memmove (void *__restrict, const void *__restrict, size_t); +extern int memcmp (const void *, const void *, size_t); +extern char *strncpy (char *__restrict, const char *__restrict, size_t); +extern char *strncat (char *__restrict, const char *__restrict, size_t); +extern char *strndup (const char *, size_t); +extern int strncmp (const char *, const char *, size_t); +extern int strncasecmp (const char *, const char *, size_t); + +#ifdef __OPTIMIZE__ +# define bos(ptr) __builtin_object_size (ptr, 1) +# define bos0(ptr) __builtin_object_size (ptr, 0) + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline void * +memset (void *dest, int c, size_t len) +{ + return __builtin___memset_chk (dest, c, len, bos0 (dest)); +} + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline void * +memcpy (void *__restrict dest, const void *__restrict src, size_t len) +{ + return __builtin___memcpy_chk (dest, src, len, bos0 (dest)); +} + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline void * +memmove (void *dest, const void *src, size_t len) +{ + return __builtin___memmove_chk (dest, src, len, bos0 (dest)); +} + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline char * +strncpy (char *__restrict dest, const char *__restrict src, size_t len) +{ + return __builtin___strncpy_chk (dest, src, len, bos (dest)); +} + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline char * +strncat (char *dest, const char *src, size_t len) +{ + return __builtin___strncat_chk (dest, src, len, bos (dest)); +} +#endif + +} + +struct A { short a, b; int c, d; long e, f; }; +typedef struct A TA; +typedef struct A *PA; +typedef TA *PTA; +struct B {}; +typedef struct B TB; +typedef struct B *PB; +typedef TB *PTB; +typedef int X[3][3][3]; + +template <int N> +int +f1 (void *x, int z) +{ + struct A a, *pa1 = &a; + TA *pa2 = &a; + PA pa3 = &a; + PTA pa4 = &a; + memset (&a, 0, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memset (pa1, 0, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pa2, 0, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pa3, 0, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pa4, 0, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pa1, 0, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memset (pa2, 0, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memset (pa3, 0, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memset (pa4, 0, sizeof (__typeof (pa4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + memcpy (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memcpy (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pa1, x, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memcpy (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memcpy (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memcpy (pa4, x, sizeof (__typeof (pa4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + memcpy (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + memcpy (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pa1, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memcpy (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memcpy (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memcpy (x, pa4, sizeof (__typeof (pa4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + + memmove (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memmove (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pa1, x, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memmove (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memmove (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memmove (pa4, x, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + memmove (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + memmove (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pa1, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memmove (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memmove (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memmove (x, pa4, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + + z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + + // These are correct, no warning. + memset (&a, 0, sizeof a); + memset (&a, 0, sizeof (a)); + memset (&a, 0, sizeof (struct A)); + memset (&a, 0, sizeof (const struct A)); + memset (&a, 0, sizeof (volatile struct A)); + memset (&a, 0, sizeof (volatile const struct A)); + memset (&a, 0, sizeof (TA)); + memset (&a, 0, sizeof (__typeof (*&a))); + memset (pa1, 0, sizeof (*pa1)); + memset (pa2, 0, sizeof (*pa3)); + memset (pa3, 0, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + memset ((void *) &a, 0, sizeof (&a)); + memset ((char *) &a, 0, sizeof (&a)); + memset (&a, 0, sizeof (&a) + 0); + memset (&a, 0, 0 + sizeof (&a)); + + // These are correct, no warning. + memcpy (&a, x, sizeof a); + memcpy (&a, x, sizeof (a)); + memcpy (&a, x, sizeof (struct A)); + memcpy (&a, x, sizeof (const struct A)); + memcpy (&a, x, sizeof (volatile struct A)); + memcpy (&a, x, sizeof (volatile const struct A)); + memcpy (&a, x, sizeof (TA)); + memcpy (&a, x, sizeof (__typeof (*&a))); + memcpy (pa1, x, sizeof (*pa1)); + memcpy (pa2, x, sizeof (*pa3)); + memcpy (pa3, x, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + memcpy ((void *) &a, x, sizeof (&a)); + memcpy ((char *) &a, x, sizeof (&a)); + memcpy (&a, x, sizeof (&a) + 0); + memcpy (&a, x, 0 + sizeof (&a)); + + // These are correct, no warning. + memcpy (x, &a, sizeof a); + memcpy (x, &a, sizeof (a)); + memcpy (x, &a, sizeof (struct A)); + memcpy (x, &a, sizeof (const struct A)); + memcpy (x, &a, sizeof (volatile struct A)); + memcpy (x, &a, sizeof (volatile const struct A)); + memcpy (x, &a, sizeof (TA)); + memcpy (x, &a, sizeof (__typeof (*&a))); + memcpy (x, pa1, sizeof (*pa1)); + memcpy (x, pa2, sizeof (*pa3)); + memcpy (x, pa3, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + memcpy (x, (void *) &a, sizeof (&a)); + memcpy (x, (char *) &a, sizeof (&a)); + memcpy (x, &a, sizeof (&a) + 0); + memcpy (x, &a, 0 + sizeof (&a)); + + // These are correct, no warning. + memmove (&a, x, sizeof a); + memmove (&a, x, sizeof (a)); + memmove (&a, x, sizeof (struct A)); + memmove (&a, x, sizeof (const struct A)); + memmove (&a, x, sizeof (volatile struct A)); + memmove (&a, x, sizeof (volatile const struct A)); + memmove (&a, x, sizeof (TA)); + memmove (&a, x, sizeof (__typeof (*&a))); + memmove (pa1, x, sizeof (*pa1)); + memmove (pa2, x, sizeof (*pa3)); + memmove (pa3, x, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + memmove ((void *) &a, x, sizeof (&a)); + memmove ((char *) &a, x, sizeof (&a)); + memmove (&a, x, sizeof (&a) + 0); + memmove (&a, x, 0 + sizeof (&a)); + + // These are correct, no warning. + memmove (x, &a, sizeof a); + memmove (x, &a, sizeof (a)); + memmove (x, &a, sizeof (struct A)); + memmove (x, &a, sizeof (const struct A)); + memmove (x, &a, sizeof (volatile struct A)); + memmove (x, &a, sizeof (volatile const struct A)); + memmove (x, &a, sizeof (TA)); + memmove (x, &a, sizeof (__typeof (*&a))); + memmove (x, pa1, sizeof (*pa1)); + memmove (x, pa2, sizeof (*pa3)); + memmove (x, pa3, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + memmove (x, (void *) &a, sizeof (&a)); + memmove (x, (char *) &a, sizeof (&a)); + memmove (x, &a, sizeof (&a) + 0); + memmove (x, &a, 0 + sizeof (&a)); + + // These are correct, no warning. + z += memcmp (&a, x, sizeof a); + z += memcmp (&a, x, sizeof (a)); + z += memcmp (&a, x, sizeof (struct A)); + z += memcmp (&a, x, sizeof (const struct A)); + z += memcmp (&a, x, sizeof (volatile struct A)); + z += memcmp (&a, x, sizeof (volatile const struct A)); + z += memcmp (&a, x, sizeof (TA)); + z += memcmp (&a, x, sizeof (__typeof (*&a))); + z += memcmp (pa1, x, sizeof (*pa1)); + z += memcmp (pa2, x, sizeof (*pa3)); + z += memcmp (pa3, x, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + z += memcmp ((void *) &a, x, sizeof (&a)); + z += memcmp ((char *) &a, x, sizeof (&a)); + z += memcmp (&a, x, sizeof (&a) + 0); + z += memcmp (&a, x, 0 + sizeof (&a)); + + // These are correct, no warning. + z += memcmp (x, &a, sizeof a); + z += memcmp (x, &a, sizeof (a)); + z += memcmp (x, &a, sizeof (struct A)); + z += memcmp (x, &a, sizeof (const struct A)); + z += memcmp (x, &a, sizeof (volatile struct A)); + z += memcmp (x, &a, sizeof (volatile const struct A)); + z += memcmp (x, &a, sizeof (TA)); + z += memcmp (x, &a, sizeof (__typeof (*&a))); + z += memcmp (x, pa1, sizeof (*pa1)); + z += memcmp (x, pa2, sizeof (*pa3)); + z += memcmp (x, pa3, sizeof (__typeof (*pa3))); + // These are probably broken, but obfuscated, no warning. + z += memcmp (x, (void *) &a, sizeof (&a)); + z += memcmp (x, (char *) &a, sizeof (&a)); + z += memcmp (x, &a, sizeof (&a) + 0); + z += memcmp (x, &a, 0 + sizeof (&a)); + + return z; +} + +template <int N> +int +f2 (void *x, int z) +{ + struct B b, *pb1 = &b; + TB *pb2 = &b; + PB pb3 = &b; + PTB pb4 = &b; + memset (&b, 0, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memset (pb1, 0, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pb2, 0, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pb3, 0, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pb4, 0, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memset (pb1, 0, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memset (pb2, 0, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memset (pb3, 0, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memset (pb4, 0, sizeof (__typeof (pb4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + memcpy (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memcpy (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memcpy (pb1, x, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memcpy (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memcpy (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memcpy (pb4, x, sizeof (__typeof (pb4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + memcpy (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + memcpy (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memcpy (x, pb1, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memcpy (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memcpy (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memcpy (x, pb4, sizeof (__typeof (pb4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + + memmove (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memmove (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + memmove (pb1, x, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memmove (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memmove (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + memmove (pb4, x, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + memmove (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + memmove (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + memmove (x, pb1, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memmove (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memmove (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + memmove (x, pb4, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + + z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } + + z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + + // These are correct, no warning. + memset (&b, 0, sizeof b); + memset (&b, 0, sizeof (b)); + memset (&b, 0, sizeof (struct B)); + memset (&b, 0, sizeof (const struct B)); + memset (&b, 0, sizeof (volatile struct B)); + memset (&b, 0, sizeof (volatile const struct B)); + memset (&b, 0, sizeof (TB)); + memset (&b, 0, sizeof (__typeof (*&b))); + memset (pb1, 0, sizeof (*pb1)); + memset (pb2, 0, sizeof (*pb3)); + memset (pb3, 0, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + memset ((void *) &b, 0, sizeof (&b)); + memset ((char *) &b, 0, sizeof (&b)); + memset (&b, 0, sizeof (&b) + 0); + memset (&b, 0, 0 + sizeof (&b)); + + // These are correct, no warning. + memcpy (&b, x, sizeof b); + memcpy (&b, x, sizeof (b)); + memcpy (&b, x, sizeof (struct B)); + memcpy (&b, x, sizeof (const struct B)); + memcpy (&b, x, sizeof (volatile struct B)); + memcpy (&b, x, sizeof (volatile const struct B)); + memcpy (&b, x, sizeof (TB)); + memcpy (&b, x, sizeof (__typeof (*&b))); + memcpy (pb1, x, sizeof (*pb1)); + memcpy (pb2, x, sizeof (*pb3)); + memcpy (pb3, x, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + memcpy ((void *) &b, x, sizeof (&b)); + memcpy ((char *) &b, x, sizeof (&b)); + memcpy (&b, x, sizeof (&b) + 0); + memcpy (&b, x, 0 + sizeof (&b)); + + // These are correct, no warning. + memcpy (x, &b, sizeof b); + memcpy (x, &b, sizeof (b)); + memcpy (x, &b, sizeof (struct B)); + memcpy (x, &b, sizeof (const struct B)); + memcpy (x, &b, sizeof (volatile struct B)); + memcpy (x, &b, sizeof (volatile const struct B)); + memcpy (x, &b, sizeof (TB)); + memcpy (x, &b, sizeof (__typeof (*&b))); + memcpy (x, pb1, sizeof (*pb1)); + memcpy (x, pb2, sizeof (*pb3)); + memcpy (x, pb3, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + memcpy (x, (void *) &b, sizeof (&b)); + memcpy (x, (char *) &b, sizeof (&b)); + memcpy (x, &b, sizeof (&b) + 0); + memcpy (x, &b, 0 + sizeof (&b)); + + // These are correct, no warning. + memmove (&b, x, sizeof b); + memmove (&b, x, sizeof (b)); + memmove (&b, x, sizeof (struct B)); + memmove (&b, x, sizeof (const struct B)); + memmove (&b, x, sizeof (volatile struct B)); + memmove (&b, x, sizeof (volatile const struct B)); + memmove (&b, x, sizeof (TB)); + memmove (&b, x, sizeof (__typeof (*&b))); + memmove (pb1, x, sizeof (*pb1)); + memmove (pb2, x, sizeof (*pb3)); + memmove (pb3, x, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + memmove ((void *) &b, x, sizeof (&b)); + memmove ((char *) &b, x, sizeof (&b)); + memmove (&b, x, sizeof (&b) + 0); + memmove (&b, x, 0 + sizeof (&b)); + + // These are correct, no warning. + memmove (x, &b, sizeof b); + memmove (x, &b, sizeof (b)); + memmove (x, &b, sizeof (struct B)); + memmove (x, &b, sizeof (const struct B)); + memmove (x, &b, sizeof (volatile struct B)); + memmove (x, &b, sizeof (volatile const struct B)); + memmove (x, &b, sizeof (TB)); + memmove (x, &b, sizeof (__typeof (*&b))); + memmove (x, pb1, sizeof (*pb1)); + memmove (x, pb2, sizeof (*pb3)); + memmove (x, pb3, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + memmove (x, (void *) &b, sizeof (&b)); + memmove (x, (char *) &b, sizeof (&b)); + memmove (x, &b, sizeof (&b) + 0); + memmove (x, &b, 0 + sizeof (&b)); + + // These are correct, no warning. + z += memcmp (&b, x, sizeof b); + z += memcmp (&b, x, sizeof (b)); + z += memcmp (&b, x, sizeof (struct B)); + z += memcmp (&b, x, sizeof (const struct B)); + z += memcmp (&b, x, sizeof (volatile struct B)); + z += memcmp (&b, x, sizeof (volatile const struct B)); + z += memcmp (&b, x, sizeof (TB)); + z += memcmp (&b, x, sizeof (__typeof (*&b))); + z += memcmp (pb1, x, sizeof (*pb1)); + z += memcmp (pb2, x, sizeof (*pb3)); + z += memcmp (pb3, x, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + z += memcmp ((void *) &b, x, sizeof (&b)); + z += memcmp ((char *) &b, x, sizeof (&b)); + z += memcmp (&b, x, sizeof (&b) + 0); + z += memcmp (&b, x, 0 + sizeof (&b)); + + // These are correct, no warning. + z += memcmp (x, &b, sizeof b); + z += memcmp (x, &b, sizeof (b)); + z += memcmp (x, &b, sizeof (struct B)); + z += memcmp (x, &b, sizeof (const struct B)); + z += memcmp (x, &b, sizeof (volatile struct B)); + z += memcmp (x, &b, sizeof (volatile const struct B)); + z += memcmp (x, &b, sizeof (TB)); + z += memcmp (x, &b, sizeof (__typeof (*&b))); + z += memcmp (x, pb1, sizeof (*pb1)); + z += memcmp (x, pb2, sizeof (*pb3)); + z += memcmp (x, pb3, sizeof (__typeof (*pb3))); + // These are probably broken, but obfuscated, no warning. + z += memcmp (x, (void *) &b, sizeof (&b)); + z += memcmp (x, (char *) &b, sizeof (&b)); + z += memcmp (x, &b, sizeof (&b) + 0); + z += memcmp (x, &b, 0 + sizeof (&b)); + + return z; +} + +template <int N> +int +f3 (void *x, char *y, int z, X w) +{ + unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16); + char buf1[7]; + signed char buf2[z + 32]; + long buf3[17]; + int *buf4[9]; + signed char *y2 = buf2; + char c; + char *y3; + memset (y, 0, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memset (y1, 0, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memset (y2, 0, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memset (&c, 0, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memset (w, 0, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + + memcpy (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memcpy (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memcpy (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memcpy (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memcpy (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + + memcpy (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + memcpy (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + memcpy (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + memcpy (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + memcpy (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + + memmove (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memmove (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memmove (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + memmove (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + memmove (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + + memmove (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + memmove (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + memmove (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + memmove (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + memmove (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + + z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } + z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + + z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } + z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + + // These are correct, no warning. + memset (y, 0, sizeof (*y)); + memset (y1, 0, sizeof (*y2)); + memset (buf1, 0, sizeof buf1); + memset (buf3, 0, sizeof (buf3)); + memset (&buf3[0], 0, sizeof (buf3)); + memset (&buf4[0], 0, sizeof (buf4)); + memset (w, 0, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + memset ((void *) y, 0, sizeof (y)); + memset ((char *) y1, 0, sizeof (y2)); + memset (y, 0, sizeof (y) + 0); + memset (y1, 0, 0 + sizeof (y2)); + memset ((void *) &c, 0, sizeof (&c)); + memset ((signed char *) &c, 0, sizeof (&c)); + memset (&c, 0, sizeof (&c) + 0); + memset (&c, 0, 0 + sizeof (&c)); + + // These are correct, no warning. + memcpy (y, x, sizeof (*y)); + memcpy (y1, x, sizeof (*y2)); + memcpy (buf1, x, sizeof buf1); + memcpy (buf3, x, sizeof (buf3)); + memcpy (&buf3[0], x, sizeof (buf3)); + memcpy (&buf4[0], x, sizeof (buf4)); + memcpy (&y3, y, sizeof (y3)); + memcpy ((char *) &y3, y, sizeof (y3)); + memcpy (w, x, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + memcpy ((void *) y, x, sizeof (y)); + memcpy ((char *) y1, x, sizeof (y2)); + memcpy (y, x, sizeof (y) + 0); + memcpy (y1, x, 0 + sizeof (y2)); + memcpy ((void *) &c, x, sizeof (&c)); + memcpy ((signed char *) &c, x, sizeof (&c)); + memcpy (&c, x, sizeof (&c) + 0); + memcpy (&c, x, 0 + sizeof (&c)); + + // These are correct, no warning. + memcpy (x, y, sizeof (*y)); + memcpy (x, y1, sizeof (*y2)); + memcpy (x, buf1, sizeof buf1); + memcpy (x, buf3, sizeof (buf3)); + memcpy (x, &buf3[0], sizeof (buf3)); + memcpy (x, &buf4[0], sizeof (buf4)); + memcpy (y, &y3, sizeof (y3)); + memcpy (y, (char *) &y3, sizeof (y3)); + memcpy (x, w, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + memcpy (x, (void *) y, sizeof (y)); + memcpy (x, (char *) y1, sizeof (y2)); + memcpy (x, y, sizeof (y) + 0); + memcpy (x, y1, 0 + sizeof (y2)); + memcpy (x, (void *) &c, sizeof (&c)); + memcpy (x, (signed char *) &c, sizeof (&c)); + memcpy (x, &c, sizeof (&c) + 0); + memcpy (x, &c, 0 + sizeof (&c)); + + // These are correct, no warning. + memmove (y, x, sizeof (*y)); + memmove (y1, x, sizeof (*y2)); + memmove (buf1, x, sizeof buf1); + memmove (buf3, x, sizeof (buf3)); + memmove (&buf3[0], x, sizeof (buf3)); + memmove (&buf4[0], x, sizeof (buf4)); + memmove (&y3, y, sizeof (y3)); + memmove ((char *) &y3, y, sizeof (y3)); + memmove (w, x, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + memmove ((void *) y, x, sizeof (y)); + memmove ((char *) y1, x, sizeof (y2)); + memmove (y, x, sizeof (y) + 0); + memmove (y1, x, 0 + sizeof (y2)); + memmove ((void *) &c, x, sizeof (&c)); + memmove ((signed char *) &c, x, sizeof (&c)); + memmove (&c, x, sizeof (&c) + 0); + memmove (&c, x, 0 + sizeof (&c)); + + // These are correct, no warning. + memmove (x, y, sizeof (*y)); + memmove (x, y1, sizeof (*y2)); + memmove (x, buf1, sizeof buf1); + memmove (x, buf3, sizeof (buf3)); + memmove (x, &buf3[0], sizeof (buf3)); + memmove (x, &buf4[0], sizeof (buf4)); + memmove (y, &y3, sizeof (y3)); + memmove (y, (char *) &y3, sizeof (y3)); + memmove (x, w, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + memmove (x, (void *) y, sizeof (y)); + memmove (x, (char *) y1, sizeof (y2)); + memmove (x, y, sizeof (y) + 0); + memmove (x, y1, 0 + sizeof (y2)); + memmove (x, (void *) &c, sizeof (&c)); + memmove (x, (signed char *) &c, sizeof (&c)); + memmove (x, &c, sizeof (&c) + 0); + memmove (x, &c, 0 + sizeof (&c)); + + // These are correct, no warning. + z += memcmp (y, x, sizeof (*y)); + z += memcmp (y1, x, sizeof (*y2)); + z += memcmp (buf1, x, sizeof buf1); + z += memcmp (buf3, x, sizeof (buf3)); + z += memcmp (&buf3[0], x, sizeof (buf3)); + z += memcmp (&buf4[0], x, sizeof (buf4)); + z += memcmp (&y3, y, sizeof (y3)); + z += memcmp ((char *) &y3, y, sizeof (y3)); + z += memcmp (w, x, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + z += memcmp ((void *) y, x, sizeof (y)); + z += memcmp ((char *) y1, x, sizeof (y2)); + z += memcmp (y, x, sizeof (y) + 0); + z += memcmp (y1, x, 0 + sizeof (y2)); + z += memcmp ((void *) &c, x, sizeof (&c)); + z += memcmp ((signed char *) &c, x, sizeof (&c)); + z += memcmp (&c, x, sizeof (&c) + 0); + z += memcmp (&c, x, 0 + sizeof (&c)); + + // These are correct, no warning. + z += memcmp (x, y, sizeof (*y)); + z += memcmp (x, y1, sizeof (*y2)); + z += memcmp (x, buf1, sizeof buf1); + z += memcmp (x, buf3, sizeof (buf3)); + z += memcmp (x, &buf3[0], sizeof (buf3)); + z += memcmp (x, &buf4[0], sizeof (buf4)); + z += memcmp (y, &y3, sizeof (y3)); + z += memcmp (y, (char *) &y3, sizeof (y3)); + z += memcmp (x, w, sizeof (X)); + // These are probably broken, but obfuscated, no warning. + z += memcmp (x, (void *) y, sizeof (y)); + z += memcmp (x, (char *) y1, sizeof (y2)); + z += memcmp (x, y, sizeof (y) + 0); + z += memcmp (x, y1, 0 + sizeof (y2)); + z += memcmp (x, (void *) &c, sizeof (&c)); + z += memcmp (x, (signed char *) &c, sizeof (&c)); + z += memcmp (x, &c, sizeof (&c) + 0); + z += memcmp (x, &c, 0 + sizeof (&c)); + + return z; +} + +template <int N> +int +f4 (char *x, char **y, int z) +{ + const char *s1 = "foobarbaz"; + const char *s2 = "abcde12345678"; + strncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + strncat (x, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + y[0] = strndup (s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + + // These are correct, no warning. + const char s3[] = "foobarbaz"; + const char s4[] = "abcde12345678"; + strncpy (x, s3, sizeof (s3)); + strncat (x, s4, sizeof (s4)); + y[1] = strndup (s3, sizeof (s3)); + z += strncmp (s3, s4, sizeof (s3)); + z += strncmp (s3, s4, sizeof (s4)); + z += strncasecmp (s3, s4, sizeof (s3)); + z += strncasecmp (s3, s4, sizeof (s4)); + + return z; +} + +int +f (void *x, char *y, int z, X w, char **u) +{ + z += f1<0> (x, z); + z += f2<0> (x, z); + z += f3<0> (x, y, z, w); + z += f4<0> (y, u, z); + return z; +} + +// { dg-prune-output "\[\n\r\]*will always overflow\[\n\r\]*" } diff --git a/gcc/testsuite/g++.dg/torture/pr54735.C b/gcc/testsuite/g++.dg/torture/pr54735.C new file mode 100644 index 000000000..0604ec517 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr54735.C @@ -0,0 +1,179 @@ +// { dg-do compile } + +class Gmpfr +{}; +class M : Gmpfr +{ +public: + Gmpfr infconst; + M(int); +}; +template<typename>struct A; +template<typename, int, int, int = 0 ? : 0, int = 0, int = 0>class N; +template<typename>class O; +template<typename>struct B; +struct C +{ + enum + { value }; +}; +class D +{ +public: + enum + { ret }; +}; +struct F +{ + enum + { ret = 0 ? : 0 }; +}; +template<typename Derived>struct G +{ + typedef O<Derived>type; +}; +struct H +{ + void operator * (); +}; +struct I +{ + enum + { RequireInitialization = C::value ? : 0, ReadCost }; +}; +template<typename Derived>struct J +{ + enum + { ret = A<Derived>::InnerStrideAtCompileTime }; +}; +template<typename Derived>struct K +{ + enum + { ret = A<Derived>::OuterStrideAtCompileTime }; +}; +template<typename Derived>class P : H +{ +public: + using H::operator *; + typedef typename A<Derived>::Scalar Scalar; + enum + { RowsAtCompileTime = + A<Derived>::RowsAtCompileTime, ColsAtCompileTime = + A<Derived>::ColsAtCompileTime, SizeAtCompileTime = + F::ret, MaxRowsAtCompileTime = + A<Derived>::MaxRowsAtCompileTime, MaxColsAtCompileTime = + A<Derived>::MaxColsAtCompileTime, MaxSizeAtCompileTime = + F::ret, Flags = + A<Derived>::Flags ? : 0 ? : 0, CoeffReadCost = + A<Derived>::CoeffReadCost, InnerStrideAtCompileTime = + J<Derived>::ret, OuterStrideAtCompileTime = K<Derived>::ret }; + B<Derived> operator << (const Scalar&); +}; + +template<typename Derived>class O : public P<Derived> +{}; + +template<int _Cols>class L +{ +public: + + int cols() + { + return _Cols; + } +}; +template<typename Derived>class Q : public G<Derived>::type +{ +public: + typedef typename G<Derived>::type Base; + typedef typename A<Derived>::Index Index; + typedef typename A<Derived>::Scalar Scalar; + L<Base::ColsAtCompileTime> m_storage; + Index cols() + { + return m_storage.cols(); + } + + Scalar& coeffRef(Index, + Index); +}; + +template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, + int _MaxCols>struct A<N<_Scalar, _Rows, _Cols, _Options, _MaxRows, + _MaxCols> > +{ + typedef _Scalar Scalar; + typedef int Index; + enum + { RowsAtCompileTime, ColsAtCompileTime = + _Cols, MaxRowsAtCompileTime, MaxColsAtCompileTime, Flags = + D::ret, CoeffReadCost = + I::ReadCost, InnerStrideAtCompileTime, OuterStrideAtCompileTime = + 0 ? : 0 }; +}; +template<typename _Scalar, int, int _Cols, int, int, + int>class N : public Q<N<_Scalar, 0, _Cols> > +{ +public: + Q<N> Base; + template<typename T0, typename T1>N(const T0&, + const T1&); +}; +void +__assert_fail(int) +throw() __attribute__((__noreturn__)); +template<typename XprType>struct B +{ + typedef typename XprType::Scalar Scalar; + typedef typename XprType::Index Index; + B(XprType & p1, const Scalar &) : m_xpr(p1), m_col(), + m_currentBlockRows(1) + {} B& operator, (const Scalar&) + { + Index a; + + if (m_col == m_xpr.cols()) + { + m_col = 0; + m_currentBlockRows = 1; + a && "Too " ? static_cast<void>(0) : __assert_fail(0); + } + m_col < m_xpr.cols() + && "Too " ? static_cast<void>(0) : __assert_fail(1); + m_currentBlockRows ? static_cast<void>(0) : __assert_fail(4); + m_xpr.coeffRef(0, m_col++) = 0; + return *this; + } + ~B() + { + 1 + m_currentBlockRows && m_col + && "Too " ? static_cast<void>(0) : __assert_fail(0); + } + + XprType& m_xpr; + Index m_col; + Index m_currentBlockRows; +}; + +template<typename Derived>B<Derived>P< + Derived >::operator << (const Scalar&) +{ + return B<Derived>(*static_cast<Derived *>(this), 0); +} + +template<class NT, int s>void + check_() +{ + N<NT, 0, s>m(0, 0); + m << 0, 0, 0, 0; +} + +template<class NT>void check() +{ + check_<NT, 3>(); +} + +int main() +{ + check<M>(); +} |