[PATCH] D43908: [RecordLayout] Only assert that fundamental type sizes are power of two on MSVC

2018-03-01 Thread Martin Storsjö via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326476: [RecordLayout] Only assert that fundamental type 
sizes are power of two on MSVC (authored by mstorsjo, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D43908?vs=136471=136583#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43908

Files:
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
  cfe/trunk/test/CodeGen/ms_struct-long-double.c


Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
===
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
@@ -759,6 +759,10 @@
   Warning<"ms_struct may not produce Microsoft-compatible layouts for classes "
   "with base classes or virtual functions">,
   DefaultError, InGroup;
+def warn_npot_ms_struct :
+  Warning<"ms_struct may not produce Microsoft-compatible layouts with 
fundamental "
+  "data types with sizes that aren't a power of two">,
+  DefaultError, InGroup;
 def err_section_conflict : Error<"%0 causes a section type conflict with %1">;
 def err_no_base_classes : Error<"invalid use of '__super', %0 has no base 
classes">;
 def err_invalid_super_scope : Error<"invalid use of '__super', "
Index: cfe/trunk/test/CodeGen/ms_struct-long-double.c
===
--- cfe/trunk/test/CodeGen/ms_struct-long-double.c
+++ cfe/trunk/test/CodeGen/ms_struct-long-double.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple i686-windows-gnu 
-fdump-record-layouts %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm-only -triple i686-linux -fdump-record-layouts 
-Wno-incompatible-ms-struct %s | FileCheck %s
+// RUN: not %clang_cc1 -emit-llvm-only -triple i686-linux 
-fdump-record-layouts %s 2>&1 | FileCheck %s -check-prefix=ERROR
+
+struct ldb_struct {
+  char c;
+  long double ldb;
+} __attribute__((__ms_struct__));
+
+struct ldb_struct a;
+
+// CHECK: 0 | struct ldb_struct
+// CHECK-NEXT:0 |   char c
+// CHECK-NEXT:4 |   long double ldb
+// CHECK-NEXT:  | [sizeof=16, align=4]
+
+// ERROR: error: ms_struct may not produce Microsoft-compatible layouts with 
fundamental data types with sizes that aren't a power of two
Index: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
===
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
@@ -1752,10 +1752,32 @@
   QualType T = Context.getBaseElementType(D->getType());
   if (const BuiltinType *BTy = T->getAs()) {
 CharUnits TypeSize = Context.getTypeSizeInChars(BTy);
-assert(
-(llvm::isPowerOf2_64(TypeSize.getQuantity()) ||
- Context.getTargetInfo().getTriple().isWindowsGNUEnvironment()) &&
-"Non PowerOf2 size outside of GNU mode");
+
+if (!llvm::isPowerOf2_64(TypeSize.getQuantity())) {
+  assert(
+  !Context.getTargetInfo().getTriple().isWindowsMSVCEnvironment() 
&&
+  "Non PowerOf2 size in MSVC mode");
+  // Base types with sizes that aren't a power of two don't work
+  // with the layout rules for MS structs. This isn't an issue in
+  // MSVC itself since there are no such base data types there.
+  // On e.g. x86_32 mingw and linux, long double is 12 bytes though.
+  // Any structs involving that data type obviously can't be ABI
+  // compatible with MSVC regardless of how it is laid out.
+
+  // Since ms_struct can be mass enabled (via a pragma or via the
+  // -mms-bitfields command line parameter), this can trigger for
+  // structs that don't actually need MSVC compatibility, so we
+  // need to be able to sidestep the ms_struct layout for these types.
+
+  // Since the combination of -mms-bitfields together with structs
+  // like max_align_t (which contains a long double) for mingw is
+  // quite comon (and GCC handles it silently), just handle it
+  // silently there. For other targets that have ms_struct enabled
+  // (most probably via a pragma or attribute), trigger a diagnostic
+  // that defaults to an error.
+  if (!Context.getTargetInfo().getTriple().isWindowsGNUEnvironment())
+Diag(D->getLocation(), diag::warn_npot_ms_struct);
+}
 if (TypeSize > FieldAlign &&
 llvm::isPowerOf2_64(TypeSize.getQuantity()))
   FieldAlign = TypeSize;


Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
===
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
@@ -759,6 +759,10 @@
   

[PATCH] D43908: [RecordLayout] Only assert that fundamental type sizes are power of two on MSVC

2018-03-01 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd accepted this revision.
compnerd added a comment.

Awesome, thanks, this makes me feel much more comfortable.


https://reviews.llvm.org/D43908



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43908: [RecordLayout] Only assert that fundamental type sizes are power of two on MSVC

2018-03-01 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo updated this revision to Diff 136471.
mstorsjo edited the summary of this revision.
mstorsjo added a comment.

Added an error-by-default diagnostic (just like the existing 
warn_cxx_ms_struct) for this case, trigger it on all targets other than mingw 
(where the situation is quite likely to occur, and GCC handles it silently).

@compnerd, do you like this better?


https://reviews.llvm.org/D43908

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/AST/RecordLayoutBuilder.cpp
  test/CodeGen/ms_struct-long-double.c


Index: test/CodeGen/ms_struct-long-double.c
===
--- /dev/null
+++ test/CodeGen/ms_struct-long-double.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple i686-windows-gnu 
-fdump-record-layouts %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm-only -triple i686-linux -fdump-record-layouts 
-Wno-incompatible-ms-struct %s | FileCheck %s
+// RUN: not %clang_cc1 -emit-llvm-only -triple i686-linux 
-fdump-record-layouts %s 2>&1 | FileCheck %s -check-prefix=ERROR
+
+struct ldb_struct {
+  char c;
+  long double ldb;
+} __attribute__((__ms_struct__));
+
+struct ldb_struct a;
+
+// CHECK: 0 | struct ldb_struct
+// CHECK-NEXT:0 |   char c
+// CHECK-NEXT:4 |   long double ldb
+// CHECK-NEXT:  | [sizeof=16, align=4]
+
+// ERROR: error: ms_struct may not produce Microsoft-compatible layouts with 
fundamental data types with sizes that aren't a power of two
Index: lib/AST/RecordLayoutBuilder.cpp
===
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -1752,10 +1752,32 @@
   QualType T = Context.getBaseElementType(D->getType());
   if (const BuiltinType *BTy = T->getAs()) {
 CharUnits TypeSize = Context.getTypeSizeInChars(BTy);
-assert(
-(llvm::isPowerOf2_64(TypeSize.getQuantity()) ||
- Context.getTargetInfo().getTriple().isWindowsGNUEnvironment()) &&
-"Non PowerOf2 size outside of GNU mode");
+
+if (!llvm::isPowerOf2_64(TypeSize.getQuantity())) {
+  assert(
+  !Context.getTargetInfo().getTriple().isWindowsMSVCEnvironment() 
&&
+  "Non PowerOf2 size in MSVC mode");
+  // Base types with sizes that aren't a power of two don't work
+  // with the layout rules for MS structs. This isn't an issue in
+  // MSVC itself since there are no such base data types there.
+  // On e.g. x86_32 mingw and linux, long double is 12 bytes though.
+  // Any structs involving that data type obviously can't be ABI
+  // compatible with MSVC regardless of how it is laid out.
+
+  // Since ms_struct can be mass enabled (via a pragma or via the
+  // -mms-bitfields command line parameter), this can trigger for
+  // structs that don't actually need MSVC compatibility, so we
+  // need to be able to sidestep the ms_struct layout for these types.
+
+  // Since the combination of -mms-bitfields together with structs
+  // like max_align_t (which contains a long double) for mingw is
+  // quite comon (and GCC handles it silently), just handle it
+  // silently there. For other targets that have ms_struct enabled
+  // (most probably via a pragma or attribute), trigger a diagnostic
+  // that defaults to an error.
+  if (!Context.getTargetInfo().getTriple().isWindowsGNUEnvironment())
+Diag(D->getLocation(), diag::warn_npot_ms_struct);
+}
 if (TypeSize > FieldAlign &&
 llvm::isPowerOf2_64(TypeSize.getQuantity()))
   FieldAlign = TypeSize;
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -759,6 +759,10 @@
   Warning<"ms_struct may not produce Microsoft-compatible layouts for classes "
   "with base classes or virtual functions">,
   DefaultError, InGroup;
+def warn_npot_ms_struct :
+  Warning<"ms_struct may not produce Microsoft-compatible layouts with 
fundamental "
+  "data types with sizes that aren't a power of two">,
+  DefaultError, InGroup;
 def err_section_conflict : Error<"%0 causes a section type conflict with %1">;
 def err_no_base_classes : Error<"invalid use of '__super', %0 has no base 
classes">;
 def err_invalid_super_scope : Error<"invalid use of '__super', "


Index: test/CodeGen/ms_struct-long-double.c
===
--- /dev/null
+++ test/CodeGen/ms_struct-long-double.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple i686-windows-gnu -fdump-record-layouts %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm-only -triple i686-linux -fdump-record-layouts -Wno-incompatible-ms-struct %s | FileCheck 

[PATCH] D43908: [RecordLayout] Only assert that fundamental type sizes are power of two on MSVC

2018-02-28 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd accepted this revision.
compnerd added a comment.

Ugh, really not a fan of this change.


Repository:
  rC Clang

https://reviews.llvm.org/D43908



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43908: [RecordLayout] Only assert that fundamental type sizes are power of two on MSVC

2018-02-28 Thread Eli Friedman via Phabricator via cfe-commits
efriedma accepted this revision.
efriedma added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rC Clang

https://reviews.llvm.org/D43908



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43908: [RecordLayout] Only assert that fundamental type sizes are power of two on MSVC

2018-02-28 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo created this revision.
mstorsjo added reviewers: efriedma, compnerd.

This fixes using the ms_struct attribute together with long double on e.g. 
x86-32 linux.


Repository:
  rC Clang

https://reviews.llvm.org/D43908

Files:
  lib/AST/RecordLayoutBuilder.cpp
  test/CodeGen/ms_struct-long-double.c


Index: test/CodeGen/ms_struct-long-double.c
===
--- /dev/null
+++ test/CodeGen/ms_struct-long-double.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple i686-windows-gnu 
-fdump-record-layouts %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm-only -triple i686-linux -fdump-record-layouts %s 
| FileCheck %s
+
+struct ldb_struct {
+  char c;
+  long double ldb;
+} __attribute__((__ms_struct__));
+
+struct ldb_struct a;
+
+// CHECK: 0 | struct ldb_struct
+// CHECK-NEXT:0 |   char c
+// CHECK-NEXT:4 |   long double ldb
+// CHECK-NEXT:  | [sizeof=16, align=4]
Index: lib/AST/RecordLayoutBuilder.cpp
===
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -1754,8 +1754,8 @@
 CharUnits TypeSize = Context.getTypeSizeInChars(BTy);
 assert(
 (llvm::isPowerOf2_64(TypeSize.getQuantity()) ||
- Context.getTargetInfo().getTriple().isWindowsGNUEnvironment()) &&
-"Non PowerOf2 size outside of GNU mode");
+ !Context.getTargetInfo().getTriple().isWindowsMSVCEnvironment()) 
&&
+"Non PowerOf2 size in MSVC mode");
 if (TypeSize > FieldAlign &&
 llvm::isPowerOf2_64(TypeSize.getQuantity()))
   FieldAlign = TypeSize;


Index: test/CodeGen/ms_struct-long-double.c
===
--- /dev/null
+++ test/CodeGen/ms_struct-long-double.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple i686-windows-gnu -fdump-record-layouts %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm-only -triple i686-linux -fdump-record-layouts %s | FileCheck %s
+
+struct ldb_struct {
+  char c;
+  long double ldb;
+} __attribute__((__ms_struct__));
+
+struct ldb_struct a;
+
+// CHECK: 0 | struct ldb_struct
+// CHECK-NEXT:0 |   char c
+// CHECK-NEXT:4 |   long double ldb
+// CHECK-NEXT:  | [sizeof=16, align=4]
Index: lib/AST/RecordLayoutBuilder.cpp
===
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -1754,8 +1754,8 @@
 CharUnits TypeSize = Context.getTypeSizeInChars(BTy);
 assert(
 (llvm::isPowerOf2_64(TypeSize.getQuantity()) ||
- Context.getTargetInfo().getTriple().isWindowsGNUEnvironment()) &&
-"Non PowerOf2 size outside of GNU mode");
+ !Context.getTargetInfo().getTriple().isWindowsMSVCEnvironment()) &&
+"Non PowerOf2 size in MSVC mode");
 if (TypeSize > FieldAlign &&
 llvm::isPowerOf2_64(TypeSize.getQuantity()))
   FieldAlign = TypeSize;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits