From patchwork Thu Jan 28 20:20:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dwight Guth X-Patchwork-Id: 10661 Received: (qmail 99423 invoked by alias); 28 Jan 2016 20:20:20 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 99126 invoked by uid 89); 28 Jan 2016 20:20:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.8 required=5.0 tests=BAYES_50, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.2 spammy=292, 69, 11, 6911, H*r:sk:server3 X-HELO: server316.webhostingpad.com Message-ID: <27c31890079f41775175b94a4abedb0c.squirrel@server316.webhostingpad.com> Date: Thu, 28 Jan 2016 14:20:10 -0600 Subject: [PATCH][BZ 17979][BZ 17721] Fix issues with sys/cdefs.h and uchar.h when using non-gcc compiler. From: "Dwight Guth" To: libc-alpha@sourceware.org User-Agent: SquirrelMail/1.5.2 [SVN] MIME-Version: 1.0 X-Get-Message-Sender-Via: server316.webhostingpad.com: authenticated_id: dwight.guth@runtimeverification.com If linking against Glibc with a compiler for which the __GNUC__ macro is not defined, problems arise when including header files that use the __restrict or __inline keyword and when including uchar.h. Glibc strips __restrict from the prototypes of C library functions in this case. This is incorrect if the compiler is a C99-compliant compiler, because C99 includes the restrict keyword and uses it in the declaration of a number of functions in the C library. This leads to undefined behavior because the definitions of those functions were defined with the restrict keyword, which makes their type signatures incompatible with their declaration, a violation of C99 sec. 6.2.7 paragraph 2. The same thing occurs with the __inline keyword, which, while not undefined behavior per-se, seems undesirable in cases where the compiler is C99-compliant and therefore includes the inline keyword. Here we except the case where the compiler declares itself to be C99-compliant from these checks in order to allow better C99 compliance for compilers other than gcc which link against Glibc. Glibc defines char16_t and char32_t in uchar.h as __CHAR16_TYPE__ and __CHAR32_TYPE__ when the __GNUC__ macro is defined, but when linking against Glibc with a different compiler, these types are not defined at all, which is a violation of C11 sec. 7.28 paragraph 2, as well as a syntax error because these types are used in the prototypes of functions declared later in the file. According to this section of the standard, these types must be defined in this header file and must be the same type as uint_least16_t and uint_least32_t, which are defined in stdint.h as "unsigned short int" and "unsigned int" respectively. Here we modify the header so that if __GNUC__ is not defined, we still provide these typedefs, but we default them manually to the same type as uint_least16_t and uint_least32_t if __CHAR16_TYPE__ and __CHAR32_TYPE__ are not defined by the compiler. ----- I had trouble testing this patch because I ran into unrelated errors in the test suite. If someone could help me figure out how to set up a test environment that is likely to pass all the tests, I can try again, but I don't have the resources to struggle with all the errors that arise without knowing their solutions. The patch should not affect any version of GCC, however. ----- 2016-01-28 Dwight Guth [BZ 17979] * wcsmbs/uchar.h (char16_t, char32_t): Define types if __GNUC__, __CHAR16_TYPE__, or __CHAR32_TYPE__ are not defined. [BZ 17721] * misc/sys/cdefs.h (__restrict, __inline): Define as keywords if __GNUC__ is not defined but __STDC_VERSION__ is at least C99. ----- diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h index 7fd4154..af23ff7 100644 --- a/misc/sys/cdefs.h +++ b/misc/sys/cdefs.h @@ -69,8 +69,11 @@ #else /* Not GCC. */ -# define __inline /* No inline functions. */ - +# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +# define __inline inline +# else +# define __inline /* No inline functions. */ +# endif # define __THROW # define __THROWNL # define __NTH(fct) fct @@ -360,7 +363,11 @@ /* __restrict is known in EGCS 1.2 and above. */ #if !__GNUC_PREREQ (2,92) -# define __restrict /* Ignore */ +# if !defined __GNUC__ && defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +# define __restrict restrict +# else +# define __restrict /* Ignore */ +# endif #endif /* ISO C99 also allows to declare arrays as non-overlapping. The syntax is diff --git a/wcsmbs/uchar.h b/wcsmbs/uchar.h index ce92b25..1484e56 100644 --- a/wcsmbs/uchar.h +++ b/wcsmbs/uchar.h @@ -39,14 +39,16 @@ __END_NAMESPACE_C99 #endif -#if defined __GNUC__ && !defined __USE_ISOCXX11 +#if !defined __USE_ISOCXX11 /* Define the 16-bit and 32-bit character types. Use the information provided by the compiler. */ # if !defined __CHAR16_TYPE__ || !defined __CHAR32_TYPE__ # if defined __STDC_VERSION__ && __STDC_VERSION__ < 201000L # error " requires ISO C11 mode" # else -# error "definitions of __CHAR16_TYPE__ and/or __CHAR32_TYPE__ missing" +/* Same as uint_least16_t and uint_least32_t in stdint.h. */ +typedef unsigned short int __CHAR16_TYPE__; +typedef unsigned int __CHAR32_TYPE__; # endif # endif typedef __CHAR16_TYPE__ char16_t;