forked from OSchip/llvm-project
[analyzer] Do not crash on callback for call_once passed by value
https://bugs.llvm.org/show_bug.cgi?id=37312 rdar://40270582 Differential Revision: https://reviews.llvm.org/D46913 llvm-svn: 332422
This commit is contained in:
parent
9a40ff502f
commit
faa03f4aca
|
@ -254,21 +254,24 @@ static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M,
|
||||||
|
|
||||||
QualType Ty = Callback->getType();
|
QualType Ty = Callback->getType();
|
||||||
DeclRefExpr *Call = M.makeDeclRefExpr(Callback);
|
DeclRefExpr *Call = M.makeDeclRefExpr(Callback);
|
||||||
CastKind CK;
|
Expr *SubExpr;
|
||||||
if (Ty->isRValueReferenceType()) {
|
if (Ty->isRValueReferenceType()) {
|
||||||
CK = CK_LValueToRValue;
|
SubExpr = M.makeImplicitCast(
|
||||||
} else {
|
Call, Ty.getNonReferenceType(), CK_LValueToRValue);
|
||||||
assert(Ty->isLValueReferenceType());
|
} else if (Ty->isLValueReferenceType() &&
|
||||||
CK = CK_FunctionToPointerDecay;
|
Call->getType()->isFunctionType()) {
|
||||||
Ty = C.getPointerType(Ty.getNonReferenceType());
|
Ty = C.getPointerType(Ty.getNonReferenceType());
|
||||||
|
SubExpr = M.makeImplicitCast(Call, Ty, CK_FunctionToPointerDecay);
|
||||||
|
} else if (Ty->isLValueReferenceType()
|
||||||
|
&& Call->getType()->isPointerType()
|
||||||
|
&& Call->getType()->getPointeeType()->isFunctionType()){
|
||||||
|
SubExpr = Call;
|
||||||
|
} else {
|
||||||
|
llvm_unreachable("Unexpected state");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new (C)
|
return new (C)
|
||||||
CallExpr(C, M.makeImplicitCast(Call, Ty.getNonReferenceType(), CK),
|
CallExpr(C, SubExpr, CallArgs, C.VoidTy, VK_RValue, SourceLocation());
|
||||||
/*args=*/CallArgs,
|
|
||||||
/*QualType=*/C.VoidTy,
|
|
||||||
/*ExprValueType=*/VK_RValue,
|
|
||||||
/*SourceLocation=*/SourceLocation());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
|
static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
|
||||||
|
|
|
@ -403,3 +403,12 @@ void callback_with_implicit_cast() {
|
||||||
std::once_flag flag;
|
std::once_flag flag;
|
||||||
call_once(flag, callback_taking_func, callback_with_implicit_cast);
|
call_once(flag, callback_taking_func, callback_with_implicit_cast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::once_flag another_once_flag;
|
||||||
|
typedef void (*my_callback_t)(int *);
|
||||||
|
my_callback_t callback;
|
||||||
|
int global_int;
|
||||||
|
|
||||||
|
void rdar40270582() {
|
||||||
|
call_once(another_once_flag, callback, &global_int);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue