diff options
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 9 | ||||
-rw-r--r-- | clang/test/CodeGen/pr9614.c | 26 |
2 files changed, 20 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 86378a9afa0..c796e0daa99 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -901,18 +901,15 @@ bool CodeGenModule::shouldEmitFunction(const FunctionDecl *F) { if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage) return true; - if (F->hasAttr<AlwaysInlineAttr>()) - return true; - if (CodeGenOpts.OptimizationLevel == 0) + if (CodeGenOpts.OptimizationLevel == 0 && + !F->hasAttr<AlwaysInlineAttr>()) return false; // PR9614. Avoid cases where the source code is lying to us. An available // externally function should have an equivalent function somewhere else, // but a function that calls itself is clearly not equivalent to the real // implementation. // This happens in glibc's btowc and in some configure checks. - if (isTriviallyRecursiveViaAsm(F)) - return false; - return true; + return !isTriviallyRecursiveViaAsm(F); } void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { diff --git a/clang/test/CodeGen/pr9614.c b/clang/test/CodeGen/pr9614.c index 68a59095ab3..e761bec3f91 100644 --- a/clang/test/CodeGen/pr9614.c +++ b/clang/test/CodeGen/pr9614.c @@ -1,15 +1,23 @@ // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s -extern int foo_alias (void) __asm ("foo"); -inline int foo (void) { +extern void foo_alias (void) __asm ("foo"); +inline void foo (void) { return foo_alias (); } -int f(void) { - return foo(); +extern void bar_alias (void) __asm ("bar"); +inline __attribute__ ((__always_inline__)) void bar (void) { + return bar_alias (); } +void f(void) { + foo(); + bar(); +} + +// CHECK: define void @f() +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @foo() +// CHECK-NEXT: call void @bar() +// CHECK-NEXT: ret void -// CHECK-NOT: define -// CHECK: define i32 @f() -// CHECK: call i32 @foo() -// CHECK-NEXT: ret i32 -// CHECK-NOT: define +// CHECK: declare void @foo() +// CHECK: declare void @bar() |