Skip to content

Commit 922b7b8

Browse files
authored
[Clang][OpenMP] Fix stdio.h wrapper when glibc includes again (#77017)
Since D154036 landed (2a65d03 on July 7, 2023), I've been seeing many (40-50) libomptarget test failures with errors like the following on some of our test systems: ``` /auto/software/gcc/x86_64/gcc-11.1.0/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../include/c++/11.1.0/cstdio:99:11: error: no member named 'fpos_t' in the global namespace 99 | using ::fpos_t; | ~~^ ``` This patch fixes that and doesn't break our other test sytems. I've looked through the glibc history and at LLVM's libc stdio.h to give me confidence that this solution should work on other systems. Of course, there might be use cases I've overlooked, so feedback is appreciated.
1 parent fc18b13 commit 922b7b8

File tree

1 file changed

+31
-3
lines changed
  • clang/lib/Headers/llvm_libc_wrappers

1 file changed

+31
-3
lines changed

clang/lib/Headers/llvm_libc_wrappers/stdio.h

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,41 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#ifndef __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__
10-
#define __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__
11-
129
#if !defined(_OPENMP) && !defined(__HIP__) && !defined(__CUDA__)
1310
#error "This file is for GPU offloading compilation only"
1411
#endif
1512

1613
#include_next <stdio.h>
1714

15+
// In some old versions of glibc, other standard headers sometimes define
16+
// special macros (e.g., __need_FILE) before including stdio.h to cause stdio.h
17+
// to produce special definitions. Future includes of stdio.h when those
18+
// special macros are undefined are expected to produce the normal definitions
19+
// from stdio.h.
20+
//
21+
// We do not apply our include guard (__CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__)
22+
// unconditionally to the above include_next. Otherwise, after an occurrence of
23+
// the first glibc stdio.h use case described above, the include_next would be
24+
// skipped for remaining includes of stdio.h, leaving required symbols
25+
// undefined.
26+
//
27+
// We make the following assumptions to handle all use cases:
28+
//
29+
// 1. If the above include_next produces special glibc definitions, then (a) it
30+
// does not produce the normal definitions that we must intercept below, (b)
31+
// the current file was included from a glibc header that already defined
32+
// __GLIBC__ (usually by including glibc's <features.h>), and (c) the above
33+
// include_next does not define _STDIO_H. In that case, we skip the rest of
34+
// the current file and don't guard against future includes.
35+
// 2. If the above include_next produces the normal stdio.h definitions, then
36+
// either (a) __GLIBC__ is not defined because C headers are from some other
37+
// libc implementation or (b) the above include_next defines _STDIO_H to
38+
// prevent the above include_next from having any effect in the future.
39+
#if !defined(__GLIBC__) || defined(_STDIO_H)
40+
41+
#ifndef __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__
42+
#define __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__
43+
1844
#if __has_include(<llvm-libc-decls/stdio.h>)
1945

2046
#if defined(__HIP__) || defined(__CUDA__)
@@ -50,3 +76,5 @@
5076
#endif
5177

5278
#endif // __CLANG_LLVM_LIBC_WRAPPERS_STDIO_H__
79+
80+
#endif

0 commit comments

Comments
 (0)