[PATCH] Make GNUInline consistent with whether we use traditional GNU inline semantics.

Peter Collingbourne peter at pcc.me.uk
Tue Apr 28 17:52:56 PDT 2015


Hi rsmith,

Previously we were setting LangOptions::GNUInline (which controls whether we
use traditional GNU inline semantics) if the language did not have the C99
feature flag set. The trouble with this is that C++ family languages also
do not have that flag set, so we ended up setting this flag in C++ modes
(and working around it in a few places downstream by also checking CPlusPlus).

This also caused us to define the __GNUC_GNU_INLINE__ macro in C++ modes,
wrongly claiming traditional GNU inline semantics in C++ (this also happens
to be what GCC does, but I think it's a GCC bug).

The fix is to check whether the C89 flag is set for the target language,
rather than whether the C99 flag is cleared. This also lets us remove the
CPlusPlus checks.

There is a change in semantics in two other places
where we weren't checking both CPlusPlus and GNUInline
(FunctionDecl::doesDeclarationForceExternallyVisibleDefinition and
FunctionDecl::isInlineDefinitionExternallyVisible), but this change seems to
put us back into line with GCC's semantics (test case: test/CodeGen/inline.c).

While at it, forbid -fgnu89-inline in C++ modes, as GCC doesn't support it,
it didn't have any effect before, and supporting it just makes things more
complicated.

http://reviews.llvm.org/D9333

Files:
  lib/Frontend/CompilerInvocation.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaExpr.cpp
  test/CodeGen/inline.c
  test/Frontend/gnu-inline.c

Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -1226,7 +1226,7 @@
   Opts.CPlusPlus1z = Std.isCPlusPlus1z();
   Opts.Digraphs = Std.hasDigraphs();
   Opts.GNUMode = Std.isGNUMode();
-  Opts.GNUInline = !Std.isC99();
+  Opts.GNUInline = Std.isC89();
   Opts.HexFloats = Std.hasHexFloats();
   Opts.ImplicitInt = Std.hasImplicitInt();
 
@@ -1409,8 +1409,13 @@
         (Opts.ObjCRuntime.getKind() == ObjCRuntime::FragileMacOSX);
   }
     
-  if (Args.hasArg(OPT_fgnu89_inline))
-    Opts.GNUInline = 1;
+  if (Args.hasArg(OPT_fgnu89_inline)) {
+    if (Opts.CPlusPlus)
+      Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fgnu89-inline"
+                                                            << "C++/ObjC++";
+    else
+      Opts.GNUInline = 1;
+  }
 
   if (Args.hasArg(OPT_fapple_kext)) {
     if (!Opts.CPlusPlus)
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -2713,7 +2713,7 @@
   // UndefinedButUsed.
   if (!Old->isInlined() && New->isInlined() &&
       !New->hasAttr<GNUInlineAttr>() &&
-      (getLangOpts().CPlusPlus || !getLangOpts().GNUInline) &&
+      !getLangOpts().GNUInline &&
       Old->isUsed(false) &&
       !Old->isDefined() && !New->isThisDeclarationADefinition())
     UndefinedButUsed.insert(std::make_pair(Old->getCanonicalDecl(),
@@ -10586,7 +10586,7 @@
       if (!FD->isExternallyVisible())
         UndefinedButUsed.erase(FD);
       else if (FD->isInlined() &&
-               (LangOpts.CPlusPlus || !LangOpts.GNUInline) &&
+               !LangOpts.GNUInline &&
                (!FD->getPreviousDecl()->hasAttr<GNUInlineAttr>()))
         UndefinedButUsed.erase(FD);
     }
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -12232,7 +12232,7 @@
     if (mightHaveNonExternalLinkage(Func))
       UndefinedButUsed.insert(std::make_pair(Func->getCanonicalDecl(), Loc));
     else if (Func->getMostRecentDecl()->isInlined() &&
-             (LangOpts.CPlusPlus || !LangOpts.GNUInline) &&
+             !LangOpts.GNUInline &&
              !Func->getMostRecentDecl()->hasAttr<GNUInlineAttr>())
       UndefinedButUsed.insert(std::make_pair(Func->getCanonicalDecl(), Loc));
   }
Index: test/CodeGen/inline.c
===================================================================
--- test/CodeGen/inline.c
+++ test/CodeGen/inline.c
@@ -49,6 +49,7 @@
 // CHECK3-NOT: unreferenced
 // CHECK3-LABEL: define void @_Z10gnu_inlinev()
 // CHECK3-LABEL: define available_externally void @_Z13gnu_ei_inlinev()
+// CHECK3-NOT: @_Z5testCv
 // CHECK3-LABEL: define linkonce_odr i32 @_Z2eiv()
 
 // RUN: echo "MS C Mode tests:"
Index: test/Frontend/gnu-inline.c
===================================================================
--- /dev/null
+++ test/Frontend/gnu-inline.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c89 -fsyntax-only -x c -E -dM %s | FileCheck --check-prefix=GNU-INLINE %s
+// RUN: %clang_cc1 -std=c99 -fsyntax-only -x c -E -dM %s | FileCheck --check-prefix=STDC-INLINE %s
+// RUN: %clang_cc1 -std=c99 -fgnu89-inline -fsyntax-only -x c -E -dM %s | FileCheck --check-prefix=GNU-INLINE %s
+// RUN: %clang_cc1 -fsyntax-only -x c++ -E -dM %s | FileCheck --check-prefix=STDC-INLINE %s
+// RUN: not %clang_cc1 -fgnu89-inline -fsyntax-only -x c++ %s 2>&1 | FileCheck --check-prefix=CXX %s
+
+// CXX: '-fgnu89-inline' not allowed with 'C++/ObjC++'
+
+// STDC-INLINE-NOT: __GNUC_GNU_INLINE__
+// STDC-INLINE: #define __GNUC_STDC_INLINE__ 1
+// STDC-INLINE-NOT: __GNUC_GNU_INLINE__
+
+// GNU-INLINE-NOT: __GNUC_STDC_INLINE__
+// GNU-INLINE: #define __GNUC_GNU_INLINE__ 1
+// GNU-INLINE-NOT: __GNUC_STDC_INLINE__

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D9333.24590.patch
Type: text/x-patch
Size: 3905 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150429/d6f21f60/attachment.bin>


More information about the cfe-commits mailing list