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() && - (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())) 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()) 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__