Check that constructor calls are null-safe.
Nullable values should not passed to parameters marked nonnull.
For example:
```
struct Foo {
Foo(int * _Nonnull);
};
void f(int * _Nullable x) {
Foo f(x); // unsafe
}
```
PiperOrigin-RevId: 475348593
diff --git a/nullability_verification/pointer_nullability_diagnosis.cc b/nullability_verification/pointer_nullability_diagnosis.cc
index c8c6a75..4fedd7a 100644
--- a/nullability_verification/pointer_nullability_diagnosis.cc
+++ b/nullability_verification/pointer_nullability_diagnosis.cc
@@ -99,6 +99,20 @@
: llvm::None;
}
+llvm::Optional<const Stmt*> diagnoseConstructExpr(
+ const CXXConstructExpr* CE, const MatchFinder::MatchResult& Result,
+ const Environment& Env) {
+ auto ConstructorParamTypes = CE->getConstructor()
+ ->getType()
+ ->getAs<FunctionProtoType>()
+ ->getParamTypes();
+ ArrayRef<const Expr*> ConstructorArgs(CE->getArgs(), CE->getNumArgs());
+ return isIncompatibleArgumentList(ConstructorParamTypes, ConstructorArgs, Env,
+ *Result.Context)
+ ? llvm::Optional<const Stmt*>(CE)
+ : llvm::None;
+}
+
llvm::Optional<const Stmt*> diagnoseReturn(
const ReturnStmt* RS, const MatchFinder::MatchResult& Result,
const Environment& Env) {
@@ -122,6 +136,7 @@
// Check compatibility of parameter assignments
.CaseOfCFGStmt<CallExpr>(isCallExpr(), diagnoseCallExpr)
.CaseOfCFGStmt<ReturnStmt>(isPointerReturn(), diagnoseReturn)
+ .CaseOfCFGStmt<CXXConstructExpr>(isConstructExpr(), diagnoseConstructExpr)
.Build();
}