From: Andy Lester Date: Thu, 19 May 2005 12:32:56 +0000 (-0500) Subject: Attribute configuration X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=0dbb1585a715e56312e579a5f0e7f82241b38352;p=p5sagit%2Fp5-mst-13.2.git Attribute configuration Message-ID: <20050519173256.GA29039@petdance.com> p4raw-id: //depot/perl@24508 --- diff --git a/Configure b/Configure index e3dc44f..3e62682 100755 --- a/Configure +++ b/Configure @@ -339,7 +339,13 @@ d_aintl='' d_alarm='' asctime_r_proto='' d_asctime_r='' -d_attribut='' +d_attribute_format='' +d_attribute_malloc='' +d_attribute_nonnull='' +d_attribute_noreturn='' +d_attribute_pure='' +d_attribute_unused='' +d_attribute_warn_unused_result='' d_bcmp='' d_bcopy='' d_bzero='' @@ -9878,21 +9884,21 @@ eval $inlibc set atoll d_atoll eval $inlibc -: Look for GNU-cc style attribute checking -case "$d_attribut" in +: Look for GCC-style attribute format +case "$d_attribute_format" in '') echo " " -echo "Checking whether your compiler can handle __attribute__ ..." >&4 +echo "Checking whether your compiler can handle __attribute__((format)) ..." >&4 $cat >attrib.c <<'EOCP' #include -void croak (char* pat,...) __attribute__((__format__(__printf__,1,2),noreturn)); +void my_special_printf(char* pat,...) __attribute__((__format__(__printf__,1,2))); EOCP if $cc $ccflags -c attrib.c >attrib.out 2>&1 ; then if $contains 'warning' attrib.out >/dev/null 2>&1; then - echo "Your C compiler doesn't fully support __attribute__." + echo "Your C compiler doesn't support __attribute__((format))." val="$undef" else - echo "Your C compiler supports __attribute__." + echo "Your C compiler supports __attribute__((format))." val="$define" fi else @@ -9900,9 +9906,177 @@ else val="$undef" fi ;; -*) val="$d_attribut" ;; +*) val="$d_attribute_format" ;; esac -set d_attribut +set d_attribute_format +eval $setvar +$rm -f attrib* + +: Look for GCC-style attribute malloc +case "$d_attribute_malloc" in +'') +echo " " +echo "Checking whether your compiler can handle __attribute__((malloc)) ..." >&4 +$cat >attrib.c <<'EOCP' +#include +char *go_get_some_memory( int how_many_bytes ) __attribute__((malloc)); +EOCP +if $cc $ccflags -c attrib.c >attrib.out 2>&1 ; then + if $contains 'warning' attrib.out >/dev/null 2>&1; then + echo "Your C compiler doesn't support __attribute__((malloc))." + val="$undef" + else + echo "Your C compiler supports __attribute__((malloc))." + val="$define" + fi +else + echo "Your C compiler doesn't seem to understand __attribute__ at all." + val="$undef" +fi +;; +*) val="$d_attribute_malloc" ;; +esac +set d_attribute_malloc +eval $setvar +$rm -f attrib* + +: Look for GCC-style attribute nonnull +case "$d_attribute_nonnull" in +'') +echo " " +echo "Checking whether your compiler can handle __attribute__((nonnull(1))) ..." >&4 +$cat >attrib.c <<'EOCP' +#include +void do_something (char *some_pointer,...) __attribute__((nonnull(1))); +EOCP +if $cc $ccflags -c attrib.c >attrib.out 2>&1 ; then + if $contains 'warning' attrib.out >/dev/null 2>&1; then + echo "Your C compiler doesn't support __attribute__((nonnull))." + val="$undef" + else + echo "Your C compiler supports __attribute__((nonnull))." + val="$define" + fi +else + echo "Your C compiler doesn't seem to understand __attribute__ at all." + val="$undef" +fi +;; +*) val="$d_attribute_nonnull" ;; +esac +set d_attribute_nonnull +eval $setvar +$rm -f attrib* + +: Look for GCC-style attribute noreturn +case "$d_attribute_noreturn" in +'') +echo " " +echo "Checking whether your compiler can handle __attribute__((noreturn)) ..." >&4 +$cat >attrib.c <<'EOCP' +#include +void fall_over_dead( void ) __attribute__((noreturn)); +EOCP +if $cc $ccflags -c attrib.c >attrib.out 2>&1 ; then + if $contains 'warning' attrib.out >/dev/null 2>&1; then + echo "Your C compiler doesn't support __attribute__((noreturn))." + val="$undef" + else + echo "Your C compiler supports __attribute__((noreturn))." + val="$define" + fi +else + echo "Your C compiler doesn't seem to understand __attribute__ at all." + val="$undef" +fi +;; +*) val="$d_attribute_noreturn" ;; +esac +set d_attribute_noreturn +eval $setvar +$rm -f attrib* + +: Look for GCC-style attribute pure +case "$d_attribute_pure" in +'') +echo " " +echo "Checking whether your compiler can handle __attribute__((pure)) ..." >&4 +$cat >attrib.c <<'EOCP' +#include +int square( int n ) __attribute__((pure)); +EOCP +if $cc $ccflags -c attrib.c >attrib.out 2>&1 ; then + if $contains 'warning' attrib.out >/dev/null 2>&1; then + echo "Your C compiler doesn't support __attribute__((pure))." + val="$undef" + else + echo "Your C compiler supports __attribute__((pure))." + val="$define" + fi +else + echo "Your C compiler doesn't seem to understand __attribute__ at all." + val="$undef" +fi +;; +*) val="$d_attribute_pure" ;; +esac +set d_attribute_pure +eval $setvar +$rm -f attrib* + +: Look for GCC-style attribute unused +case "$d_attribute_unused" in +'') +echo " " +echo "Checking whether your compiler can handle __attribute__((unused)) ..." >&4 +$cat >attrib.c <<'EOCP' +#include +int do_something( int dummy __attribute__((unused)), int n ); +EOCP +if $cc $ccflags -c attrib.c >attrib.out 2>&1 ; then + if $contains 'warning' attrib.out >/dev/null 2>&1; then + echo "Your C compiler doesn't support __attribute__((unused))." + val="$undef" + else + echo "Your C compiler supports __attribute__((unused))." + val="$define" + fi +else + echo "Your C compiler doesn't seem to understand __attribute__ at all." + val="$undef" +fi +;; +*) val="$d_attribute_unused" ;; +esac +set d_attribute_unused +eval $setvar +$rm -f attrib* + +: Look for GCC-style attribute warn_unused_result +case "$d_attribute_warn_unused_result" in +'') +echo " " +echo "Checking whether your compiler can handle __attribute__((warn_unused_result)) ..." >&4 +$cat >attrib.c <<'EOCP' +#include +int I_will_not_be_ignored(void) __attribute__((warn_unused_result)); +EOCP +if $cc $ccflags -c attrib.c >attrib.out 2>&1 ; then + if $contains 'warning' attrib.out >/dev/null 2>&1; then + echo "Your C compiler doesn't support __attribute__((warn_unused_result))." + val="$undef" + else + echo "Your C compiler supports __attribute__((warn_unused_result))." + val="$define" + fi +else + echo "Your C compiler doesn't seem to understand __attribute__ at all." + val="$undef" +fi +;; +*) val="$d_attribute_warn_unused_result" ;; +esac +set d_attribute_warn_unused_result eval $setvar $rm -f attrib* @@ -20631,7 +20805,13 @@ d_archlib='$d_archlib' d_asctime_r='$d_asctime_r' d_atolf='$d_atolf' d_atoll='$d_atoll' -d_attribut='$d_attribut' +d_attribute_format='$d_attribute_format' +d_attribute_malloc='$d_attribute_malloc' +d_attribute_nonnull='$d_attribute_nonnull' +d_attribute_noreturn='$d_attribute_noreturn' +d_attribute_pure='$d_attribute_pure' +d_attribute_unused='$d_attribute_unused' +d_attribute_warn_unused_result='$d_attribute_warn_unused_result' d_bcmp='$d_bcmp' d_bcopy='$d_bcopy' d_bsd='$d_bsd' diff --git a/Cross/config.sh-arm-linux b/Cross/config.sh-arm-linux index afe4d48..6b7e992 100644 --- a/Cross/config.sh-arm-linux +++ b/Cross/config.sh-arm-linux @@ -111,7 +111,13 @@ d_archlib='define' d_asctime_r='undef' d_atolf='undef' d_atoll='define' -d_attribut='define' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='define' d_bcopy='define' d_bsd='undef' diff --git a/NetWare/config.wc b/NetWare/config.wc index 7ea7b1e..8808b8c 100644 --- a/NetWare/config.wc +++ b/NetWare/config.wc @@ -97,7 +97,13 @@ d_archlib='define' d_asctime_r='undef' d_atolf='undef' d_atoll='undef' -d_attribut='undef' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='undef' d_bcopy='undef' d_bsd='define' diff --git a/Porting/Glossary b/Porting/Glossary index 41eec75..99b8e34 100644 --- a/Porting/Glossary +++ b/Porting/Glossary @@ -406,10 +406,42 @@ d_atoll (atoll.U): This variable conditionally defines the HAS_ATOLL symbol, which indicates to the C program that the atoll() routine is available. -d_attribut (d_attribut.U): - This variable conditionally defines HASATTRIBUTE, which - indicates the C compiler can check for function attributes, - such as printf formats. +d_attribute_format (d_attribut_format.U): + This variable conditionally defines HASATTRIBUTE_FORMAT, which + indicates the C compiler can check for printf-like formats. + +d_attribute_malloc (d_attribute_malloc.U): + This variable conditionally defines HASATTRIBUTE_MALLOC, which + indicates the C compiler can understand functions as having + malloc-like semantics. + +d_attribute_nonnull (d_attribute_nonnull.U): + This variable conditionally defines HASATTRIBUTE_NONNULL, which + indicates that the C compiler can know that certain arguments + must not be NULL, and will check accordingly at compile time. + +d_attribute_noreturn (d_attribute_noreturn.U): + This variable conditionally defines HASATTRIBUTE_NORETURN, which + indicates that the C compiler can know that certain functions + are guaranteed never to return. + +d_attribute_pure (d_attribute_pure.U): + This variable conditionally defines HASATTRIBUTE_PURE, which + indicates that the C compiler can know that certain functions + are "pure" functions, meaning that they have no side effects, and + only rely on function input and/or global data for their results. + +d_attribute_unused (d_attribute_unused.U): + This variable conditionally defines HASATTRIBUTE_UNUSED, which + indicates that the C compiler can know that certain variables + and arguments may not always be used, and to not throw warnings + if they don't get used. + +d_attribute_warn_unused_result (d_attribute_warn_unused_result.U): + This variable conditionally defines + HASATTRIBUTE_WARN_UNUSED_RESULT, which indicates that the C + compiler can know that certain functions have a return values + that must not be ignored, such as malloc() or open(). d_bcmp (d_bcmp.U): This variable conditionally defines the HAS_BCMP symbol if diff --git a/Porting/config.sh b/Porting/config.sh index 006c38d..2b208fb 100644 --- a/Porting/config.sh +++ b/Porting/config.sh @@ -111,7 +111,13 @@ d_archlib='define' d_asctime_r='undef' d_atolf='undef' d_atoll='define' -d_attribut='define' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='define' d_bcopy='define' d_bsd='undef' diff --git a/Porting/pumpkin.pod b/Porting/pumpkin.pod index ff1e5bd..37e68f8 100644 --- a/Porting/pumpkin.pod +++ b/Porting/pumpkin.pod @@ -711,45 +711,6 @@ branches. =head2 Other tests -=over 4 - -=item CHECK_FORMAT - -If you have gcc, you can test the correct use of printf-style -arguments. Run C with S<-Dccflags='-DCHECK_FORMAT --Wformat'> (and S<-Dcc=gcc>, if you are not on a system where C -is C) and run C. The compiler will produce warnings of -incorrect use of format arguments. - -As of change 23767, CHECK_FORMAT changes perl-defined formats -to obscure (but standard) formats, and then traps the obscure -format. The resulting perl executable operates properly but -you should not use the executable produced by this process. - -=over 4 - -=item * - -A more accurate approach is the following commands: - - make clean - make all OPTIMIZE='-DCHECK_FORMAT -Wformat' >& make.log - perl -nwe 'print if /^\S+:/ and not /^make\b/' make.log - -=item * - -A more thorough approach to compiler warnings is - - make clean - make miniperl OPTIMIZE=-O\ -DCHECK_FORMAT >& make.log - make all OPTIMIZE=-O\ -DCHECK_FORMAT\ -Wall\ -Wno-unused\ - -Wno-uninitialized >>& make.log - perl -nwe 'print if /^\S+:/ and not /^make\b/' make.log - -=back - -(-Wformat support by Robin Barker.) - =item gcc -ansi -pedantic Configure -Dgccansipedantic [ -Dcc=gcc ] will enable (via the cflags script, diff --git a/XSUB.h b/XSUB.h index 8997778..b59a95f 100644 --- a/XSUB.h +++ b/XSUB.h @@ -92,8 +92,8 @@ is a lexical $_ in scope. # define XS(name) EXPORT_C void name(pTHX_ CV* cv) #endif #ifndef XS -# if defined(HASATTRIBUTE) -# define XS(name) void name(pTHX_ CV* cv __attribute__((unused))) +# ifdef HASATTRIBUTE_UNUSED +# define XS(name) void name(pTHX_ CV* cv __attribute__unused__) # else # define XS(name) void name(pTHX_ CV* cv) # endif diff --git a/config_h.SH b/config_h.SH index da368ce..78f262d 100644 --- a/config_h.SH +++ b/config_h.SH @@ -3727,17 +3727,40 @@ sed <$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un #define M_VOID /* Xenix strikes again */ #endif -/* HASATTRIBUTE: - * This symbol indicates the C compiler can check for function attributes, - * such as printf formats. This is normally only supported by GNU cc. - */ -#$d_attribut HASATTRIBUTE /**/ -#ifndef HASATTRIBUTE -#ifdef __attribute__ -#undef __attribute__ -#endif -#define __attribute__(_arg_) -#endif +/* HASATTRIBUTE_FORMAT: + * Can we handle GCC attribute for checking printf-style formats + */ +#$d_attribute_format HASATTRIBUTE_FORMAT /**/ + +/* HASATTRIBUTE_MALLOC: + * Can we handle GCC attribute for malloc-style functions. + */ +#$d_attribute_malloc HASATTRIBUTE_MALLOC /**/ + +/* HASATTRIBUTE_NONNULL: + * Can we handle GCC attribute for nonnull function parms. + */ +#$d_attribute_nonnull HASATTRIBUTE_NONNULL /**/ + +/* HASATTRIBUTE_NORETURN: + * Can we handle GCC attribute for functions that do not return + */ +#$d_attribute_noreturn HASATTRIBUTE_NORETURN /**/ + +/* HASATTRIBUTE_PURE: + * Can we handle GCC attribute for pure functions + */ +#$d_attribute_pure HASATTRIBUTE_PURE /**/ + +/* HASATTRIBUTE_UNUSED: + * Can we handle GCC attribute for unused variables and arguments + */ +#$d_attribute_unused HASATTRIBUTE_UNUSED /**/ + +/* HASATTRIBUTE_WARN_UNUSED_RESULT: + * Can we handle GCC attribute for warning on unused results + */ +#$d_attribute_warn_unused_result HASATTRIBUTE_WARN_UNUSED_RESULT /**/ /* HAS_CRYPT: * This symbol, if defined, indicates that the crypt routine is available diff --git a/configure.com b/configure.com index e306ff4..bccbf2f 100644 --- a/configure.com +++ b/configure.com @@ -5417,7 +5417,13 @@ $ WC "d_alarm='define'" $ WC "d_archlib='define'" $ WC "d_atolf='" + d_atolf + "'" $ WC "d_atoll='" + d_atoll + "'" -$ WC "d_attribut='" + d_attribut + "'" +$ WC "d_attribute_format='" + d_attribut + "'" +$ WC "d_attribute_malloc='undef'" +$ WC "d_attribute_nonnull='undef'" +$ WC "d_attribute_noreturn='undef'" +$ WC "d_attribute_pure='undef'" +$ WC "d_attribute_unused='undef'" +$ WC "d_attribute_warn_unused_result='undef'" $ WC "d_bcmp='" + d_bcmp + "'" $ WC "d_bcopy='" + d_bcopy + "'" $ WC "d_bincompat3='undef'" diff --git a/epoc/config.sh b/epoc/config.sh index 6dd7077..9553265 100644 --- a/epoc/config.sh +++ b/epoc/config.sh @@ -103,7 +103,13 @@ d_archlib='define' d_asctime_r='undef' d_atolf='undef' d_atoll='undef' -d_attribut='undef' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='define' d_bcopy='define' d_bsd='undef' diff --git a/hints/next_3_0.sh b/hints/next_3_0.sh index b444578..06d122a 100644 --- a/hints/next_3_0.sh +++ b/hints/next_3_0.sh @@ -16,7 +16,7 @@ echo find it. By default, it is placed in /usr/local/include/gdbm.h. >&4 echo It will not be found there. Try moving it to >&4 echo /NextDeveloper/Headers/bsd/gdbm.h. >&4 -ccflags="$ccflags -DUSE_NEXT_CTYPE -DNEXT30_NO_ATTRIBUTE" +ccflags="$ccflags -DUSE_NEXT_CTYPE" POSIX_cflags='ccflags="-posix $ccflags"' useposix='undef' ldflags="$ldflags -u libsys_s" @@ -51,3 +51,11 @@ d_setpgid='undef' # (Thanks to Andreas Koenig ) ranlib='sleep 5; /bin/ranlib' +# Doesn't support attributes, so we'll set that here. +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' diff --git a/hints/vmesa.sh b/hints/vmesa.sh index 5fad22b..bda26fc 100644 --- a/hints/vmesa.sh +++ b/hints/vmesa.sh @@ -25,7 +25,13 @@ d_alarm='define' d_archlib='define' # randbits='15' archobjs="vmesa.o" -d_attribut='undef' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='define' d_bcopy='define' d_bsd='undef' diff --git a/malloc.c b/malloc.c index 1ff10be..affe763 100644 --- a/malloc.c +++ b/malloc.c @@ -409,7 +409,7 @@ # ifndef pTHX # define pTHX void # define pTHX_ -# ifdef HASATTRIBUTE +# ifdef HASATTRIBUTE_UNUSED # define dTHX extern int Perl___notused PERL_UNUSED_DECL # else # define dTHX extern int Perl___notused diff --git a/mg.c b/mg.c index baad04f..1611d1f 100644 --- a/mg.c +++ b/mg.c @@ -468,12 +468,7 @@ Perl_magic_regdatum_set(pTHX_ SV *sv, MAGIC *mg) { (void)sv; (void)mg; Perl_croak(aTHX_ PL_no_modify); - /* NOT REACHED */ -#ifndef HASATTRIBUTE_NORETURN - /* No __attribute__((noreturn)), so the compiler doesn't know that - * croak never returns. */ - return 0; -#endif + NORETURN_FUNCTION_END; } U32 diff --git a/op.c b/op.c index 5f36c57..dc70613 100644 --- a/op.c +++ b/op.c @@ -4899,11 +4899,7 @@ Perl_oopsCV(pTHX_ OP *o) Perl_croak(aTHX_ "NOT IMPL LINE %d",__LINE__); /* STUB */ (void)o; -#ifndef HASATTRIBUTE_NORETURN - /* No __attribute__((noreturn)), so the compiler doesn't know that - * croak never returns. */ - return 0; -#endif + NORETURN_FUNCTION_END; } OP * diff --git a/perl.c b/perl.c index 5f38e64..c6e5ee3 100644 --- a/perl.c +++ b/perl.c @@ -1006,14 +1006,10 @@ perl_free(pTHXx) #pragma fini "perl_fini" #endif -#if defined(__GNUC__) && defined(__attribute__) -/* want to make sure __attribute__ works here even - * for -Dd_attribut=undef builds. - */ -#undef __attribute__ +static void +#if defined(__GNUC__) +__attribute__((destructor)) #endif - -static void __attribute__((destructor)) perl_fini(void) { dVAR; diff --git a/perl.h b/perl.h index 1a2145c..54a6d3e 100644 --- a/perl.h +++ b/perl.h @@ -190,27 +190,7 @@ #define CALLREG_INTUIT_STRING CALL_FPTR(PL_regint_string) #define CALLREGFREE CALL_FPTR(PL_regfree) -#if defined(SYMBIAN) && defined(__GNUC__) -# undef __attribute__ -# undef __attribute__(_arg_) -# define HASATTRIBUTE -#endif - -#ifdef HASATTRIBUTE -# if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER) -# define PERL_UNUSED_DECL -# else -# define PERL_UNUSED_DECL __attribute__((unused)) -# endif -#else -# define PERL_UNUSED_DECL -#endif - -#if defined(SYMBIAN) && defined(__GNUC__) -# undef __attribute__ -# undef __attribute__(_arg_) -# define HASATTRIBUTE -#endif +#define PERL_UNUSED_DECL __attribute__unused__ /* gcc -Wall: * for silencing unused variables that are actually used most of the time, @@ -2550,20 +2530,17 @@ typedef pthread_key_t perl_key; # define PERL_SET_THX(t) PERL_SET_CONTEXT(t) #endif +/* This replaces the previous %_ "hack" by the "%-p" hack + All that is required is that the perl source does not + use "%-p" or "%-p" format. These format will + still work in perl code. RMB 2005/05/17 +*/ #ifndef SVf -# ifdef CHECK_FORMAT -# define SVf "-p" -# else -# define SVf "_" -# endif +# define SVf "-p" #endif #ifndef SVf_precision -# ifdef CHECK_FORMAT -# define SVf_precision(n) "-" n "p" -# else -# define SVf_precision(n) "." n "_" -# endif +# define SVf_precision(n) "-" n "p" #endif #ifndef SVf32 @@ -2579,41 +2556,66 @@ typedef pthread_key_t perl_key; #endif #ifndef DieNull -# ifdef CHECK_FORMAT -# define DieNull Perl_vdie(aTHX_ Nullch, Null(va_list *)) -# else -# define DieNull Perl_die(aTHX_ Nullch) +# define DieNull Perl_vdie(aTHX_ Nullch, Null(va_list *)) +#endif + +/* In case Configure was not used (we are using a "canned config" + * such as Win32, or a cross-compilation setup, for example) try going + * by the gcc major and minor versions. One useful URL is + * http://www.ohse.de/uwe/articles/gcc-attributes.html, + * but contrary to this information warn_unused_result seems + * not to be in gcc 3.3.5, at least. --jhi */ +#if defined __GNUC__ +# if __GNUC__ >= 3 /* 3.0 -> */ /* XXX Verify this version */ +# define HASATTRIBUTE_FORMAT # endif -#endif - -#ifndef __attribute__format__ -# ifdef CHECK_FORMAT -# define __attribute__format__(x,y,z) __attribute__((format(x,y,z))) -# else -# define __attribute__format__(x,y,z) +# if __GNUC__ >= 3 /* 3.0 -> */ +# define HASATTRIBUTE_MALLOC +# endif +# if __GNUC__ == 3 && __GNUC_MINOR__ >= 3 || __GNUC__ > 3 /* 3.3 -> */ +# define HASATTRIBUTE_NONNULL +# endif +# if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 || __GNUC__ > 2 /* 2.5 -> */ +# define HASATTRIBUTE_NORETURN +# endif +# if __GNUC__ >= 3 /* gcc 3.0 -> */ +# define HASATTRIBUTE_PURE +# endif +# if __GNUC__ >= 3 /* gcc 3.0 -> */ /* XXX Verify this version */ +# define HASATTRIBUTE_UNUSED +# endif +# if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 || __GNUC__ > 3 /* 3.4 -> */ +# define HASATTRIBUTE_WARN_UNUSED_RESULT # endif #endif -/* See http://www.ohse.de/uwe/articles/gcc-attributes.html, but - * contrary to the information warn_unused_result seems not to be in - * gcc 3.3.5, at least. --jhi */ -#if __GNUC__ >= 3 +#ifdef HASATTRIBUTE_FORMAT +# define __attribute__format__(x,y,z) __attribute__((format(x,y,z))) +#endif +#ifdef HASATTRIBUTE_MALLOC # define __attribute__malloc__ __attribute__((malloc)) #endif -#if __GNUC__ == 3 && __GNUC_MINOR__ >= 3 || __GNUC__ > 3 +#ifdef HASATTRIBUTE_NONNULL # define __attribute__nonnull__(a) __attribute__((nonnull(a))) #endif -#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 || __GNUC__ > 2 +#ifdef HASATTRIBUTE_NORETURN # define __attribute__noreturn__ __attribute__((noreturn)) #endif -#if __GNUC__ >= 3 +#ifdef HASATTRIBUTE_PURE # define __attribute__pure__ __attribute__((pure)) #endif -#if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 || __GNUC__ > 3 +#ifdef HASATTRIBUTE_UNUSED +# define __attribute__unused__ __attribute__((unused)) +#endif +#ifdef HASATTRIBUTE_WARN_UNUSED_RESULT # define __attribute__warn_unused_result__ __attribute__((warn_unused_result)) #endif +/* If we haven't defined the attributes yet, define them to blank. */ +#ifndef __attribute__format__ +# define __attribute__format__(x,y,z) +#endif #ifndef __attribute__malloc__ # define __attribute__malloc__ #endif @@ -2626,12 +2628,20 @@ typedef pthread_key_t perl_key; #ifndef __attribute__pure__ # define __attribute__pure__ #endif +#ifndef __attribute__unused__ +# define __attribute__unused__ +#endif #ifndef __attribute__warn_unused_result__ # define __attribute__warn_unused_result__ #endif -#if defined(HASATTRIBUTE) && __GNUC__ >= 3 -# define HASATTRIBUTE_NORETURN +/* For functions that are marked as __attribute__noreturn__, it's not + appropriate to call return. In either case, include the lint directive. + */ +#ifdef HASATTRIBUTE_NORETURN +# define NORETURN_FUNCTION_END /* NOT REACHED */ +#else +# define NORETURN_FUNCTION_END /* NOT REACHED */ return 0 #endif /* Some unistd.h's give a prototype for pause() even though @@ -3928,16 +3938,6 @@ struct tempsym; /* defined in pp_pack.c */ #ifndef PERL_CALLCONV # define PERL_CALLCONV #endif - -#ifndef NEXT30_NO_ATTRIBUTE -# ifndef HASATTRIBUTE /* disable GNU-cc attribute checking? */ -# ifdef __attribute__ /* Avoid possible redefinition errors */ -# undef __attribute__ -# endif -# define __attribute__(attr) -# endif -#endif - #undef PERL_CKDEF #undef PERL_PPDEF #define PERL_CKDEF(s) OP *s (pTHX_ OP *o); diff --git a/perlio.h b/perlio.h index 9183948..3022282 100644 --- a/perlio.h +++ b/perlio.h @@ -210,19 +210,7 @@ PERL_EXPORT_C void PerlIO_clone(pTHX_ PerlInterpreter *proto, START_EXTERN_C #ifndef __attribute__format__ -# ifdef CHECK_FORMAT -# define __attribute__format__(x,y,z) __attribute__((format(x,y,z))) -# else -# define __attribute__format__(x,y,z) -#endif -#endif -#ifndef NEXT30_NO_ATTRIBUTE -#ifndef HASATTRIBUTE /* disable GNU-cc attribute checking? */ -#ifdef __attribute__ /* Avoid possible redefinition errors */ -#undef __attribute__ -#endif -#define __attribute__(attr) -#endif +# define __attribute__format__(x,y,z) __attribute__((format(x,y,z))) #endif #ifndef PerlIO_init PERL_EXPORT_C void PerlIO_init(pTHX); diff --git a/plan9/config_sh.sample b/plan9/config_sh.sample index bf78b38..9ac6eb6 100644 --- a/plan9/config_sh.sample +++ b/plan9/config_sh.sample @@ -111,7 +111,13 @@ d_archlib='define' d_asctime_r='undef' d_atolf='undef' d_atoll='define' -d_attribut='undef' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='define' d_bcopy='define' d_bsd='undef' diff --git a/plan9/genconfig.pl b/plan9/genconfig.pl index d934659..30f4af7 100644 --- a/plan9/genconfig.pl +++ b/plan9/genconfig.pl @@ -118,7 +118,13 @@ EndOfIntro # Plan 9 compiler stuff print OUT "cc='pcc'\n"; -print OUT "d_attribut='undef'\n"; +print OUT "d_attribute_format='undef'\n"; +print OUT "d_attribute_malloc='undef'\n"; +print OUT "d_attribute_nonnull='undef'\n"; +print OUT "d_attribute_noreturn='undef'\n"; +print OUT "d_attribute_pure='undef'\n"; +print OUT "d_attribute_unused='undef'\n"; +print OUT "d_attribute_warn_unused_result='undef'\n"; print OUT "d_socket='define'\n"; print OUT "d_sockpair='define'\n"; print OUT "d_sigsetjmp='define'\n"; diff --git a/scope.c b/scope.c index 085ed16..50258df 100644 --- a/scope.c +++ b/scope.c @@ -469,11 +469,7 @@ Perl_save_threadsv(pTHX_ PADOFFSET i) { Perl_croak(aTHX_ "panic: save_threadsv called in non-threaded perl"); (void)i; -#ifndef HASATTRIBUTE_NORETURN - /* No __attribute__((noreturn)), so the compiler doesn't know that - * croak never returns. */ - return 0; -#endif + NORETURN_FUNCTION_END; } void diff --git a/sv.c b/sv.c index 799cf52..66b07e2 100644 --- a/sv.c +++ b/sv.c @@ -9222,12 +9222,10 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV /* no matter what, this is a string now */ (void)SvPV_force(sv, origlen); - /* special-case "", "%s", and "%_" */ + /* special-case "", "%s", and "%-p" (SVf) */ if (patlen == 0) return; - if (patlen == 2 && pat[0] == '%') { - switch (pat[1]) { - case 's': + if (patlen == 2 && pat[0] == '%' && pat[1] == 's') { if (args) { const char *s = va_arg(*args, char*); sv_catpv(sv, s ? s : nullstr); @@ -9238,7 +9236,9 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV SvUTF8_on(sv); } return; - case '_': + } + if (patlen == 3 && pat[0] == '%' && + pat[1] == '-' && pat[2] == 'p') { if (args) { argsv = va_arg(*args, SV*); sv_catsv(sv, argsv); @@ -9246,9 +9246,6 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV SvUTF8_on(sv); return; } - /* See comment on '_' below */ - break; - } } #ifndef USE_LONG_DOUBLE @@ -9626,23 +9623,6 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV is_utf8 = TRUE; } } - goto string; - - case '_': -#ifdef CHECK_FORMAT - format_sv: -#endif - /* - * The "%_" hack might have to be changed someday, - * if ISO or ANSI decide to use '_' for something. - * So we keep it hidden from users' code. - */ - if (!args || vectorize) - goto unknown; - argsv = va_arg(*args, SV*); - eptr = SvPVx(argsv, elen); - if (DO_UTF8(argsv)) - is_utf8 = TRUE; string: vectorize = FALSE; @@ -9653,17 +9633,21 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV /* INTEGERS */ case 'p': -#ifdef CHECK_FORMAT - if (left) { + if (left && args) { /* SVf */ left = FALSE; - if (!width) - goto format_sv; /* %-p -> %_ */ - precis = width; - has_precis = TRUE; - width = 0; - goto format_sv; /* %-Np -> %.N_ */ + if (width) { + precis = width; + has_precis = TRUE; + width = 0; + } + if (vectorize) + goto unknown; + argsv = va_arg(*args, SV*); + eptr = SvPVx(argsv, elen); + if (DO_UTF8(argsv)) + is_utf8 = TRUE; + goto string; } -#endif if (alt || vectorize) goto unknown; uv = PTR2UV(args ? va_arg(*args, void*) : argsv); diff --git a/symbian/config.sh b/symbian/config.sh index 1c1fa01..c0ef96b 100644 --- a/symbian/config.sh +++ b/symbian/config.sh @@ -51,7 +51,13 @@ d_archlib='define' d_asctime_r='undef' d_atolf='undef' d_atoll='undef' -d_attribut='undef' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='undef' d_bcopy='undef' d_bsd='undef' diff --git a/t/op/sprintf.t b/t/op/sprintf.t index c854588..90ac8a7 100755 --- a/t/op/sprintf.t +++ b/t/op/sprintf.t @@ -323,6 +323,7 @@ __END__ >%+o< >642< >1202< >%#o< >642< >01202< >%d< >$p=sprintf('%p',$p);$p=~/^[0-9a-f]+$/< >1< >Coarse hack: hex from %p?< +>%d< >$p=sprintf('%-8p',$p);$p=~/^[0-9a-f]+\s*$/< >1< >Coarse hack: hex from %p?< >%#p< >''< >%#p INVALID< >%q< >''< >%q INVALID< >%r< >''< >%r INVALID< diff --git a/uconfig.sh b/uconfig.sh index 87be639..28b0c3e 100755 --- a/uconfig.sh +++ b/uconfig.sh @@ -40,7 +40,13 @@ d_archlib='undef' d_asctime_r='undef' d_atolf='undef' d_atoll='undef' -d_attribut='undef' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='undef' d_bcopy='undef' d_bsd='undef' diff --git a/vms/genconfig.pl b/vms/genconfig.pl index 2794a17..6e9df70 100644 --- a/vms/genconfig.pl +++ b/vms/genconfig.pl @@ -140,7 +140,14 @@ foreach (@ARGV) { $d_attr = 'undef'; } print OUT "vms_cc_type='$cctype'\n"; - print OUT "d_attribut='$d_attr'\n"; + print OUT "d_attribute_format='$d_attr'\n"; + # XXX The following attributes may be able to use $d_attr, too. + print OUT "d_attribute_malloc='undef'\n"; + print OUT "d_attribute_nonnull='undef'\n"; + print OUT "d_attribute_noreturn='undef'\n"; + print OUT "d_attribute_pure='undef'\n"; + print OUT "d_attribute_unused='undef'\n"; + print OUT "d_attribute_warn_unused_result='undef'\n"; print OUT "cc='$cc'\n"; if ( ($cctype eq 'decc' and $archsufx eq 'VAX') || $cctype eq 'gcc') { # gcc and DECC for VAX requires filename in /object qualifier, so we diff --git a/win32/config.bc b/win32/config.bc index fe78757..5434b33 100644 --- a/win32/config.bc +++ b/win32/config.bc @@ -99,7 +99,13 @@ d_archlib='define' d_asctime_r='undef' d_atolf='undef' d_atoll='undef' -d_attribut='undef' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='undef' d_bcopy='undef' d_bsd='define' diff --git a/win32/config.gc b/win32/config.gc index d1432dd..f86a4a5 100644 --- a/win32/config.gc +++ b/win32/config.gc @@ -99,7 +99,13 @@ d_archlib='define' d_asctime_r='undef' d_atolf='undef' d_atoll='undef' -d_attribut='define' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='undef' d_bcopy='undef' d_bsd='define' diff --git a/win32/config.vc b/win32/config.vc index 0eeb4b7..0baf3f5 100644 --- a/win32/config.vc +++ b/win32/config.vc @@ -99,7 +99,13 @@ d_archlib='define' d_asctime_r='undef' d_atolf='undef' d_atoll='undef' -d_attribut='undef' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='undef' d_bcopy='undef' d_bsd='define' diff --git a/win32/config.vc64 b/win32/config.vc64 index c2548f1..c45b6bf 100644 --- a/win32/config.vc64 +++ b/win32/config.vc64 @@ -99,7 +99,13 @@ d_archlib='define' d_asctime_r='undef' d_atolf='undef' d_atoll='define' -d_attribut='undef' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='undef' d_bcopy='undef' d_bsd='define' diff --git a/wince/config.ce b/wince/config.ce index 2f63f5b..ff53bdd 100644 --- a/wince/config.ce +++ b/wince/config.ce @@ -97,7 +97,13 @@ d_archlib='define' d_asctime_r='undef' d_atolf='undef' d_atoll='undef' -d_attribut='undef' +d_attribute_format='undef' +d_attribute_malloc='undef' +d_attribute_nonnull='undef' +d_attribute_noreturn='undef' +d_attribute_pure='undef' +d_attribute_unused='undef' +d_attribute_warn_unused_result='undef' d_bcmp='undef' d_bcopy='undef' d_bsd='define'