r272971 - [CodeGen] Fix a segfault caused by pass_object_size.
George Burgess IV via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 16 16:06:04 PDT 2016
Author: gbiv
Date: Thu Jun 16 18:06:04 2016
New Revision: 272971
URL: http://llvm.org/viewvc/llvm-project?rev=272971&view=rev
Log:
[CodeGen] Fix a segfault caused by pass_object_size.
This patch fixes a bug where we'd segfault (in some cases) if we saw a
variadic function with one or more pass_object_size arguments.
Differential Revision: http://reviews.llvm.org/D17462
Modified:
cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h
cfe/trunk/lib/CodeGen/CGCall.cpp
cfe/trunk/lib/CodeGen/CGExprCXX.cpp
cfe/trunk/lib/CodeGen/CGVTables.cpp
cfe/trunk/test/CodeGen/pass-object-size.c
cfe/trunk/test/CodeGenCXX/pass-object-size.cpp
Modified: cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h?rev=272971&r1=272970&r2=272971&view=diff
==============================================================================
--- cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h (original)
+++ cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h Thu Jun 16 18:06:04 2016
@@ -16,8 +16,10 @@
#ifndef LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
#define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
+#include "clang/AST/Attr.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CharUnits.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/ADT/FoldingSet.h"
@@ -25,8 +27,6 @@
#include <cassert>
namespace clang {
-class Decl;
-
namespace CodeGen {
/// ABIArgInfo - Helper class to encapsulate information about how a
@@ -393,23 +393,34 @@ public:
/// Compute the arguments required by the given formal prototype,
/// given that there may be some additional, non-formal arguments
/// in play.
+ ///
+ /// If FD is not null, this will consider pass_object_size params in FD.
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
- unsigned additional) {
+ unsigned additional,
+ const FunctionDecl *FD) {
if (!prototype->isVariadic()) return All;
+ if (FD)
+ additional += std::count_if(FD->param_begin(), FD->param_end(),
+ [](const ParmVarDecl *PVD) {
+ return PVD->hasAttr<PassObjectSizeAttr>();
+ });
return RequiredArgs(prototype->getNumParams() + additional);
}
- static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
- return forPrototypePlus(prototype, 0);
+ static RequiredArgs forPrototype(const FunctionProtoType *prototype,
+ const FunctionDecl *FD) {
+ return forPrototypePlus(prototype, 0, FD);
}
- static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) {
- return forPrototype(prototype.getTypePtr());
+ static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype,
+ const FunctionDecl *FD) {
+ return forPrototype(prototype.getTypePtr(), FD);
}
static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
- unsigned additional) {
- return forPrototypePlus(prototype.getTypePtr(), additional);
+ unsigned additional,
+ const FunctionDecl *FD) {
+ return forPrototypePlus(prototype.getTypePtr(), additional, FD);
}
bool allowsOptionalArgs() const { return NumRequired != ~0U; }
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=272971&r1=272970&r2=272971&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Thu Jun 16 18:06:04 2016
@@ -141,7 +141,8 @@ arrangeLLVMFunctionInfo(CodeGenTypes &CG
CanQual<FunctionProtoType> FTP,
const FunctionDecl *FD) {
SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
- RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, prefix.size());
+ RequiredArgs Required =
+ RequiredArgs::forPrototypePlus(FTP, prefix.size(), FD);
// FIXME: Kill copy.
appendParameterTypes(CGT, prefix, paramInfos, FTP, FD);
CanQualType resultType = FTP->getReturnType().getUnqualifiedType();
@@ -149,7 +150,7 @@ arrangeLLVMFunctionInfo(CodeGenTypes &CG
return CGT.arrangeLLVMFunctionInfo(resultType, instanceMethod,
/*chainCall=*/false, prefix,
FTP->getExtInfo(), paramInfos,
- required);
+ Required);
}
/// Arrange the argument and result information for a value of the
@@ -338,7 +339,7 @@ CodeGenTypes::arrangeCXXConstructorCall(
ArgTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
CanQual<FunctionProtoType> FPT = GetFormalType(D);
- RequiredArgs Required = RequiredArgs::forPrototypePlus(FPT, 1 + ExtraArgs);
+ RequiredArgs Required = RequiredArgs::forPrototypePlus(FPT, 1 + ExtraArgs, D);
GlobalDecl GD(D, CtorKind);
CanQualType ResultType = TheCXXABI.HasThisReturn(GD)
? ArgTypes.front()
@@ -555,10 +556,11 @@ CodeGenTypes::arrangeBlockFunctionDeclar
auto paramInfos = getExtParameterInfosForCall(proto, 1, params.size());
auto argTypes = getArgTypesForDeclaration(Context, params);
- return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
- /*instanceMethod*/ false, /*chainCall*/ false,
- argTypes, proto->getExtInfo(), paramInfos,
- RequiredArgs::forPrototypePlus(proto, 1));
+ return arrangeLLVMFunctionInfo(
+ GetReturnType(proto->getReturnType()),
+ /*instanceMethod*/ false, /*chainCall*/ false, argTypes,
+ proto->getExtInfo(), paramInfos,
+ RequiredArgs::forPrototypePlus(proto, 1, nullptr));
}
const CGFunctionInfo &
Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=272971&r1=272970&r2=272971&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Thu Jun 16 18:06:04 2016
@@ -54,7 +54,7 @@ commonEmitCXXMemberOrOperatorCall(CodeGe
}
const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
- RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, Args.size());
+ RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, Args.size(), MD);
// And the rest of the call args.
if (CE) {
@@ -324,10 +324,11 @@ CodeGenFunction::EmitCXXMemberPointerCal
// Push the this ptr.
Args.add(RValue::get(ThisPtrForCall), ThisType);
- RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, 1);
-
+ RequiredArgs required =
+ RequiredArgs::forPrototypePlus(FPT, 1, /*FD=*/nullptr);
+
// And the rest of the call args
- EmitCallArgs(Args, FPT, E->arguments(), E->getDirectCallee());
+ EmitCallArgs(Args, FPT, E->arguments());
return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required),
Callee, ReturnValue, Args);
}
Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=272971&r1=272970&r2=272971&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Thu Jun 16 18:06:04 2016
@@ -290,9 +290,8 @@ void CodeGenFunction::EmitCallAndReturnF
const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
#ifndef NDEBUG
- const CGFunctionInfo &CallFnInfo =
- CGM.getTypes().arrangeCXXMethodCall(CallArgs, FPT,
- RequiredArgs::forPrototypePlus(FPT, 1));
+ const CGFunctionInfo &CallFnInfo = CGM.getTypes().arrangeCXXMethodCall(
+ CallArgs, FPT, RequiredArgs::forPrototypePlus(FPT, 1, MD));
assert(CallFnInfo.getRegParm() == CurFnInfo->getRegParm() &&
CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() &&
CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention());
Modified: cfe/trunk/test/CodeGen/pass-object-size.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/pass-object-size.c?rev=272971&r1=272970&r2=272971&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/pass-object-size.c (original)
+++ cfe/trunk/test/CodeGen/pass-object-size.c Thu Jun 16 18:06:04 2016
@@ -351,3 +351,18 @@ void test13() {
ObjectSize0(++p);
ObjectSize0(p++);
}
+
+// There was a bug where variadic functions with pass_object_size would cause
+// problems in the form of failed assertions.
+void my_sprintf(char *const c __attribute__((pass_object_size(0))), ...) {}
+
+// CHECK-LABEL: define void @test14
+void test14(char *c) {
+ // CHECK: @llvm.objectsize
+ // CHECK: call void (i8*, i64, ...) @my_sprintf
+ my_sprintf(c);
+
+ // CHECK: @llvm.objectsize
+ // CHECK: call void (i8*, i64, ...) @my_sprintf
+ my_sprintf(c, 1, 2, 3);
+}
Modified: cfe/trunk/test/CodeGenCXX/pass-object-size.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/pass-object-size.cpp?rev=272971&r1=272970&r2=272971&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/pass-object-size.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/pass-object-size.cpp Thu Jun 16 18:06:04 2016
@@ -53,3 +53,30 @@ namespace delegate {
// CHECK: define void @_ZN8delegate1AC1EPvU17pass_object_size0({{[^,]*}}, i8*{{[^,]*}}, i64{{[^,]*}})
// CHECK: call void @_ZN8delegate1AC2EPvU17pass_object_size0({{[^,]*}}, i8*{{[^,]*}}, i64{{[^,]*}})
}
+
+namespace variadic {
+// We had an issue where variadic member/operator calls with pass_object_size
+// would cause crashes.
+
+struct AsCtor {
+ AsCtor(const char *const c __attribute__((pass_object_size(0))), double a,
+ ...) {}
+};
+
+struct AsMember {
+ void bar(const char *const c __attribute__((pass_object_size(0))), double a,
+ ...) {}
+ void operator()(const char *const c __attribute__((pass_object_size(0))),
+ double a, ...) {}
+};
+
+// CHECK-LABEL: define void @_ZN8variadic4testEv()
+void test() {
+ // CHECK-RE: call{{[^@]+}}@_ZN8variadic6AsCtorC1EPKcU17pass_object_size0dz
+ AsCtor("a", 1.0);
+ // CHECK-RE: call{{[^@]+}}@_ZN8variadic8AsMember3barEPKcU17pass_object_size0dz
+ AsMember{}.bar("a", 1.0);
+ // CHECK-RE: call{{[^@]+}}@_ZN8variadic8AsMemberclEPKcU17pass_object_size0dz
+ AsMember{}("a", 1.0);
+}
+}
More information about the cfe-commits
mailing list