]> granicus.if.org Git - clang/commitdiff
Fix interaction of max_align_t and modules.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 3 Oct 2014 00:31:35 +0000 (00:31 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 3 Oct 2014 00:31:35 +0000 (00:31 +0000)
When building with modules enabled, we were defining max_align_t as a typedef
for a different anonymous struct type each time it was included, resulting in
an error if <stddef.h> is not covered by a module map and is included more than
once in the same modules-enabled compilation of C11 or C++11 code.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218931 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Headers/CMakeLists.txt
lib/Headers/__stddef_max_align_t.h [new file with mode: 0644]
lib/Headers/module.modulemap
lib/Headers/stddef.h
test/Headers/c11.c
test/Modules/Inputs/StdDef/include_again.h [new file with mode: 0644]
test/Modules/Inputs/StdDef/module.map
test/Modules/Inputs/StdDef/ptrdiff_t.h [new file with mode: 0644]
test/Modules/stddef.c [new file with mode: 0644]
test/Modules/system_headers.m

index d23e2122e31370e520e1c89ec7a6fbccc47151f2..f5457807857c9c95ff25684fd0dee42f8fb5db4e 100644 (file)
@@ -35,6 +35,7 @@ set(files
   stdarg.h
   stdbool.h
   stddef.h
+  __stddef_max_align_t.h
   stdint.h
   stdnoreturn.h
   tbmintrin.h
diff --git a/lib/Headers/__stddef_max_align_t.h b/lib/Headers/__stddef_max_align_t.h
new file mode 100644 (file)
index 0000000..a06f412
--- /dev/null
@@ -0,0 +1,40 @@
+/*===---- __stddef_max_align_t.h - Definition of max_align_t for modules ---===
+ *
+ * Copyright (c) 2014 Chandler Carruth
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __CLANG_MAX_ALIGN_T_DEFINED
+#define __CLANG_MAX_ALIGN_T_DEFINED
+
+#ifndef _MSC_VER
+typedef struct {
+  long long __clang_max_align_nonce1
+      __attribute__((__aligned__(__alignof__(long long))));
+  long double __clang_max_align_nonce2
+      __attribute__((__aligned__(__alignof__(long double))));
+} max_align_t;
+#else
+typedef double max_align_t;
+#endif
+
+#endif
index 93e4d65b8f15b399212ed6d388d1bec148e676ec..3c42477405bebea062a047d0d283cc46cecde0e7 100644 (file)
@@ -170,3 +170,7 @@ module _Builtin_intrinsics [system] {
     }
   }
 }
+
+module _Builtin_stddef_max_align_t [system] [extern_c] {
+  header "__stddef_max_align_t.h"
+}
index 2dfe0a29b2a2cd328e5cca9501c0a1bfe7a18129..7354996711562306fa77f3c7a95655f40df8d183 100644 (file)
 #if !defined(__need_ptrdiff_t) && !defined(__need_size_t) &&                   \
     !defined(__need_wchar_t) && !defined(__need_NULL) &&                       \
     !defined(__need_wint_t)
+/* Always define miscellaneous pieces when modules are available. */
+#if !__has_feature(modules)
 #define __STDDEF_H
+#endif
 #define __need_ptrdiff_t
 #define __need_size_t
 #define __need_wchar_t
 #define __need_NULL
+#define __need_STDDEF_H_misc
 /* __need_wint_t is intentionally not defined here. */
 #endif
 
@@ -60,7 +64,7 @@ typedef __SIZE_TYPE__ size_t;
 #undef __need_size_t
 #endif /*defined(__need_size_t) */
 
-#if defined(__STDDEF_H)
+#if defined(__need_STDDEF_H_misc)
 /* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is
  * enabled. */
 #if (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 && \
@@ -71,7 +75,7 @@ typedef __SIZE_TYPE__ size_t;
 #endif
 typedef __SIZE_TYPE__ rsize_t;
 #endif
-#endif /* defined(__STDDEF_H) */
+#endif /* defined(__need_STDDEF_H_misc) */
 
 #if defined(__need_wchar_t)
 #ifndef __cplusplus
@@ -109,26 +113,13 @@ using ::std::nullptr_t;
 #undef __need_NULL
 #endif /* defined(__need_NULL) */
 
-#if defined(__STDDEF_H)
-
+#if defined(__need_STDDEF_H_misc)
 #if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
-#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) || __has_feature(modules)
-#ifndef _MSC_VER
-typedef struct {
-  long long __clang_max_align_nonce1
-      __attribute__((__aligned__(__alignof__(long long))));
-  long double __clang_max_align_nonce2
-      __attribute__((__aligned__(__alignof__(long double))));
-} max_align_t;
-#else
-typedef double max_align_t;
+#include "__stddef_max_align_t.h"
 #endif
-#define __CLANG_MAX_ALIGN_T_DEFINED
-#endif
-#endif
-
 #define offsetof(t, d) __builtin_offsetof(t, d)
-#endif  /* __STDDEF_H */
+#undef __need_STDDEF_H_misc
+#endif  /* defined(__need_STDDEF_H_misc) */
 
 /* Some C libraries expect to see a wint_t here. Others (notably MinGW) will use
 __WINT_TYPE__ directly; accommodate both by requiring __need_wint_t */
index b7b15011f3ceedeedfd9b7b01114d5f5a5cbc224..6594823c273346552a21ef51d7bf0f3a501e6de2 100644 (file)
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -fmodules -fmodules-cache-path=%t %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -fmodules -fmodules-cache-path=%t %s -D__STDC_WANT_LIB_EXT1__=1
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -ffreestanding %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -triple i686-pc-win32 -fms-compatibility-version=17.00 %s
 
diff --git a/test/Modules/Inputs/StdDef/include_again.h b/test/Modules/Inputs/StdDef/include_again.h
new file mode 100644 (file)
index 0000000..f29f636
--- /dev/null
@@ -0,0 +1,2 @@
+#include <stddef.h>
+
index 69c69eac35b51611a3e8b7298b570787c49ef3d4..5c4e0dae7ba6a93cbf539b0aa29216dbe820ba68 100644 (file)
@@ -8,4 +8,14 @@ module StdDef {
     header "other.h"
     export *
   }
+
+  module PtrDiffT {
+    header "ptrdiff_t.h"
+    export *
+  }
+
+  module IncludeAgain {
+    header "include_again.h"
+    export *
+  }
 }
diff --git a/test/Modules/Inputs/StdDef/ptrdiff_t.h b/test/Modules/Inputs/StdDef/ptrdiff_t.h
new file mode 100644 (file)
index 0000000..acb0ab8
--- /dev/null
@@ -0,0 +1,2 @@
+#define __need_ptrdiff_t
+#include <stddef.h>
diff --git a/test/Modules/stddef.c b/test/Modules/stddef.c
new file mode 100644 (file)
index 0000000..aefc90f
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify -fno-modules-error-recovery
+
+#include "ptrdiff_t.h"
+
+ptrdiff_t pdt;
+
+size_t st; // expected-error {{must be imported}}
+// expected-note@stddef.h:* {{previous}}
+
+#include "include_again.h"
+
+size_t st2;
index 39b13ca5fc4a13752eaf5d7111d98bebdf1ac04e..8adc7e857699b283685f8d845fa6b7d61dccd22b 100644 (file)
@@ -1,8 +1,13 @@
 // Test that system-headerness works for building modules.
 
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -isystem %S/Inputs -pedantic -Werror %s -verify
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -isystem %S/Inputs -pedantic -Werror %s -verify -std=c11
 // expected-no-diagnostics
 
 @import warning;
 int i = bigger_than_int;
+
+#include <stddef.h>
+
+#define __need_size_t
+#include <stddef.h>