diff --git a/llvm/lib/Transforms/Utils/CtorUtils.cpp b/llvm/lib/Transforms/Utils/CtorUtils.cpp --- a/llvm/lib/Transforms/Utils/CtorUtils.cpp +++ b/llvm/lib/Transforms/Utils/CtorUtils.cpp @@ -98,8 +98,9 @@ if (isa(CS->getOperand(1))) continue; - // Must have a function or null ptr. - if (!isa(CS->getOperand(1))) + // Can only handle global constructors with no arguments. + Function *F = dyn_cast(CS->getOperand(1)); + if (!F || F->arg_size() != 0) return nullptr; // Init priority must be standard. diff --git a/llvm/lib/Transforms/Utils/Evaluator.cpp b/llvm/lib/Transforms/Utils/Evaluator.cpp --- a/llvm/lib/Transforms/Utils/Evaluator.cpp +++ b/llvm/lib/Transforms/Utils/Evaluator.cpp @@ -629,6 +629,8 @@ /// function. bool Evaluator::EvaluateFunction(Function *F, Constant *&RetVal, const SmallVectorImpl &ActualArgs) { + assert(ActualArgs.size() == F->arg_size() && "wrong number of arguments"); + // Check to see if this function is already executing (recursion). If so, // bail out. TODO: we might want to accept limited recursion. if (is_contained(CallStack, F)) diff --git a/llvm/test/Transforms/GlobalOpt/global-constructor-opaque-ptr.ll b/llvm/test/Transforms/GlobalOpt/global-constructor-opaque-ptr.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/GlobalOpt/global-constructor-opaque-ptr.ll @@ -0,0 +1,14 @@ +; RUN: opt -passes=globalopt -S < %s | FileCheck %s + +; CHECK: @f1 +; CHECK: @f2 + +@llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @f1, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @f2, ptr null }] + +define void @f1(i32 %args) { + ret void +} + +define i32 @f2(i32 %args) { + ret i32 0 +}