Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -7002,6 +7002,36 @@ SourceRange(CondRHS->getLocStart(), RHSExpr->getLocEnd())); } +/// Modify the nullability kind of the result type of a binary conditional +/// expression. +static QualType modifyNullability(QualType ResTy, Expr *RHSExpr, + ASTContext &Ctx) { + if (!ResTy->isPointerType()) + return ResTy; + + auto GetNullability = [&Ctx](QualType Ty) { + Optional Kind = Ty->getNullability(Ctx); + if (Kind) + return *Kind; + return NullabilityKind::Unspecified; + }; + + // Change the result type only if the conditional expression is nullable and + // the RHS is nonnull. + if (GetNullability(ResTy) != NullabilityKind::Nullable) + return ResTy; + + NullabilityKind NewKind = GetNullability(RHSExpr->getType()); + + if (NewKind != NullabilityKind::NonNull) + return ResTy; + + // Create a new AttributedType with the new nullability kind. + QualType NewTy = ResTy.getDesugaredType(Ctx); + auto NewAttr = AttributedType::getNullabilityAttrKind(NewKind); + return Ctx.getAttributedType(NewAttr, NewTy, NewTy); +} + /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null /// in the case of a the GNU conditional expr extension. ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, @@ -7088,6 +7118,7 @@ ConditionalOperator(Cond.get(), QuestionLoc, LHS.get(), ColonLoc, RHS.get(), result, VK, OK); + result = modifyNullability(result, RHSExpr, Context); return new (Context) BinaryConditionalOperator( commonExpr, opaqueValue, Cond.get(), LHS.get(), RHS.get(), QuestionLoc, ColonLoc, result, VK, OK); Index: test/Sema/nullability.c =================================================================== --- test/Sema/nullability.c +++ test/Sema/nullability.c @@ -128,3 +128,11 @@ accepts_nonnull_1(ptr); // expected-warning{{implicit conversion from nullable pointer 'int * _Nullable' to non-nullable pointer type 'int * _Nonnull'}} } + +// Check nullability of binary conditional expressions. +void modify_nullability(int c) { + int * _Nullable p0; + int * _Nonnull p1; + + int * _Nonnull p2 = p0 ?: p1; // no warnings here. +}