This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


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

[PATCH][BZ 17979][BZ 17721] Fix issues with sys/cdefs.h and uchar.h when using non-gcc compiler.


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  <dwight.guth@runtimeverification.com>

	[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 "<uchar.h> 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;



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