https://github.com/DanShaders updated https://github.com/llvm/llvm-project/pull/71148
>From 1033441efd9e790bdb027824ffa1986cd09c06f2 Mon Sep 17 00:00:00 2001 From: Dan Klishch <danilklis...@gmail.com> Date: Fri, 3 Nov 2023 21:18:06 -0400 Subject: [PATCH 1/7] [clang] Stub out gcc_struct attribute This commit implements gcc_struct attribute with the behavior similar to one in GCC. Current behavior is as follows: When C++ ABI is not "Microsoft" (i. e. when ItaniumRecordLayoutBuilder is used), [[gcc_struct]] will locally cancel the effect of -mms-bitfields on a record. If -mms-bitfields is not supplied and is not a default behavior on a target, [[gcc_struct]] will be a no-op. This should provide enough compatibility with GCC. If C++ ABI is "Microsoft", [[gcc_struct]] will currently always produce a diagnostic, since support for it is not yet implemented in MicrosoftRecordLayoutBuilder. Note, however, that all the infrastructure is ready for the future implementation. In particular, check for default value of -mms-bitfields is moved from a driver to TargetInfo, since it now non-trivially depends on other supplied flags. Also this, unfortunately, makes it impossible to use usual argument parsing for `-m{no-,}ms-bitfields`. The patch doesn't introduce any backwards-incompatible changes, except for situations when cc1 is called directly with `-mms-bitfields` option. --- clang/include/clang/Basic/Attr.td | 7 +++++ clang/include/clang/Basic/LangOptions.def | 1 - clang/include/clang/Basic/LangOptions.h | 2 ++ clang/include/clang/Basic/TargetInfo.h | 4 +++ clang/include/clang/Driver/Options.td | 4 +-- clang/lib/AST/Decl.cpp | 7 ++++- clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 5 +--- clang/lib/Driver/ToolChains/Clang.cpp | 10 ++++--- clang/lib/Frontend/CompilerInvocation.cpp | 12 +++++++++ clang/lib/Sema/SemaDecl.cpp | 4 +-- clang/lib/Sema/SemaDeclCXX.cpp | 27 ++++++++++++------- clang/test/Driver/ms-bitfields.c | 11 +++++--- clang/test/Layout/itanium-union-bitfield.cpp | 2 +- ...a-attribute-supported-attributes-list.test | 1 + 14 files changed, 69 insertions(+), 28 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 1800f584c7e1088..0d7e44d783bcc39 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3671,6 +3671,13 @@ def MSStruct : InheritableAttr { let SimpleHandler = 1; } +def GCCStruct : InheritableAttr { + let Spellings = [GCC<"gcc_struct">]; + let Subjects = SubjectList<[Record]>; + let Documentation = [Undocumented]; + let SimpleHandler = 1; +} + def DLLExport : InheritableAttr, TargetSpecificAttr<TargetHasDLLImportExport> { let Spellings = [Declspec<"dllexport">, GCC<"dllexport">]; let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>; diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index c3d5399905a3fda..5b0869a792d8785 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -149,7 +149,6 @@ LANGOPT(AssumeNothrowExceptionDtor , 1, 0, "Assume exception object's destructor LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation") LANGOPT(RTTI , 1, 1, "run-time type information") LANGOPT(RTTIData , 1, 1, "emit run-time type information data") -LANGOPT(MSBitfields , 1, 0, "Microsoft-compatible structure layout") LANGOPT(MSVolatile , 1, 0, "Microsoft-compatible volatile loads and stores") LANGOPT(Freestanding, 1, 0, "freestanding implementation") LANGOPT(NoBuiltin , 1, 0, "disable builtin functions") diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 2d167dd2bdf1287..162929b90730b0e 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -507,6 +507,8 @@ class LangOptions : public LangOptionsBase { // implementation on real-world examples. std::string OpenACCMacroOverride; + std::optional<bool> MSBitfields; + LangOptions(); /// Set language defaults for the given input language and diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 41f3c2e403cbef6..fc9555cf29cec7b 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1738,6 +1738,10 @@ class TargetInfo : public TransferrableTargetInfo, /// Whether to support HIP image/texture API's. virtual bool hasHIPImageSupport() const { return true; } + virtual bool defaultsToMsStruct() const { + return getCXXABI().isMicrosoft() || getTriple().isWindowsGNUEnvironment(); + } + protected: /// Copy type and layout related info. void copyAuxTarget(const TargetInfo *Aux); diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 9689f12fd01417b..ffad856e1fd8781 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4426,8 +4426,7 @@ def : Joined<["-"], "mmacosx-version-min=">, Group<m_Group>, Alias<mmacos_version_min_EQ>; def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard">, - MarshallingInfoFlag<LangOpts<"MSBitfields">>; + HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard">; def moutline : Flag<["-"], "moutline">, Group<f_clang_Group>, Visibility<[ClangOption, CC1Option]>, HelpText<"Enable function outlining (AArch64 only)">; @@ -4435,6 +4434,7 @@ def mno_outline : Flag<["-"], "mno-outline">, Group<f_clang_Group>, Visibility<[ClangOption, CC1Option]>, HelpText<"Disable function outlining (AArch64 only)">; def mno_ms_bitfields : Flag<["-"], "mno-ms-bitfields">, Group<m_Group>, + Visibility<[ClangOption, CC1Option]>, HelpText<"Do not set the default structure layout to be compatible with the Microsoft compiler standard">; def mskip_rax_setup : Flag<["-"], "mskip-rax-setup">, Group<m_Group>, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index c5c2edf1bfe3aba..25201995925322e 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -5031,7 +5031,12 @@ void RecordDecl::completeDefinition() { /// This which can be turned on with an attribute, pragma, or the /// -mms-bitfields command-line option. bool RecordDecl::isMsStruct(const ASTContext &C) const { - return hasAttr<MSStructAttr>() || C.getLangOpts().MSBitfields == 1; + if (hasAttr<MSStructAttr>()) + return true; + if (hasAttr<GCCStructAttr>()) + return false; + return C.getLangOpts().MSBitfields.value_or( + C.getTargetInfo().defaultsToMsStruct()); } void RecordDecl::reorderDecls(const SmallVectorImpl<Decl *> &Decls) { diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index cbfa79e10bfefcc..296151c32c91c12 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -104,10 +104,7 @@ struct CGRecordLowering { /// fields of the same formal type. We want to emit a layout with /// these discrete storage units instead of combining them into a /// continuous run. - bool isDiscreteBitFieldABI() { - return Context.getTargetInfo().getCXXABI().isMicrosoft() || - D->isMsStruct(Context); - } + bool isDiscreteBitFieldABI() { return D->isMsStruct(Context); } /// Helper function to check if we are targeting AAPCS. bool isAAPCS() const { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 2d73f42772a29dc..4851a4915ece91e 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5666,9 +5666,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (KernelOrKext && RawTriple.isOSDarwin()) CmdArgs.push_back("-fforbid-guard-variables"); - if (Args.hasFlag(options::OPT_mms_bitfields, options::OPT_mno_ms_bitfields, - Triple.isWindowsGNUEnvironment())) { - CmdArgs.push_back("-mms-bitfields"); + if (Args.hasArg(options::OPT_mms_bitfields) || + Args.hasArg(options::OPT_mno_ms_bitfields)) { + if (Args.hasFlag(options::OPT_mms_bitfields, options::OPT_mno_ms_bitfields, + false)) + CmdArgs.push_back("-mms-bitfields"); + else + CmdArgs.push_back("-mno-ms-bitfields"); } if (Triple.isWindowsGNUEnvironment()) { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 5a8e4cf9843de2b..b4f48863653bcd7 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3635,6 +3635,13 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, GenerateArg(Consumer, OPT_fcxx_abi_EQ, TargetCXXABI::getSpelling(*Opts.CXXABI)); + if (Opts.MSBitfields.has_value()) { + if (Opts.MSBitfields.value()) + GenerateArg(Consumer, OPT_mms_bitfields); + else + GenerateArg(Consumer, OPT_mno_ms_bitfields); + } + if (Opts.RelativeCXXABIVTables) GenerateArg(Consumer, OPT_fexperimental_relative_cxx_abi_vtables); else @@ -4177,6 +4184,11 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, options::OPT_fno_experimental_relative_cxx_abi_vtables, TargetCXXABI::usesRelativeVTables(T)); + if (Args.hasArg(options::OPT_mms_bitfields) || + Args.hasArg(options::OPT_mno_ms_bitfields)) + Opts.MSBitfields = Args.hasFlag(options::OPT_mms_bitfields, + options::OPT_mno_ms_bitfields, false); + // RTTI is on by default. bool HasRTTI = !Args.hasArg(options::OPT_fno_rtti); Opts.OmitVTableRTTI = diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 77ff4e1df8e9c90..74e3514a3149293 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18246,9 +18246,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, // ABI. bool CStdConstraintViolation = BitfieldIsOverwide && !getLangOpts().CPlusPlus; - bool MSBitfieldViolation = - Value.ugt(TypeStorageSize) && - (IsMsStruct || Context.getTargetInfo().getCXXABI().isMicrosoft()); + bool MSBitfieldViolation = Value.ugt(TypeStorageSize) && IsMsStruct; if (CStdConstraintViolation || MSBitfieldViolation) { unsigned DiagWidth = CStdConstraintViolation ? TypeWidth : TypeStorageSize; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 7385eac48d8c895..8b2f4f13e4c09cc 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -7255,20 +7255,27 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) { CheckCompletedMemberFunction(MD); } - // ms_struct is a request to use the same ABI rules as MSVC. Check - // whether this class uses any C++ features that are implemented - // completely differently in MSVC, and if so, emit a diagnostic. - // That diagnostic defaults to an error, but we allow projects to - // map it down to a warning (or ignore it). It's a fairly common - // practice among users of the ms_struct pragma to mass-annotate - // headers, sweeping up a bunch of types that the project doesn't - // really rely on MSVC-compatible layout for. We must therefore - // support "ms_struct except for C++ stuff" as a secondary ABI. + // {ms,gcc}_struct is a request to change ABI rules to either follow + // Microsoft or Itanium C++ ABI. However, even if these attributes are + // present, we do not layout classes following foreign ABI rules, but + // instead enter a special "compatibility mode", which only changes + // alignements of fundamental types and layout of bit fields. + // Check whether this class uses any C++ features that are implemented + // completely differently in the requested ABI, and if so, emit a + // diagnostic. That diagnostic defaults to an error, but we allow + // projects to map it down to a warning (or ignore it). It's a fairly + // common practice among users of the ms_struct pragma to + // mass-annotate headers, sweeping up a bunch of types that the + // project doesn't really rely on MSVC-compatible layout for. We must + // therefore support "ms_struct except for C++ stuff" as a secondary + // ABI. // Don't emit this diagnostic if the feature was enabled as a // language option (as opposed to via a pragma or attribute), as // the option -mms-bitfields otherwise essentially makes it impossible // to build C++ code, unless this diagnostic is turned off. - if (Record->isMsStruct(Context) && !Context.getLangOpts().MSBitfields && + if (!Context.getLangOpts().MSBitfields.has_value() && + Record->isMsStruct(Context) != + Context.getTargetInfo().defaultsToMsStruct() && (Record->isPolymorphic() || Record->getNumBases())) { Diag(Record->getLocation(), diag::warn_cxx_ms_struct); } diff --git a/clang/test/Driver/ms-bitfields.c b/clang/test/Driver/ms-bitfields.c index 031ed41e2aad678..4cd3f1380e41acf 100644 --- a/clang/test/Driver/ms-bitfields.c +++ b/clang/test/Driver/ms-bitfields.c @@ -1,8 +1,13 @@ -// RUN: %clang -### -target x86_64-linux-gnu %s 2>&1 | FileCheck %s -check-prefix=NO-MSBITFIELDS -// RUN: %clang -### -target x86_64-windows-gnu %s 2>&1 | FileCheck %s -check-prefix=MSBITFIELDS +// RUN: %clang -### -target x86_64-linux-gnu %s 2>&1 | FileCheck %s -check-prefix=DEFAULT-MSBITFIELDS +// RUN: %clang -### -target x86_64-windows-gnu %s 2>&1 | FileCheck %s -check-prefix=DEFAULT-MSBITFIELDS +// RUN: %clang -### -target x86_64-windows-msvc %s 2>&1 | FileCheck %s -check-prefix=DEFAULT-MSBITFIELDS +// RUN: %clang -### -mms-bitfields %s 2>&1 | FileCheck %s -check-prefix=MSBITFIELDS +// RUN: %clang -### -mno-ms-bitfields %s 2>&1 | FileCheck %s -check-prefix=NO-MSBITFIELDS // RUN: %clang -### -mno-ms-bitfields -mms-bitfields %s 2>&1 | FileCheck %s -check-prefix=MSBITFIELDS // RUN: %clang -### -mms-bitfields -mno-ms-bitfields %s 2>&1 | FileCheck %s -check-prefix=NO-MSBITFIELDS // MSBITFIELDS: -mms-bitfields -// NO-MSBITFIELDS-NOT: -mms-bitfields +// NO-MSBITFIELDS: -mno-ms-bitfields +// DEFAULT-MSBITFIELDS-NOT: -mms-bitfields +// DEFAULT-MSBITFIELDS-NOT: -mno-ms-bitfields diff --git a/clang/test/Layout/itanium-union-bitfield.cpp b/clang/test/Layout/itanium-union-bitfield.cpp index febfc46dfee54c1..3e22fe9a3faabd3 100644 --- a/clang/test/Layout/itanium-union-bitfield.cpp +++ b/clang/test/Layout/itanium-union-bitfield.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -fdump-record-layouts %s 2>/dev/null \ +// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -mno-ms-bitfields -fdump-record-layouts %s 2>/dev/null \ // RUN: | FileCheck %s // On z/OS, a bit-field has single byte alignment. Add aligned(4) on z/OS so the union has diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index dd91f4f88ad685b..b7073cd1adde118 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -77,6 +77,7 @@ // CHECK-NEXT: FlagEnum (SubjectMatchRule_enum) // CHECK-NEXT: Flatten (SubjectMatchRule_function) // CHECK-NEXT: FunctionReturnThunks (SubjectMatchRule_function) +// CHECK-NEXT: GCCStruct (SubjectMatchRule_record) // CHECK-NEXT: GNUInline (SubjectMatchRule_function) // CHECK-NEXT: HIPManaged (SubjectMatchRule_variable) // CHECK-NEXT: Hot (SubjectMatchRule_function) >From 3bb5235c74aa149df8b95e58190d1fc3b939b6e0 Mon Sep 17 00:00:00 2001 From: Dan Klishch <danilklis...@gmail.com> Date: Mon, 13 Nov 2023 19:08:03 -0500 Subject: [PATCH 2/7] documentation and diagnostic --- clang/docs/ReleaseNotes.rst | 5 ++++ clang/include/clang/Basic/Attr.td | 4 ++-- clang/include/clang/Basic/AttrDocs.td | 23 +++++++++++++++++++ .../include/clang/Basic/DiagnosticASTKinds.td | 3 +++ clang/lib/AST/RecordLayoutBuilder.cpp | 7 ++++++ 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e4beeee0a2cb5e0..dcda86566a1c3ce 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -340,6 +340,11 @@ Attribute Changes in Clang All parameters of a function are considered to be lifetime bound if the function returns a type annotated with ``[[clang::coro_lifetimebound]]`` and ``[[clang::coro_return_type]]``. +- On targets with C++ ABI other than Microsoft, Clang now supports + ``[[gnu:gcc_struct]]`` with the behavior similar to one existing in GCC. In + particular, it locally cancels the effect of ``-mms-bitfields`` switch (either + if it is provided explicitly or if the behavior is default on a target). + Improvements to Clang's diagnostics ----------------------------------- - Clang constexpr evaluator now prints template arguments when displaying diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 0d7e44d783bcc39..26028e72a033ad3 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3667,14 +3667,14 @@ def CFGuard : InheritableAttr, TargetSpecificAttr<TargetWindows> { def MSStruct : InheritableAttr { let Spellings = [GCC<"ms_struct">]; let Subjects = SubjectList<[Record]>; - let Documentation = [Undocumented]; + let Documentation = [MSStructDocs]; let SimpleHandler = 1; } def GCCStruct : InheritableAttr { let Spellings = [GCC<"gcc_struct">]; let Subjects = SubjectList<[Record]>; - let Documentation = [Undocumented]; + let Documentation = [GCCStructDocs]; let SimpleHandler = 1; } diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index b7f366c29b77b48..4c829aaf3f3bff3 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -7659,3 +7659,26 @@ Both coroutines and coroutine wrappers are part of this analysis. .. _`CRT`: https://clang.llvm.org/docs/AttributeReference.html#coro-return-type }]; } + +def MSStructDocs : Documentation { + let Category = DocCatDecl; + let Content = [{ +The ``ms_struct`` and ``gcc_struct`` attributes request the compiler to enter a +special record layout compatibility mode which mimics the layout of Microsoft or +Itanium C++ ABI respectively. Obviously, if the current C++ ABI matches the +requested ABI, the attribute does nothing. However, if it does not, annotated +structure or class is laid out in a special compatibility mode, which slightly +changes offsets for fields and bit-fields. The intention is to match the layout +of the requested ABI for structures which only use C features. + +Note that the default behavior can be controlled by ``-mms-bitfields`` and +``-mno-ms-bitfields`` switches and via ``#pragma ms_struct``. + }]; +} + +def GCCStructDocs : Documentation { + let Category = DocCatDecl; + let Content = [{ +See ms_struct_. + }]; +} diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td index c81d17ed641084a..9d61a3285c3d5f1 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -998,6 +998,9 @@ def warn_npot_ms_struct : Warning< "data types with sizes that aren't a power of two">, DefaultError, InGroup<IncompatibleMSStruct>; +def err_itanium_layout_unimplemented : Error< + "sorry, Itanium-compatible layout is unimplemented for the current C++ ABI">; + // -Wpadded-bitfield def warn_padded_struct_bitfield : Warning< "padding %select{struct|interface|class}0 %1 with %2 " diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index a51c8b938f411c0..8ea46f680b19e70 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2795,6 +2795,13 @@ void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) { UseExternalLayout = Source->layoutRecordType( RD, External.Size, External.Align, External.FieldOffsets, External.BaseOffsets, External.VirtualBaseOffsets); + + if (!RD->isMsStruct(Context)) { + auto Location = RD->getLocation(); + if (Location.isValid()) + Context.getDiagnostics().Report(Location, + diag::err_itanium_layout_unimplemented); + } } void >From 87deadc18823054b4e8cf38ff9feabb8d4d7b38c Mon Sep 17 00:00:00 2001 From: Dan Klishch <danilklis...@gmail.com> Date: Tue, 14 Nov 2023 11:45:00 -0500 Subject: [PATCH 3/7] fixup --- clang/docs/ReleaseNotes.rst | 9 +++++---- clang/include/clang/Basic/DiagnosticASTKinds.td | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index dcda86566a1c3ce..a61150a57855cc6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -340,10 +340,11 @@ Attribute Changes in Clang All parameters of a function are considered to be lifetime bound if the function returns a type annotated with ``[[clang::coro_lifetimebound]]`` and ``[[clang::coro_return_type]]``. -- On targets with C++ ABI other than Microsoft, Clang now supports - ``[[gnu:gcc_struct]]`` with the behavior similar to one existing in GCC. In - particular, it locally cancels the effect of ``-mms-bitfields`` switch (either - if it is provided explicitly or if the behavior is default on a target). +- On targets with Itanium C++ ABI, Clang now supports ``[[gnu:gcc_struct]]`` + with the behavior similar to one existing in GCC. In particular, whenever + ``-mms-bitfields`` command line option is provided (or if Microsoft-compatible + structure layout is default on the target), ``[[gnu::gcc_struct]]`` requests + the compiler to follow Itanium rules for the layout of an annotated structure. Improvements to Clang's diagnostics ----------------------------------- diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td index 9d61a3285c3d5f1..0346b7fed8163ef 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -999,7 +999,7 @@ def warn_npot_ms_struct : Warning< DefaultError, InGroup<IncompatibleMSStruct>; def err_itanium_layout_unimplemented : Error< - "sorry, Itanium-compatible layout is unimplemented for the current C++ ABI">; + "Itanium-compatible layout for the Microsoft C++ ABI is not yet supported">; // -Wpadded-bitfield def warn_padded_struct_bitfield : Warning< >From b7d7efab31ccb0d3595cd1ea221be77647da156d Mon Sep 17 00:00:00 2001 From: Dan Klishch <danilklis...@gmail.com> Date: Tue, 14 Nov 2023 15:24:47 -0500 Subject: [PATCH 4/7] fixup --- clang/lib/Sema/SemaDeclCXX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 8b2f4f13e4c09cc..c0e76594364134e 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -7259,7 +7259,7 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) { // Microsoft or Itanium C++ ABI. However, even if these attributes are // present, we do not layout classes following foreign ABI rules, but // instead enter a special "compatibility mode", which only changes - // alignements of fundamental types and layout of bit fields. + // alignments of fundamental types and layout of bit fields. // Check whether this class uses any C++ features that are implemented // completely differently in the requested ABI, and if so, emit a // diagnostic. That diagnostic defaults to an error, but we allow >From 354896c5a2e03442f12f9f6c311a1b6a047b095e Mon Sep 17 00:00:00 2001 From: Dan Klishch <danilklis...@gmail.com> Date: Wed, 15 Nov 2023 13:52:47 -0500 Subject: [PATCH 5/7] fixup --- clang/include/clang/Basic/Attr.td | 2 +- clang/include/clang/Basic/AttrDocs.td | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 26028e72a033ad3..571889c08c84d07 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3674,7 +3674,7 @@ def MSStruct : InheritableAttr { def GCCStruct : InheritableAttr { let Spellings = [GCC<"gcc_struct">]; let Subjects = SubjectList<[Record]>; - let Documentation = [GCCStructDocs]; + let Documentation = [MSStructDocs]; // Covers this attribute too. let SimpleHandler = 1; } diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 4c829aaf3f3bff3..c5322ef223bc605 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -7675,10 +7675,3 @@ Note that the default behavior can be controlled by ``-mms-bitfields`` and ``-mno-ms-bitfields`` switches and via ``#pragma ms_struct``. }]; } - -def GCCStructDocs : Documentation { - let Category = DocCatDecl; - let Content = [{ -See ms_struct_. - }]; -} >From fc6a51224e47d0db633c63e3b9720a9e981705f6 Mon Sep 17 00:00:00 2001 From: Dan Klishch <danilklis...@gmail.com> Date: Tue, 28 Nov 2023 21:37:28 -0500 Subject: [PATCH 6/7] change cc1 option to -fms-layout-compatibility={default,microsoft,itanium} --- clang/include/clang/Basic/LangOptions.def | 2 ++ clang/include/clang/Basic/LangOptions.h | 11 +++++++-- clang/include/clang/Driver/Options.td | 10 ++++++-- clang/lib/AST/Decl.cpp | 6 +++-- clang/lib/Driver/ToolChains/Clang.cpp | 4 ++-- clang/lib/Frontend/CompilerInvocation.cpp | 12 ---------- clang/lib/Sema/SemaDeclCXX.cpp | 2 +- clang/test/CodeGen/mingw-long-double.c | 2 +- clang/test/CodeGen/mms-bitfields.c | 2 +- clang/test/Driver/ms-bitfields.c | 24 +++++++++++--------- clang/test/Layout/itanium-union-bitfield.cpp | 2 +- clang/test/Sema/mms-bitfields.c | 2 +- clang/test/SemaCXX/ms_struct.cpp | 2 +- clang/test/SemaCXX/ms_wide_bitfield.cpp | 2 +- 14 files changed, 45 insertions(+), 38 deletions(-) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 5b0869a792d8785..24ef16b8950c51a 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -149,6 +149,8 @@ LANGOPT(AssumeNothrowExceptionDtor , 1, 0, "Assume exception object's destructor LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation") LANGOPT(RTTI , 1, 1, "run-time type information") LANGOPT(RTTIData , 1, 1, "emit run-time type information data") +ENUM_LANGOPT(LayoutCompatibility, LayoutCompatibilityKind, 2, + LayoutCompatibilityKind::Default, "Microsoft-compatible structure layout") LANGOPT(MSVolatile , 1, 0, "Microsoft-compatible volatile loads and stores") LANGOPT(Freestanding, 1, 0, "freestanding implementation") LANGOPT(NoBuiltin , 1, 0, "disable builtin functions") diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 162929b90730b0e..bc7abc6de2a6b77 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -391,6 +391,15 @@ class LangOptions : public LangOptionsBase { IncompleteOnly = 3, }; + enum class LayoutCompatibilityKind { + /// Use default layout rules of the target. + Default = 0, + /// Use Itanium rules for bit-field layout and fundamental types alignment. + Itanium = 1, + /// Use Microsoft C++ ABI rules for bit-field layout and fundamental types alignment. + Microsoft = 2, + }; + public: /// The used language standard. LangStandard::Kind LangStd; @@ -507,8 +516,6 @@ class LangOptions : public LangOptionsBase { // implementation on real-world examples. std::string OpenACCMacroOverride; - std::optional<bool> MSBitfields; - LangOptions(); /// Set language defaults for the given input language and diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index ffad856e1fd8781..3b29790d246e67d 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4425,7 +4425,7 @@ def mmacos_version_min_EQ : Joined<["-"], "mmacos-version-min=">, def : Joined<["-"], "mmacosx-version-min=">, Group<m_Group>, Alias<mmacos_version_min_EQ>; def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>, - Visibility<[ClangOption, CC1Option]>, + Visibility<[ClangOption]>, HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard">; def moutline : Flag<["-"], "moutline">, Group<f_clang_Group>, Visibility<[ClangOption, CC1Option]>, @@ -4434,8 +4434,14 @@ def mno_outline : Flag<["-"], "mno-outline">, Group<f_clang_Group>, Visibility<[ClangOption, CC1Option]>, HelpText<"Disable function outlining (AArch64 only)">; def mno_ms_bitfields : Flag<["-"], "mno-ms-bitfields">, Group<m_Group>, - Visibility<[ClangOption, CC1Option]>, + Visibility<[ClangOption]>, HelpText<"Do not set the default structure layout to be compatible with the Microsoft compiler standard">; +def fms_layout_compatibility_EQ : Joined<["-"], "fms-layout-compatibility=">, + Visibility<[CC1Option]>, + HelpText<"Structure layout compatibility with Microsoft C++ ABI">, + Values<"default,itanium,microsoft">, + NormalizedValues<["Default", "Itanium", "Microsoft"]>, NormalizedValuesScope<"LangOptions::LayoutCompatibilityKind">, + MarshallingInfoEnum<LangOpts<"LayoutCompatibility">, "Default">; def mskip_rax_setup : Flag<["-"], "mskip-rax-setup">, Group<m_Group>, Visibility<[ClangOption, CC1Option]>, HelpText<"Skip setting up RAX register when passing variable arguments (x86 only)">, diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 25201995925322e..0fff0a4f53cc8c9 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -5035,8 +5035,10 @@ bool RecordDecl::isMsStruct(const ASTContext &C) const { return true; if (hasAttr<GCCStructAttr>()) return false; - return C.getLangOpts().MSBitfields.value_or( - C.getTargetInfo().defaultsToMsStruct()); + auto LayoutCompatibility = C.getLangOpts().getLayoutCompatibility(); + if (LayoutCompatibility == LangOptions::LayoutCompatibilityKind::Default) + return C.getTargetInfo().defaultsToMsStruct(); + return LayoutCompatibility == LangOptions::LayoutCompatibilityKind::Microsoft; } void RecordDecl::reorderDecls(const SmallVectorImpl<Decl *> &Decls) { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 4851a4915ece91e..c0e37e2a13a1d63 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5670,9 +5670,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.hasArg(options::OPT_mno_ms_bitfields)) { if (Args.hasFlag(options::OPT_mms_bitfields, options::OPT_mno_ms_bitfields, false)) - CmdArgs.push_back("-mms-bitfields"); + CmdArgs.push_back("-fms-layout-compatibility=microsoft"); else - CmdArgs.push_back("-mno-ms-bitfields"); + CmdArgs.push_back("-fms-layout-compatibility=itanium"); } if (Triple.isWindowsGNUEnvironment()) { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index b4f48863653bcd7..5a8e4cf9843de2b 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3635,13 +3635,6 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, GenerateArg(Consumer, OPT_fcxx_abi_EQ, TargetCXXABI::getSpelling(*Opts.CXXABI)); - if (Opts.MSBitfields.has_value()) { - if (Opts.MSBitfields.value()) - GenerateArg(Consumer, OPT_mms_bitfields); - else - GenerateArg(Consumer, OPT_mno_ms_bitfields); - } - if (Opts.RelativeCXXABIVTables) GenerateArg(Consumer, OPT_fexperimental_relative_cxx_abi_vtables); else @@ -4184,11 +4177,6 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, options::OPT_fno_experimental_relative_cxx_abi_vtables, TargetCXXABI::usesRelativeVTables(T)); - if (Args.hasArg(options::OPT_mms_bitfields) || - Args.hasArg(options::OPT_mno_ms_bitfields)) - Opts.MSBitfields = Args.hasFlag(options::OPT_mms_bitfields, - options::OPT_mno_ms_bitfields, false); - // RTTI is on by default. bool HasRTTI = !Args.hasArg(options::OPT_fno_rtti); Opts.OmitVTableRTTI = diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index c0e76594364134e..d7349809a43bf35 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -7273,7 +7273,7 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) { // language option (as opposed to via a pragma or attribute), as // the option -mms-bitfields otherwise essentially makes it impossible // to build C++ code, unless this diagnostic is turned off. - if (!Context.getLangOpts().MSBitfields.has_value() && + if (Context.getLangOpts().getLayoutCompatibility() == LangOptions::LayoutCompatibilityKind::Default && Record->isMsStruct(Context) != Context.getTargetInfo().defaultsToMsStruct() && (Record->isPolymorphic() || Record->getNumBases())) { diff --git a/clang/test/CodeGen/mingw-long-double.c b/clang/test/CodeGen/mingw-long-double.c index a50f8f0b3b63341..2bd212a69566664 100644 --- a/clang/test/CodeGen/mingw-long-double.c +++ b/clang/test/CodeGen/mingw-long-double.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -o - %s \ // RUN: | FileCheck %s --check-prefix=GNU32 -// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -o - %s -mms-bitfields \ +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -o - %s -fms-layout-compatibility=microsoft \ // RUN: | FileCheck %s --check-prefix=GNU32 // RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -o - %s \ // RUN: | FileCheck %s --check-prefix=GNU64 diff --git a/clang/test/CodeGen/mms-bitfields.c b/clang/test/CodeGen/mms-bitfields.c index 49c5c1c3e7d40d8..43d189a793f7e52 100644 --- a/clang/test/CodeGen/mms-bitfields.c +++ b/clang/test/CodeGen/mms-bitfields.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin10 -mms-bitfields -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fms-layout-compatibility=microsoft -emit-llvm %s -o - | FileCheck %s struct s1 { int f32; diff --git a/clang/test/Driver/ms-bitfields.c b/clang/test/Driver/ms-bitfields.c index 4cd3f1380e41acf..07d1c38c3ef3bed 100644 --- a/clang/test/Driver/ms-bitfields.c +++ b/clang/test/Driver/ms-bitfields.c @@ -1,13 +1,15 @@ -// RUN: %clang -### -target x86_64-linux-gnu %s 2>&1 | FileCheck %s -check-prefix=DEFAULT-MSBITFIELDS -// RUN: %clang -### -target x86_64-windows-gnu %s 2>&1 | FileCheck %s -check-prefix=DEFAULT-MSBITFIELDS -// RUN: %clang -### -target x86_64-windows-msvc %s 2>&1 | FileCheck %s -check-prefix=DEFAULT-MSBITFIELDS -// RUN: %clang -### -mms-bitfields %s 2>&1 | FileCheck %s -check-prefix=MSBITFIELDS -// RUN: %clang -### -mno-ms-bitfields %s 2>&1 | FileCheck %s -check-prefix=NO-MSBITFIELDS -// RUN: %clang -### -mno-ms-bitfields -mms-bitfields %s 2>&1 | FileCheck %s -check-prefix=MSBITFIELDS -// RUN: %clang -### -mms-bitfields -mno-ms-bitfields %s 2>&1 | FileCheck %s -check-prefix=NO-MSBITFIELDS +// RUN: %clang -### -target x86_64-linux-gnu %s 2>&1 | FileCheck %s -check-prefix=DEFAULT-LAYOUT +// RUN: %clang -### -target x86_64-windows-gnu %s 2>&1 | FileCheck %s -check-prefix=DEFAULT-LAYOUT +// RUN: %clang -### -target x86_64-windows-msvc %s 2>&1 | FileCheck %s -check-prefix=DEFAULT-LAYOUT +// RUN: %clang -### -mms-bitfields %s 2>&1 | FileCheck %s -check-prefix=MICROSOFT-LAYOUT +// RUN: %clang -### -mno-ms-bitfields %s 2>&1 | FileCheck %s -check-prefix=ITANIUM-LAYOUT +// RUN: %clang -### -mno-ms-bitfields -mms-bitfields %s 2>&1 | FileCheck %s -check-prefix=MICROSOFT-LAYOUT +// RUN: %clang -### -mms-bitfields -mno-ms-bitfields %s 2>&1 | FileCheck %s -check-prefix=ITANIUM-LAYOUT -// MSBITFIELDS: -mms-bitfields -// NO-MSBITFIELDS: -mno-ms-bitfields -// DEFAULT-MSBITFIELDS-NOT: -mms-bitfields -// DEFAULT-MSBITFIELDS-NOT: -mno-ms-bitfields +// DEFAULT-LAYOUT-NOT: -fms-layout-compatibility=itanium +// DEFAULT-LAYOUT-NOT: -fms-layout-compatibility=microsoft +// MICROSOFT-LAYOUT: -fms-layout-compatibility=microsoft +// MICROSOFT-LAYOUT-NOT: -fms-layout-compatibility=itanium +// ITANIUM-LAYOUT: -fms-layout-compatibility=itanium +// ITANIUM-LAYOUT-NOT: -fms-layout-compatibility=microsoft diff --git a/clang/test/Layout/itanium-union-bitfield.cpp b/clang/test/Layout/itanium-union-bitfield.cpp index 3e22fe9a3faabd3..34f501f4b569a7b 100644 --- a/clang/test/Layout/itanium-union-bitfield.cpp +++ b/clang/test/Layout/itanium-union-bitfield.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -mno-ms-bitfields -fdump-record-layouts %s 2>/dev/null \ +// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -fms-layout-compatibility=itanium -fdump-record-layouts %s 2>/dev/null \ // RUN: | FileCheck %s // On z/OS, a bit-field has single byte alignment. Add aligned(4) on z/OS so the union has diff --git a/clang/test/Sema/mms-bitfields.c b/clang/test/Sema/mms-bitfields.c index cee5b0669d252fd..d0a67a4a3d793e1 100644 --- a/clang/test/Sema/mms-bitfields.c +++ b/clang/test/Sema/mms-bitfields.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -mms-bitfields -fsyntax-only -verify -triple x86_64-apple-darwin9 %s +// RUN: %clang_cc1 -fms-layout-compatibility=microsoft -fsyntax-only -verify -triple x86_64-apple-darwin9 %s // expected-no-diagnostics // The -mms-bitfields commandline parameter should behave the same diff --git a/clang/test/SemaCXX/ms_struct.cpp b/clang/test/SemaCXX/ms_struct.cpp index 995e424d1f87640..29d29e4fd6fdc82 100644 --- a/clang/test/SemaCXX/ms_struct.cpp +++ b/clang/test/SemaCXX/ms_struct.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -DTEST_FOR_WARNING -Wno-error=incompatible-ms-struct -verify -triple i686-apple-darwin9 -std=c++11 %s // RUN: %clang_cc1 -fsyntax-only -DTEST_FOR_WARNING -Wno-error=incompatible-ms-struct -verify -triple armv7-apple-darwin9 -std=c++11 %s // RUN: %clang_cc1 -fsyntax-only -DTEST_FOR_ERROR -verify -triple armv7-apple-darwin9 -std=c++11 %s -// RUN: %clang_cc1 -fsyntax-only -DNO_PRAGMA -mms-bitfields -verify -triple armv7-apple-darwin9 -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -DNO_PRAGMA -fms-layout-compatibility=microsoft -verify -triple armv7-apple-darwin9 -std=c++11 %s #ifndef NO_PRAGMA #pragma ms_struct on diff --git a/clang/test/SemaCXX/ms_wide_bitfield.cpp b/clang/test/SemaCXX/ms_wide_bitfield.cpp index 0dcc787928b0a31..76af5bdaf90930e 100644 --- a/clang/test/SemaCXX/ms_wide_bitfield.cpp +++ b/clang/test/SemaCXX/ms_wide_bitfield.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -mms-bitfields -verify %s 2>&1 +// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -fms-layout-compatibility=microsoft -verify %s 2>&1 struct A { char a : 9; // expected-error{{width of bit-field 'a' (9 bits) exceeds the size of its type (8 bits)}} >From f2ca9e72ae662b6ea756dec4d1e9070d0f53a2e5 Mon Sep 17 00:00:00 2001 From: Dan Klishch <danilklis...@gmail.com> Date: Tue, 28 Nov 2023 21:44:39 -0500 Subject: [PATCH 7/7] fixup style --- clang/include/clang/Basic/LangOptions.h | 3 ++- clang/lib/Sema/SemaDeclCXX.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index bc7abc6de2a6b77..9da86d00e4a961e 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -396,7 +396,8 @@ class LangOptions : public LangOptionsBase { Default = 0, /// Use Itanium rules for bit-field layout and fundamental types alignment. Itanium = 1, - /// Use Microsoft C++ ABI rules for bit-field layout and fundamental types alignment. + /// Use Microsoft C++ ABI rules for bit-field layout and fundamental types + /// alignment. Microsoft = 2, }; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index d7349809a43bf35..f553964b1c0a4f5 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -7273,7 +7273,8 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) { // language option (as opposed to via a pragma or attribute), as // the option -mms-bitfields otherwise essentially makes it impossible // to build C++ code, unless this diagnostic is turned off. - if (Context.getLangOpts().getLayoutCompatibility() == LangOptions::LayoutCompatibilityKind::Default && + if (Context.getLangOpts().getLayoutCompatibility() == + LangOptions::LayoutCompatibilityKind::Default && Record->isMsStruct(Context) != Context.getTargetInfo().defaultsToMsStruct() && (Record->isPolymorphic() || Record->getNumBases())) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits