From 5e866e411caad4c4e17e7e0c67b06d28451e1bf2 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 10 Oct 2019 21:04:25 +0000 Subject: Add -fgnuc-version= to control __GNUC__ and other GCC macros I noticed that compiling on Windows with -fno-ms-compatibility had the side effect of defining __GNUC__, along with __GNUG__, __GXX_RTTI__, and a number of other macros for GCC compatibility. This is undesirable and causes Chromium to do things like mix __attribute__ and __declspec, which doesn't work. We should have a positive language option to enable GCC compatibility features so that we can experiment with -fno-ms-compatibility on Windows. This change adds -fgnuc-version= to be that option. My issue aside, users have, for a long time, reported that __GNUC__ doesn't match their expectations in one way or another. We have encouraged users to migrate code away from this macro, but new code continues to be written assuming a GCC-only environment. There's really nothing we can do to stop that. By adding this flag, we can allow them to choose their own adventure with __GNUC__. This overlaps a bit with the "GNUMode" language option from -std=gnu*. The gnu language mode tends to enable non-conforming behaviors that we'd rather not enable by default, but the we want to set things like __GXX_RTTI__ by default, so I've kept these separate. Helps address PR42817 Reviewed By: hans, nickdesaulniers, MaskRay Differential Revision: https://reviews.llvm.org/D68055 llvm-svn: 374449 --- clang/lib/Frontend/CompilerInvocation.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'clang/lib/Frontend/CompilerInvocation.cpp') diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index d55f969..3ea421c 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2250,6 +2250,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.Digraphs = Std.hasDigraphs(); Opts.GNUMode = Std.isGNUMode(); Opts.GNUInline = !Opts.C99 && !Opts.CPlusPlus; + Opts.GNUCVersion = 0; Opts.HexFloats = Std.hasHexFloats(); Opts.ImplicitInt = Std.hasImplicitInt(); @@ -2574,6 +2575,21 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, (Opts.ObjCRuntime.getKind() == ObjCRuntime::FragileMacOSX); } + if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) { + // Check that the version has 1 to 3 components and the minor and patch + // versions fit in two decimal digits. + VersionTuple GNUCVer; + bool Invalid = GNUCVer.tryParse(A->getValue()); + unsigned Major = GNUCVer.getMajor(); + unsigned Minor = GNUCVer.getMinor().getValueOr(0); + unsigned Patch = GNUCVer.getSubminor().getValueOr(0); + if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) { + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(); + } + Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch; + } + if (Args.hasArg(OPT_fgnu89_inline)) { if (Opts.CPlusPlus) Diags.Report(diag::err_drv_argument_not_allowed_with) -- cgit v1.1