This is an archive of the discontinued LLVM Phabricator instance.

Make GNUInline consistent with whether we use traditional GNU inline semantics.
ClosedPublic

Authored by pcc on Apr 28 2015, 5:52 PM.

Details

Summary

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.

Diff Detail

Repository
rL LLVM

Event Timeline

pcc updated this revision to Diff 24590.Apr 28 2015, 5:52 PM
pcc retitled this revision from to Make GNUInline consistent with whether we use traditional GNU inline semantics..
pcc updated this object.
pcc edited the test plan for this revision. (Show Details)
pcc added a reviewer: rsmith.
pcc added a subscriber: Unknown Object (MLST).
rsmith edited edge metadata.May 13 2015, 1:54 PM

I believe your change to not define __GNUC_GNU_INLINE__ will break recent versions of glibc, which test for the definition of either that or __GNUC_STD_INLINE__ to determine whether __attribute__((__gnu_inline__)) is available: https://sourceware.org/git/?p=glibc.git;a=blob;f=misc/sys/cdefs.h;h=99e94cce869572b724df6b5b8c847cc38a0b3a57;hb=HEAD#l331

Other than the change to -D__GNUC_GNU_INLINE__, this patch looks good to me. Can we unconditionally predefine that macro in C++ mode?

pcc added a comment.May 13 2015, 2:00 PM

We always define one of __GNUC_GNU_INLINE__ or __GNUC_STDC_INLINE__ depending on whether GNUInline is set; see lib/Frontend/InitPreprocessor.cpp lines 793-796. So I don't think this would break.

__GNUC_STDC_INLINE__ means C99 inline semantics, which is just as wrong as __GNUC_GNU_INLINE__ for C++. We have to make a choice between these two to support glibc, and sticking to what g++ does (and what clang previously did) seems like the clear better choice -- the risk of breaking things by making a change here is high, and I don't see that there's any real benefit to changing which lie we tell the user.

pcc added a comment.May 13 2015, 2:47 PM

That seems like a reasonable position to take. I am aware of some headers which are broken without this change, but it's probably more reasonable to consider this to be a bug in those headers.

pcc updated this revision to Diff 25735.May 13 2015, 3:03 PM
pcc edited edge metadata.

Retain the existing logic for deciding whether to define GNUC_GNU_INLINE

rsmith accepted this revision.May 13 2015, 3:04 PM
rsmith edited edge metadata.

LGTM

This revision is now accepted and ready to land.May 13 2015, 3:04 PM
This revision was automatically updated to reflect the committed changes.