When a function takes a variable number of pointer arguments, with a zero

pointer marking the end of the list, the zero *must* be cast to the pointer
type.  An un-cast zero is a 32-bit int, and at least on x86_64, gcc will
not extend the zero to 64 bits, thus allowing the upper 32 bits to be
random junk.

The new END_WITH_NULL macro may be used to annotate a such a function
so that GCC (version 4 or newer) will detect the use of un-casted zero
at compile time.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23888 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jeff Cohen 2005-10-23 04:37:20 +00:00
parent 8b7f14e970
commit 66c5fd6c53
27 changed files with 290 additions and 262 deletions

View File

@ -221,7 +221,7 @@ else
endif
endif
CXX.Flags += $(CXXFLAGS)
CXX.Flags += $(CXXFLAGS) -Wformat
C.Flags += $(CFLAGS)
CPP.Flags += $(CPPFLAGS)
LD.Flags += $(LDFLAGS)

View File

@ -37,7 +37,8 @@ using namespace llvm;
static Function *CreateFibFunction(Module *M) {
// Create the fib function and insert it into module M. This function is said
// to return an int and take an int parameter.
Function *FibF = M->getOrInsertFunction("fib", Type::IntTy, Type::IntTy, 0);
Function *FibF = M->getOrInsertFunction("fib", Type::IntTy, Type::IntTy,
(Type *)0);
// Add a basic block to the function.
BasicBlock *BB = new BasicBlock("EntryBlock", FibF);

View File

@ -51,7 +51,8 @@ int main() {
// Create the add1 function entry and insert this entry into module M. The
// function will have a return type of "int" and take an argument of "int".
// The '0' terminates the list of argument types.
Function *Add1F = M->getOrInsertFunction("add1", Type::IntTy, Type::IntTy, 0);
Function *Add1F = M->getOrInsertFunction("add1", Type::IntTy, Type::IntTy,
(Type *)0);
// Add a basic block to the function. As before, it automatically inserts
// because of the last argument.
@ -76,7 +77,7 @@ int main() {
// Now we going to create function `foo', which returns an int and takes no
// arguments.
Function *FooF = M->getOrInsertFunction("foo", Type::IntTy, 0);
Function *FooF = M->getOrInsertFunction("foo", Type::IntTy, (Type *)0);
// Add a basic block to the FooF function.
BB = new BasicBlock("EntryBlock", FooF);

View File

@ -33,7 +33,8 @@ static Function* createAdd1(Module* M)
// Create the add1 function entry and insert this entry into module M. The
// function will have a return type of "int" and take an argument of "int".
// The '0' terminates the list of argument types.
Function *Add1F = M->getOrInsertFunction("add1", Type::IntTy, Type::IntTy, 0);
Function *Add1F = M->getOrInsertFunction("add1", Type::IntTy, Type::IntTy,
(Type *)0);
// Add a basic block to the function. As before, it automatically inserts
// because of the last argument.
@ -61,7 +62,8 @@ static Function *CreateFibFunction(Module *M)
{
// Create the fib function and insert it into module M. This function is said
// to return an int and take an int parameter.
Function *FibF = M->getOrInsertFunction("fib", Type::IntTy, Type::IntTy, 0);
Function *FibF = M->getOrInsertFunction("fib", Type::IntTy, Type::IntTy,
(Type *)0);
// Add a basic block to the function.
BasicBlock *BB = new BasicBlock("EntryBlock", FibF);

View File

@ -22,6 +22,7 @@
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@ -111,7 +112,8 @@ public:
/// table. If it does not exist, add a prototype for the function and return
/// it. This version of the method takes a null terminated list of function
/// arguments, which makes it easier for clients to use.
Function *getOrInsertFunction(const std::string &Name, const Type *RetTy,...);
Function *getOrInsertFunction(const std::string &Name, const Type *RetTy,...)
END_WITH_NULL;
/// getFunction - Look up the specified function in the module symbol table.
/// If it does not exist, return null.

View File

@ -21,6 +21,7 @@
#define LLVM_SUPPORT_COMMANDLINE_H
#include "llvm/Support/type_traits.h"
#include "llvm/Support/DataTypes.h"
#include <string>
#include <vector>
#include <utility>
@ -335,7 +336,7 @@ public:
template<class DataType>
ValuesClass<DataType> values(const char *Arg, DataType Val, const char *Desc,
...) {
...) END_WITH_NULL {
va_list ValueArgs;
va_start(ValueArgs, Desc);
ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs);

View File

@ -98,4 +98,10 @@ typedef signed int ssize_t;
# define UINT64_MAX 0xffffffffffffffffULL
#endif
#if __GNUC__ > 3
#define END_WITH_NULL __attribute__((sentinel))
#else
#define END_WITH_NULL
#endif
#endif /* SUPPORT_DATATYPES_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* A Bison parser, made by GNU Bison 1.875c. */
/* A Bison parser, made by GNU Bison 1.875d. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -218,7 +218,7 @@
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 865 "/proj/llvm/build/../llvm/lib/AsmParser/llvmAsmParser.y"
#line 866 "/usr/home/llvm/obj/../lib/AsmParser/llvmAsmParser.y"
typedef union YYSTYPE {
llvm::Module *ModuleVal;
llvm::Function *FunctionVal;
@ -258,7 +258,7 @@ typedef union YYSTYPE {
llvm::Instruction::OtherOps OtherOpVal;
llvm::Module::Endianness Endianness;
} YYSTYPE;
/* Line 1275 of yacc.c. */
/* Line 1285 of yacc.c. */
#line 263 "llvmAsmParser.tab.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1

View File

@ -766,7 +766,7 @@ static PATypeHolder HandleUpRefs(const Type *ty) {
const Type* ArgTy = F->getFunctionType()->getReturnType();
const Type* ArgTyPtr = PointerType::get(ArgTy);
Function* NF = Result->getOrInsertFunction("llvm.va_start",
RetTy, ArgTyPtr, 0);
RetTy, ArgTyPtr, (Type *)0);
while (!F->use_empty()) {
CallInst* CI = cast<CallInst>(F->use_back());
@ -791,7 +791,7 @@ static PATypeHolder HandleUpRefs(const Type *ty) {
const Type* ArgTy = F->getFunctionType()->getParamType(0);
const Type* ArgTyPtr = PointerType::get(ArgTy);
Function* NF = Result->getOrInsertFunction("llvm.va_end",
RetTy, ArgTyPtr, 0);
RetTy, ArgTyPtr, (Type *)0);
while (!F->use_empty()) {
CallInst* CI = cast<CallInst>(F->use_back());
@ -818,7 +818,8 @@ static PATypeHolder HandleUpRefs(const Type *ty) {
const Type* ArgTy = F->getFunctionType()->getReturnType();
const Type* ArgTyPtr = PointerType::get(ArgTy);
Function* NF = Result->getOrInsertFunction("llvm.va_copy",
RetTy, ArgTyPtr, ArgTyPtr, 0);
RetTy, ArgTyPtr, ArgTyPtr,
(Type *)0);
while (!F->use_empty()) {
CallInst* CI = cast<CallInst>(F->use_back());
@ -2074,7 +2075,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
ObsoleteVarArgs = true;
const Type* ArgTy = $2->getType();
Function* NF = CurModule.CurrentModule->
getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0);
getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0);
//b = vaarg a, t ->
//foo = alloca 1 of t
@ -2093,7 +2094,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
ObsoleteVarArgs = true;
const Type* ArgTy = $2->getType();
Function* NF = CurModule.CurrentModule->
getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0);
getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0);
//b = vanext a, t ->
//foo = alloca 1 of t

View File

@ -680,7 +680,8 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
break;
case 32: { //VANext_old
const Type* ArgTy = getValue(iType, Oprnds[0])->getType();
Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0);
Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy,
(Type *)0);
//b = vanext a, t ->
//foo = alloca 1 of t
@ -700,7 +701,8 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
}
case 33: { //VAArg_old
const Type* ArgTy = getValue(iType, Oprnds[0])->getType();
Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0);
Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy,
(Type *)0);
//b = vaarg a, t ->
//foo = alloca 1 of t

View File

@ -181,7 +181,7 @@ static ModuleProvider* CheckVarargs(ModuleProvider* MP) {
const Type* ArgTy = F->getFunctionType()->getReturnType();
const Type* ArgTyPtr = PointerType::get(ArgTy);
Function* NF = M->getOrInsertFunction("llvm.va_start",
RetTy, ArgTyPtr, 0);
RetTy, ArgTyPtr, (Type *)0);
for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;)
if (CallInst* CI = dyn_cast<CallInst>(*I++)) {
@ -204,7 +204,7 @@ static ModuleProvider* CheckVarargs(ModuleProvider* MP) {
const Type* ArgTy = F->getFunctionType()->getParamType(0);
const Type* ArgTyPtr = PointerType::get(ArgTy);
Function* NF = M->getOrInsertFunction("llvm.va_end",
RetTy, ArgTyPtr, 0);
RetTy, ArgTyPtr, (Type *)0);
for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;)
if (CallInst* CI = dyn_cast<CallInst>(*I++)) {
@ -230,7 +230,7 @@ static ModuleProvider* CheckVarargs(ModuleProvider* MP) {
const Type* ArgTy = F->getFunctionType()->getReturnType();
const Type* ArgTyPtr = PointerType::get(ArgTy);
Function* NF = M->getOrInsertFunction("llvm.va_copy",
RetTy, ArgTyPtr, ArgTyPtr, 0);
RetTy, ArgTyPtr, ArgTyPtr, (Type *)0);
for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;)
if (CallInst* CI = dyn_cast<CallInst>(*I++)) {

View File

@ -110,7 +110,8 @@ void DefaultIntrinsicLowering::AddPrototypes(Module &M) {
case Intrinsic::memset:
M.getOrInsertFunction("memset", PointerType::get(Type::SByteTy),
PointerType::get(Type::SByteTy),
Type::IntTy, (--(--I->arg_end()))->getType(), 0);
Type::IntTy, (--(--I->arg_end()))->getType(),
(Type *)0);
break;
case Intrinsic::isunordered:
EnsureFunctionExists(M, "isunordered", I->arg_begin(), I->arg_end(),

View File

@ -924,7 +924,8 @@ static void runChild(Module *M, const std::vector<std::string> &Arguments,
// If the program didn't explicitly call exit, call exit now, for the program.
// This ensures that any atexit handlers get called correctly.
Function *Exit = M->getOrInsertFunction("exit", Type::VoidTy, Type::IntTy, 0);
Function *Exit = M->getOrInsertFunction("exit", Type::VoidTy, Type::IntTy,
(Type *)0);
std::vector<GenericValue> Args;
GenericValue ResultGV;

View File

@ -204,32 +204,33 @@ bool LowerSetJmp::doInitialization(Module& M)
// void __llvm_sjljeh_init_setjmpmap(void**)
InitSJMap = M.getOrInsertFunction("__llvm_sjljeh_init_setjmpmap",
Type::VoidTy, SBPPTy, NULL);
Type::VoidTy, SBPPTy, (Type *)0);
// void __llvm_sjljeh_destroy_setjmpmap(void**)
DestroySJMap = M.getOrInsertFunction("__llvm_sjljeh_destroy_setjmpmap",
Type::VoidTy, SBPPTy, NULL);
Type::VoidTy, SBPPTy, (Type *)0);
// void __llvm_sjljeh_add_setjmp_to_map(void**, void*, unsigned)
AddSJToMap = M.getOrInsertFunction("__llvm_sjljeh_add_setjmp_to_map",
Type::VoidTy, SBPPTy, SBPTy,
Type::UIntTy, NULL);
Type::UIntTy, (Type *)0);
// void __llvm_sjljeh_throw_longjmp(int*, int)
ThrowLongJmp = M.getOrInsertFunction("__llvm_sjljeh_throw_longjmp",
Type::VoidTy, SBPTy, Type::IntTy, NULL);
Type::VoidTy, SBPTy, Type::IntTy,
(Type *)0);
// unsigned __llvm_sjljeh_try_catching_longjmp_exception(void **)
TryCatchLJ =
M.getOrInsertFunction("__llvm_sjljeh_try_catching_longjmp_exception",
Type::UIntTy, SBPPTy, NULL);
Type::UIntTy, SBPPTy, (Type *)0);
// bool __llvm_sjljeh_is_longjmp_exception()
IsLJException = M.getOrInsertFunction("__llvm_sjljeh_is_longjmp_exception",
Type::BoolTy, NULL);
Type::BoolTy, (Type *)0);
// int __llvm_sjljeh_get_longjmp_value()
GetLJValue = M.getOrInsertFunction("__llvm_sjljeh_get_longjmp_value",
Type::IntTy, NULL);
Type::IntTy, (Type *)0);
return true;
}

View File

@ -311,7 +311,8 @@ public:
if (!memcpy_func) {
const Type *SBP = PointerType::get(Type::SByteTy);
memcpy_func = M->getOrInsertFunction("llvm.memcpy", Type::VoidTy,SBP, SBP,
Type::UIntTy, Type::UIntTy, 0);
Type::UIntTy, Type::UIntTy,
(Type *)0);
}
return memcpy_func;
}
@ -319,7 +320,7 @@ public:
Function* get_floorf() {
if (!floorf_func)
floorf_func = M->getOrInsertFunction("floorf", Type::FloatTy,
Type::FloatTy, 0);
Type::FloatTy, (Type *)0);
return floorf_func;
}

View File

@ -40,7 +40,7 @@ static void getTriggerCode(Module *M, BasicBlock *BB, int MethNo, Value *pathNo,
const Type *PIntTy = PointerType::get(Type::IntTy);
Function *trigMeth = M->getOrInsertFunction("trigger", Type::VoidTy,
Type::IntTy, Type::IntTy,
PIntTy, PIntTy, 0);
PIntTy, PIntTy, (Type *)0);
assert(trigMeth && "trigger method could not be inserted!");
vector<Value *> trargs;

View File

@ -156,7 +156,8 @@ void InstLoops::findAndInstrumentBackEdges(Function &F){
}
bool InstLoops::doInitialization (Module &M) {
inCountMth = M.getOrInsertFunction("llvm_first_trigger", Type::VoidTy, 0);
inCountMth = M.getOrInsertFunction("llvm_first_trigger", Type::VoidTy,
(Type *)0);
return true; // Module was modified.
}

View File

@ -189,7 +189,8 @@ bool ProfilePaths::runOnFunction(Function &F){
// IN THEIR INITIALIZE METHOD!!
Function *initialize =
F.getParent()->getOrInsertFunction("reoptimizerInitialize", Type::VoidTy,
PointerType::get(Type::IntTy), 0);
PointerType::get(Type::IntTy),
(Type *)0);
std::vector<Value *> trargs;
trargs.push_back(threshold);

View File

@ -26,7 +26,8 @@ void llvm::InsertProfilingInitCall(Function *MainFn, const char *FnName,
const PointerType *UIntPtr = PointerType::get(Type::UIntTy);
Module &M = *MainFn->getParent();
Function *InitFn = M.getOrInsertFunction(FnName, Type::IntTy, Type::IntTy,
ArgVTy, UIntPtr, Type::UIntTy, 0);
ArgVTy, UIntPtr, Type::UIntTy,
(Type *)0);
// This could force argc and argv into programs that wouldn't otherwise have
// them, but instead we just pass null values in.

View File

@ -46,7 +46,7 @@ static void InsertInstrumentationCall (BasicBlock *BB,
<< "\", \"" << FnName << "\", " << BBNumber << ")\n");
Module &M = *BB->getParent ()->getParent ();
Function *InstrFn = M.getOrInsertFunction (FnName, Type::VoidTy,
Type::UIntTy, 0);
Type::UIntTy, (Type *)0);
std::vector<Value*> Args (1);
Args[0] = ConstantUInt::get (Type::UIntTy, BBNumber);

View File

@ -130,17 +130,18 @@ void ExternalFuncs::doInitialization(Module &M) {
// uint (sbyte*)
HashPtrFunc = M.getOrInsertFunction("HashPointerToSeqNum", Type::UIntTy, SBP,
0);
(Type *)0);
// void (sbyte*)
ReleasePtrFunc = M.getOrInsertFunction("ReleasePointerSeqNum",
Type::VoidTy, SBP, 0);
Type::VoidTy, SBP, (Type *)0);
RecordPtrFunc = M.getOrInsertFunction("RecordPointer",
Type::VoidTy, SBP, 0);
Type::VoidTy, SBP, (Type *)0);
PushOnEntryFunc = M.getOrInsertFunction("PushPointerSet", Type::VoidTy, 0);
PushOnEntryFunc = M.getOrInsertFunction("PushPointerSet", Type::VoidTy,
(Type *)0);
ReleaseOnReturnFunc = M.getOrInsertFunction("ReleasePointersPopSet",
Type::VoidTy, 0);
Type::VoidTy, (Type *)0);
}

View File

@ -109,10 +109,11 @@ bool LowerGC::doInitialization(Module &M) {
// If the program is using read/write barriers, find the implementations of
// them from the GC runtime library.
if (GCReadInt) // Make: sbyte* %llvm_gc_read(sbyte**)
GCRead = M.getOrInsertFunction("llvm_gc_read", VoidPtr, VoidPtr, VoidPtrPtr, 0);
GCRead = M.getOrInsertFunction("llvm_gc_read", VoidPtr, VoidPtr, VoidPtrPtr,
(Type *)0);
if (GCWriteInt) // Make: void %llvm_gc_write(sbyte*, sbyte**)
GCWrite = M.getOrInsertFunction("llvm_gc_write", Type::VoidTy,
VoidPtr, VoidPtr, VoidPtrPtr, 0);
VoidPtr, VoidPtr, VoidPtrPtr, (Type *)0);
// If the program has GC roots, get or create the global root list.
if (GCRootInt) {

View File

@ -83,7 +83,7 @@ bool LowerAllocations::doInitialization(Module &M) {
MallocFunc = M.getOrInsertFunction("malloc", FT);
}
if (FreeFunc == 0)
FreeFunc = M.getOrInsertFunction("free" , Type::VoidTy, SBPTy, 0);
FreeFunc = M.getOrInsertFunction("free" , Type::VoidTy, SBPTy, (Type *)0);
return true;
}

View File

@ -124,14 +124,14 @@ bool LowerInvoke::doInitialization(Module &M) {
Constant::getNullValue(PtrJBList),
"llvm.sjljeh.jblist", &M);
SetJmpFn = M.getOrInsertFunction("llvm.setjmp", Type::IntTy,
PointerType::get(JmpBufTy), NULL);
PointerType::get(JmpBufTy), (Type *)0);
LongJmpFn = M.getOrInsertFunction("llvm.longjmp", Type::VoidTy,
PointerType::get(JmpBufTy),
Type::IntTy, NULL);
Type::IntTy, (Type *)0);
}
// We need the 'write' and 'abort' functions for both models.
AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, NULL);
AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, (Type *)0);
// Unfortunately, 'write' can end up being prototyped in several different
// ways. If the user defines a three (or more) operand function named 'write'
@ -148,7 +148,7 @@ bool LowerInvoke::doInitialization(Module &M) {
WriteFn = 0;
} else {
WriteFn = M.getOrInsertFunction("write", Type::VoidTy, Type::IntTy,
VoidPtrTy, Type::IntTy, NULL);
VoidPtrTy, Type::IntTy, (Type *)0);
}
return true;
}

View File

@ -666,7 +666,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
Function *resolverFunc =
Safe->getOrInsertFunction("getPointerToNamedFunction",
PointerType::get(Type::SByteTy),
PointerType::get(Type::SByteTy), 0);
PointerType::get(Type::SByteTy), (Type *)0);
// Use the function we just added to get addresses of functions we need.
for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) {

View File

@ -96,7 +96,8 @@ int main(int argc, char **argv, char * const *envp) {
// If the program didn't explicitly call exit, call exit now, for the program.
// This ensures that any atexit handlers get called correctly.
Function *Exit = MP->getModule()->getOrInsertFunction("exit", Type::VoidTy,
Type::IntTy, 0);
Type::IntTy,
(Type *)0);
std::vector<GenericValue> Args;
GenericValue ResultGV;