[cfe-commits] r69069 - in /cfe/trunk: lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h test/CodeGen/inline.c
Chris Lattner
sabre at nondot.org
Tue Apr 14 13:25:55 PDT 2009
Author: lattner
Date: Tue Apr 14 15:25:53 2009
New Revision: 69069
URL: http://llvm.org/viewvc/llvm-project?rev=69069&view=rev
Log:
Fix PR3988: extern inline functions get strong symbol definitions in
C99 mode. This is a regression from an earlier patch of mine.
This also simplifies the linkage enums a bit.
Modified:
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/test/CodeGen/inline.c
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=69069&r1=69068&r2=69069&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Apr 14 15:25:53 2009
@@ -229,26 +229,32 @@
return CodeGenModule::GVA_Internal;
if (!FD->isInline())
- return CodeGenModule::GVA_Normal;
+ return CodeGenModule::GVA_StrongExternal;
- if (FD->getStorageClass() == FunctionDecl::Extern)
- return CodeGenModule::GVA_ExternInline;
-
// If the inline function explicitly has the GNU inline attribute on it, then
- // force to GNUC semantics, regardless of language.
+ // force to GNUC semantics (which is strong external), regardless of language.
if (FD->hasAttr<GNUCInlineAttr>())
- return CodeGenModule::GVA_GNUCInline;
-
+ return CodeGenModule::GVA_StrongExternal;
+
// The definition of inline changes based on the language. Note that we
// have already handled "static inline" above, with the GVA_Internal case.
- if (Features.CPlusPlus)
+ if (Features.CPlusPlus) // inline and extern inline.
return CodeGenModule::GVA_CXXInline;
+ if (FD->getStorageClass() == FunctionDecl::Extern) {
+ // extern inline in C99 is a strong definition. In C89, it is extern inline.
+ if (Features.C99)
+ return CodeGenModule::GVA_StrongExternal;
+
+ // In C89 mode, an 'extern inline' works like a C99 inline function.
+ return CodeGenModule::GVA_C99Inline;
+ }
+
if (Features.C99)
return CodeGenModule::GVA_C99Inline;
// Otherwise, this is the GNU inline extension in K&R and GNU C89 mode.
- return CodeGenModule::GVA_GNUCInline;
+ return CodeGenModule::GVA_StrongExternal;
}
/// SetFunctionDefinitionAttributes - Set attributes for a global.
@@ -266,10 +272,9 @@
GV->setLinkage(llvm::Function::DLLExportLinkage);
} else if (D->hasAttr<WeakAttr>() || D->hasAttr<WeakImportAttr>()) {
GV->setLinkage(llvm::Function::WeakAnyLinkage);
- } else if (Linkage == GVA_ExternInline) {
- // "extern inline" always gets available_externally linkage, which is the
- // strongest linkage type we can give an inline function: we don't have to
- // codegen the definition at all, yet we know that it is "ODR".
+ } else if (Linkage == GVA_C99Inline) {
+ // In C99 mode, 'inline' functions are guaranteed to have a strong
+ // definition somewhere else, so we can use available_externally linkage.
GV->setLinkage(llvm::Function::AvailableExternallyLinkage);
} else if (Linkage == GVA_CXXInline) {
// In C++, the compiler has to emit a definition in every translation unit
@@ -279,16 +284,9 @@
// merged with other definitions. c) C++ has the ODR, so we know the
// definition is dependable.
GV->setLinkage(llvm::Function::LinkOnceODRLinkage);
- } else if (Linkage == GVA_C99Inline) {
- // In C99 mode, 'inline' functions are guaranteed to have a strong
- // definition somewhere else, so we can use available_externally linkage.
- GV->setLinkage(llvm::Function::AvailableExternallyLinkage);
- } else if (Linkage == GVA_GNUCInline) {
- // In C89 mode, an 'inline' function may only occur in one translation
- // unit in the program, but may be extern'd in others. Give it strong
- // external linkage.
- GV->setLinkage(llvm::Function::ExternalLinkage);
} else {
+ assert(Linkage == GVA_StrongExternal);
+ // Otherwise, we have strong external linkage.
GV->setLinkage(llvm::Function::ExternalLinkage);
}
@@ -481,8 +479,8 @@
// static, static inline, always_inline, and extern inline functions can
// always be deferred. Normal inline functions can be deferred in C99/C++.
- if (Linkage == GVA_Internal || Linkage == GVA_ExternInline ||
- Linkage == GVA_C99Inline || Linkage == GVA_CXXInline)
+ if (Linkage == GVA_Internal || Linkage == GVA_C99Inline ||
+ Linkage == GVA_CXXInline)
return true;
return false;
}
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=69069&r1=69068&r2=69069&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Apr 14 15:25:53 2009
@@ -315,10 +315,9 @@
enum GVALinkage {
GVA_Internal,
GVA_ExternInline,
- GVA_GNUCInline,
GVA_C99Inline,
GVA_CXXInline,
- GVA_Normal
+ GVA_StrongExternal
};
private:
Modified: cfe/trunk/test/CodeGen/inline.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/inline.c?rev=69069&r1=69068&r2=69069&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/inline.c (original)
+++ cfe/trunk/test/CodeGen/inline.c Tue Apr 14 15:25:53 2009
@@ -9,15 +9,16 @@
// RUN: echo "\nC99 tests:" &&
// RUN: clang %s -emit-llvm -S -o %t -std=c99 &&
-// RUN: grep "define available_externally i32 @ei()" %t &&
+// RUN: grep "define i32 @ei()" %t &&
// RUN: grep "define available_externally i32 @foo()" %t &&
// RUN: grep "define i32 @bar()" %t &&
-// RUN: not grep unreferenced %t &&
+// RUN: not grep unreferenced1 %t &&
+// RUN: grep "define void @unreferenced2()" %t &&
// RUN: grep "define void @gnu_inline()" %t &&
// RUN: echo "\nC++ tests:" &&
// RUN: clang %s -emit-llvm -S -o %t -std=c++98 &&
-// RUN: grep "define available_externally i32 @_Z2eiv()" %t &&
+// RUN: grep "define linkonce_odr i32 @_Z2eiv()" %t &&
// RUN: grep "define linkonce_odr i32 @_Z3foov()" %t &&
// RUN: grep "define i32 @_Z3barv()" %t &&
// RUN: not grep unreferenced %t &&
More information about the cfe-commits
mailing list