Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit bcf6b98

Browse files
committed
Extend the fix for PR9614 to handle inline asm in the outer decl and
the inner decl being a builtin. This is needed to support the glibc headers in fedora 16 (2.14). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146867 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 0f45682 commit bcf6b98

File tree

3 files changed

+41
-17
lines changed

3 files changed

+41
-17
lines changed

Diff for: lib/CodeGen/CodeGenModule.cpp

+32-15
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "clang/AST/Mangle.h"
3131
#include "clang/AST/RecordLayout.h"
3232
#include "clang/AST/RecursiveASTVisitor.h"
33+
#include "clang/Basic/Builtins.h"
3334
#include "clang/Basic/Diagnostic.h"
3435
#include "clang/Basic/SourceManager.h"
3536
#include "clang/Basic/TargetInfo.h"
@@ -863,20 +864,27 @@ namespace {
863864
struct FunctionIsDirectlyRecursive :
864865
public RecursiveASTVisitor<FunctionIsDirectlyRecursive> {
865866
const StringRef Name;
867+
const Builtin::Context &BI;
866868
bool Result;
867-
FunctionIsDirectlyRecursive(const FunctionDecl *F) :
868-
Name(F->getName()), Result(false) {
869+
FunctionIsDirectlyRecursive(StringRef N, const Builtin::Context &C) :
870+
Name(N), BI(C), Result(false) {
869871
}
870872
typedef RecursiveASTVisitor<FunctionIsDirectlyRecursive> Base;
871873

872874
bool TraverseCallExpr(CallExpr *E) {
873-
const Decl *D = E->getCalleeDecl();
874-
if (!D)
875+
const FunctionDecl *FD = E->getDirectCallee();
876+
if (!FD)
875877
return true;
876-
AsmLabelAttr *Attr = D->getAttr<AsmLabelAttr>();
877-
if (!Attr)
878+
AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
879+
if (Attr && Name == Attr->getLabel()) {
880+
Result = true;
881+
return false;
882+
}
883+
unsigned BuiltinID = FD->getBuiltinID();
884+
if (!BuiltinID)
878885
return true;
879-
if (Name == Attr->getLabel()) {
886+
const char *BuiltinName = BI.GetName(BuiltinID) + strlen("__builtin_");
887+
if (Name == BuiltinName) {
880888
Result = true;
881889
return false;
882890
}
@@ -885,15 +893,24 @@ namespace {
885893
};
886894
}
887895

888-
// isTriviallyRecursiveViaAsm - Check if this function calls another
889-
// decl that, because of the asm attribute, ends up pointing to itself.
896+
// isTriviallyRecursive - Check if this function calls another
897+
// decl that, because of the asm attribute or the other decl being a builtin,
898+
// ends up pointing to itself.
890899
bool
891-
CodeGenModule::isTriviallyRecursiveViaAsm(const FunctionDecl *F) {
892-
if (getCXXABI().getMangleContext().shouldMangleDeclName(F))
893-
return false;
900+
CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) {
901+
StringRef Name;
902+
if (getCXXABI().getMangleContext().shouldMangleDeclName(FD)) {
903+
// asm labels are a special king of mangling we have to support.
904+
AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
905+
if (!Attr)
906+
return false;
907+
Name = Attr->getLabel();
908+
} else {
909+
Name = FD->getName();
910+
}
894911

895-
FunctionIsDirectlyRecursive Walker(F);
896-
Walker.TraverseFunctionDecl(const_cast<FunctionDecl*>(F));
912+
FunctionIsDirectlyRecursive Walker(Name, Context.BuiltinInfo);
913+
Walker.TraverseFunctionDecl(const_cast<FunctionDecl*>(FD));
897914
return Walker.Result;
898915
}
899916

@@ -909,7 +926,7 @@ CodeGenModule::shouldEmitFunction(const FunctionDecl *F) {
909926
// but a function that calls itself is clearly not equivalent to the real
910927
// implementation.
911928
// This happens in glibc's btowc and in some configure checks.
912-
return !isTriviallyRecursiveViaAsm(F);
929+
return !isTriviallyRecursive(F);
913930
}
914931

915932
void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {

Diff for: lib/CodeGen/CodeGenModule.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ class CodeGenModule : public CodeGenTypeCache {
323323
void createOpenCLRuntime();
324324
void createCUDARuntime();
325325

326-
bool isTriviallyRecursiveViaAsm(const FunctionDecl *F);
326+
bool isTriviallyRecursive(const FunctionDecl *F);
327327
bool shouldEmitFunction(const FunctionDecl *F);
328328
llvm::LLVMContext &VMContext;
329329

Diff for: test/CodeGen/pr9614.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -emit-llvm %s -O1 -o - | FileCheck %s
1+
// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
22

33
extern void foo_alias (void) __asm ("foo");
44
inline void foo (void) {
@@ -8,15 +8,22 @@ extern void bar_alias (void) __asm ("bar");
88
inline __attribute__ ((__always_inline__)) void bar (void) {
99
return bar_alias ();
1010
}
11+
extern char *strrchr_foo (const char *__s, int __c) __asm ("strrchr");
12+
extern inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) char * strrchr_foo (const char *__s, int __c) {
13+
return __builtin_strrchr (__s, __c);
14+
}
1115
void f(void) {
1216
foo();
1317
bar();
18+
strrchr_foo("", '.');
1419
}
1520

1621
// CHECK: define void @f()
1722
// CHECK: call void @foo()
1823
// CHECK-NEXT: call void @bar()
24+
// CHECK-NEXT: call i8* @strrchr(
1925
// CHECK-NEXT: ret void
2026

2127
// CHECK: declare void @foo()
2228
// CHECK: declare void @bar()
29+
// CHECK: declare i8* @strrchr(i8*, i32)

0 commit comments

Comments
 (0)