diff --git a/llvm-pr9614-part1.patch b/llvm-pr9614-part1.patch new file mode 100644 index 0000000..dddbde8 --- /dev/null +++ b/llvm-pr9614-part1.patch @@ -0,0 +1,96 @@ +--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp 2011/10/26 20:33:43 143048 ++++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp 2011/10/26 20:41:06 143049 +@@ -29,6 +29,7 @@ + #include "clang/AST/DeclTemplate.h" + #include "clang/AST/Mangle.h" + #include "clang/AST/RecordLayout.h" ++#include "clang/AST/RecursiveASTVisitor.h" + #include "clang/Basic/Diagnostic.h" + #include "clang/Basic/SourceManager.h" + #include "clang/Basic/TargetInfo.h" +@@ -858,6 +859,62 @@ + } + } + ++namespace { ++ struct FunctionIsDirectlyRecursive : ++ public RecursiveASTVisitor { ++ const StringRef Name; ++ bool Result; ++ FunctionIsDirectlyRecursive(const FunctionDecl *F) : ++ Name(F->getName()), Result(false) { ++ } ++ typedef RecursiveASTVisitor Base; ++ ++ bool TraverseCallExpr(CallExpr *E) { ++ const Decl *D = E->getCalleeDecl(); ++ if (!D) ++ return true; ++ AsmLabelAttr *Attr = D->getAttr(); ++ if (!Attr) ++ return true; ++ if (Name == Attr->getLabel()) { ++ Result = true; ++ return false; ++ } ++ return true; ++ } ++ }; ++} ++ ++// isTriviallyRecursiveViaAsm - Check if this function calls another ++// decl that, because of the asm attribute, ends up pointing to itself. ++bool ++CodeGenModule::isTriviallyRecursiveViaAsm(const FunctionDecl *F) { ++ if (getCXXABI().getMangleContext().shouldMangleDeclName(F)) ++ return false; ++ ++ FunctionIsDirectlyRecursive Walker(F); ++ Walker.TraverseFunctionDecl(const_cast(F)); ++ return Walker.Result; ++} ++ ++bool ++CodeGenModule::shouldEmitFunction(const FunctionDecl *F) { ++ if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage) ++ return true; ++ if (F->hasAttr()) ++ return true; ++ if (CodeGenOpts.OptimizationLevel == 0) ++ 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; ++} ++ + void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { + const ValueDecl *D = cast(GD.getDecl()); + +@@ -868,10 +925,7 @@ + if (const FunctionDecl *Function = dyn_cast(D)) { + // At -O0, don't generate IR for functions with available_externally + // linkage. +- if (CodeGenOpts.OptimizationLevel == 0 && +- !Function->hasAttr() && +- getFunctionLinkage(Function) +- == llvm::Function::AvailableExternallyLinkage) ++ if (!shouldEmitFunction(Function)) + return; + + if (const CXXMethodDecl *Method = dyn_cast(D)) { +--- cfe/trunk/lib/CodeGen/CodeGenModule.h 2011/10/26 20:33:43 143048 ++++ cfe/trunk/lib/CodeGen/CodeGenModule.h 2011/10/26 20:41:06 143049 +@@ -324,6 +324,8 @@ + void createOpenCLRuntime(); + void createCUDARuntime(); + ++ bool isTriviallyRecursiveViaAsm(const FunctionDecl *F); ++ bool shouldEmitFunction(const FunctionDecl *F); + llvm::LLVMContext &VMContext; + + /// @name Cache for Blocks Runtime Globals diff --git a/llvm-pr9614-part2.patch b/llvm-pr9614-part2.patch new file mode 100644 index 0000000..06a8c32 --- /dev/null +++ b/llvm-pr9614-part2.patch @@ -0,0 +1,24 @@ +--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp 2011/10/28 20:43:47 143221 ++++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp 2011/10/28 20:43:56 143222 +@@ -901,18 +901,15 @@ + CodeGenModule::shouldEmitFunction(const FunctionDecl *F) { + if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage) + return true; +- if (F->hasAttr()) +- return true; +- if (CodeGenOpts.OptimizationLevel == 0) ++ if (CodeGenOpts.OptimizationLevel == 0 && ++ !F->hasAttr()) + 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/llvm.changes b/llvm.changes index 981db4b..240bb86 100644 --- a/llvm.changes +++ b/llvm.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Fri Oct 28 20:54:16 UTC 2011 - idonmez@suse.com + +- Add llvm-pr9614-part{1,2}.patch to fix LLVM PR9614 + ------------------------------------------------------------------- Fri Oct 28 08:23:03 UTC 2011 - idonmez@suse.com diff --git a/llvm.spec b/llvm.spec index 9a5f5b0..31623a0 100644 --- a/llvm.spec +++ b/llvm.spec @@ -40,6 +40,9 @@ Patch1: set-revision.patch Patch2: clang-cmake-lib.patch # PATCH-FIX-OPENSUSE assume-opensuse.patch idoenmez@suse.de -- Always enable openSUSE/SUSE features Patch3: assume-opensuse.patch +# PATCH-FIX-UPSTREAM llvm-pr9614-part1.patch idoenmez@suse.de -- Fix LLVM PR9614 +Patch4: llvm-pr9614-part1.patch +Patch5: llvm-pr9614-part2.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: autoconf BuildRequires: automake @@ -132,6 +135,11 @@ This package contains vim plugins for LLVM like syntax highlighting. %patch2 %patch3 +pushd tools/clang +%patch4 -p2 +%patch5 -p2 +popd + sed -i s,SVN_REVISION,\"%{_revision}\",g tools/clang/lib/Basic/Version.cpp %build