fcloutier created this revision.
Herald added a subscriber: jfb.
Herald added a reviewer: aaron.ballman.
fcloutier requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added subscribers: cfe-commits, sstefan1.
Herald added a project: clang.

This change creates Sema::BuildImplicitCast, which the rest of Sema now uses to
create implicit casts. The main change in terms of interface is that now,
technically, creating an implicit cast could fail. However, the current
implementation of BuildImplicitCast never does because it simply calls
ImplicitCastExpr::Create.

Nevertheless, Sema users of ImplicitCastExpr::Create, and their downstream users
in several cases, were updated to allow failing, except in some cases (such as
in OpenMP) where existing code already didn't bother to check implicit casts
failing.

rdar://74050758


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D96196

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaExprObjC.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaObjCProperty.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp

Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -7236,8 +7236,11 @@
                                                                 FoundResult)) {
         if (DiagnoseUseOfDecl(Fn, Arg->getBeginLoc()))
           return ExprError();
-
-        Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn);
+        ExprResult OverloadArg =
+            FixOverloadedFunctionReference(Arg, FoundResult, Fn);
+        if (OverloadArg.isInvalid())
+          return ExprError();
+        Arg = OverloadArg.get();
         ArgType = Arg->getType();
       } else
         return ExprError();
@@ -7290,7 +7293,11 @@
         if (DiagnoseUseOfDecl(Fn, Arg->getBeginLoc()))
           return ExprError();
 
-        Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn);
+        ExprResult OverloadArg =
+            FixOverloadedFunctionReference(Arg, FoundResult, Fn);
+        if (OverloadArg.isInvalid())
+          return ExprError();
+        Arg = OverloadArg.get();
         ArgType = Arg->getType();
       } else
         return ExprError();
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -3187,13 +3187,16 @@
     NeedSecondOverloadResolution = false;
     // Promote "AsRvalue" to the heap, since we now need this
     // expression node to persist.
-    Value =
-        ImplicitCastExpr::Create(S.Context, Value->getType(), CK_NoOp, Value,
-                                 nullptr, VK_XValue, FPOptionsOverride());
-
+    ExprResult AsXValue = S.BuildImplicitCastExpr(
+        Value, Value->getType(), CK_NoOp, VK_XValue, FPOptionsOverride());
     // Complete type-checking the initialization of the return type
     // using the constructor we found.
-    Res = Seq.Perform(S, Entity, Kind, Value);
+    if (AsXValue.isInvalid())
+      Res = ExprError();
+    else {
+      Expr *E = AsXValue.get();
+      Res = Seq.Perform(S, Entity, Kind, E);
+    }
   }
 
   return NeedSecondOverloadResolution;
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -1754,8 +1754,9 @@
       // FIXME: FixOverloadedFunctionReference has side-effects; we shouldn't
       // be calling it from within an NDEBUG block.
       assert(S.Context.hasSameType(
-        FromType,
-        S.FixOverloadedFunctionReference(From, AccessPair, Fn)->getType()));
+          FromType, S.FixOverloadedFunctionReference(From, AccessPair, Fn)
+                        .get()
+                        ->getType()));
     } else {
       return false;
     }
@@ -5935,10 +5936,12 @@
     if (Result.isInvalid())
       return true;
     // Record usage of conversion in an implicit cast.
-    From = ImplicitCastExpr::Create(SemaRef.Context, Result.get()->getType(),
-                                    CK_UserDefinedConversion, Result.get(),
-                                    nullptr, Result.get()->getValueKind(),
-                                    SemaRef.CurFPFeatureOverrides());
+    Result = SemaRef.BuildImplicitCastExpr(
+        Result.get(), Result.get()->getType(), CK_UserDefinedConversion,
+        Result.get()->getValueKind(), SemaRef.CurFPFeatureOverrides());
+    if (Result.isInvalid())
+      return true;
+    From = Result.get();
   }
   return false;
 }
@@ -5965,10 +5968,12 @@
   if (Result.isInvalid())
     return true;
   // Record usage of conversion in an implicit cast.
-  From = ImplicitCastExpr::Create(SemaRef.Context, Result.get()->getType(),
-                                  CK_UserDefinedConversion, Result.get(),
-                                  nullptr, Result.get()->getValueKind(),
-                                  SemaRef.CurFPFeatureOverrides());
+  Result = SemaRef.BuildImplicitCastExpr(
+      Result.get(), Result.get()->getType(), CK_UserDefinedConversion,
+      Result.get()->getValueKind(), SemaRef.CurFPFeatureOverrides());
+  if (Result.isInvalid())
+    return true;
+  From = Result.get();
   return false;
 }
 
@@ -12409,11 +12414,13 @@
   // for both.
   DiagnoseUseOfDecl(Found, E->getExprLoc());
   CheckAddressOfMemberAccess(E, DAP);
-  Expr *Fixed = FixOverloadedFunctionReference(E, DAP, Found);
-  if (DoFunctionPointerConverion && Fixed->getType()->isFunctionType())
-    SrcExpr = DefaultFunctionArrayConversion(Fixed, /*Diagnose=*/false);
+  ExprResult Fixed = FixOverloadedFunctionReference(E, DAP, Found);
+  if (Fixed.isInvalid())
+    return false;
+  if (DoFunctionPointerConverion && Fixed.get()->getType()->isFunctionType())
+    SrcExpr = DefaultFunctionArrayConversion(Fixed.get(), /*Diagnose=*/false);
   else
-    SrcExpr = Fixed;
+    SrcExpr = Fixed.get();
   return true;
 }
 
@@ -12553,10 +12560,10 @@
 
     // Fix the expression to refer to 'fn'.
     SingleFunctionExpression =
-        FixOverloadedFunctionReference(SrcExpr.get(), found, fn);
+        FixOverloadedFunctionReference(SrcExpr, found, fn);
 
     // If desired, do function-to-pointer decay.
-    if (doFunctionPointerConverion) {
+    if (!SingleFunctionExpression.isInvalid() && doFunctionPointerConverion) {
       SingleFunctionExpression =
         DefaultFunctionArrayLvalueConversion(SingleFunctionExpression.get());
       if (SingleFunctionExpression.isInvalid()) {
@@ -13075,10 +13082,13 @@
     SemaRef.CheckUnresolvedLookupAccess(ULE, (*Best)->FoundDecl);
     if (SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc()))
       return ExprError();
-    Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl);
-    return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, RParenLoc,
-                                         ExecConfig, /*IsExecConfig=*/false,
-                                         (*Best)->IsADLCandidate);
+    ExprResult OverloadFn =
+        SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl);
+    if (OverloadFn.isInvalid())
+      return ExprError();
+    return SemaRef.BuildResolvedCallExpr(
+        OverloadFn.get(), FDecl, LParenLoc, Args, RParenLoc, ExecConfig,
+        /*IsExecConfig=*/false, (*Best)->IsADLCandidate);
   }
 
   case OR_No_Viable_Function: {
@@ -13133,10 +13143,13 @@
     // We emitted an error for the unavailable/deleted function call but keep
     // the call in the AST.
     FunctionDecl *FDecl = (*Best)->Function;
-    Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl);
-    return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, RParenLoc,
-                                         ExecConfig, /*IsExecConfig=*/false,
-                                         (*Best)->IsADLCandidate);
+    ExprResult OverloadFn =
+        SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl);
+    if (OverloadFn.isInvalid())
+      return ExprError();
+    return SemaRef.BuildResolvedCallExpr(
+        OverloadFn.get(), FDecl, LParenLoc, Args, RParenLoc, ExecConfig,
+        /*IsExecConfig=*/false, (*Best)->IsADLCandidate);
   }
   }
 
@@ -14342,7 +14355,11 @@
     if (!Succeeded)
       return BuildRecoveryExpr(chooseRecoveryType(CandidateSet, &Best));
 
-    MemExprE = FixOverloadedFunctionReference(MemExprE, FoundDecl, Method);
+    ExprResult OverloadFn =
+        FixOverloadedFunctionReference(MemExprE, FoundDecl, Method);
+    if (OverloadFn.isInvalid())
+      return BuildRecoveryExpr(chooseRecoveryType(CandidateSet, &Best));
+    MemExprE = OverloadFn.get();
 
     // If overload resolution picked a static member, build a
     // non-member call based on that function.
@@ -14604,9 +14621,11 @@
     if (Call.isInvalid())
       return ExprError();
     // Record usage of conversion in an implicit cast.
-    Call = ImplicitCastExpr::Create(
-        Context, Call.get()->getType(), CK_UserDefinedConversion, Call.get(),
-        nullptr, VK_RValue, CurFPFeatureOverrides());
+    Call = BuildImplicitCastExpr(Call.get(), Call.get()->getType(),
+                                 CK_UserDefinedConversion, VK_RValue,
+                                 CurFPFeatureOverrides());
+    if (Call.isInvalid())
+      return ExprError();
 
     return BuildCallExpr(S, Call.get(), LParenLoc, Args, RParenLoc);
   }
@@ -14990,37 +15009,46 @@
 /// perhaps a '&' around it). We have resolved the overloaded function
 /// to the function declaration Fn, so patch up the expression E to
 /// refer (possibly indirectly) to Fn. Returns the new expr.
-Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
-                                           FunctionDecl *Fn) {
+ExprResult Sema::FixOverloadedFunctionReference(ExprResult ER,
+                                                DeclAccessPair Found,
+                                                FunctionDecl *Fn) {
+  Expr *E = ER.get();
   if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
-    Expr *SubExpr = FixOverloadedFunctionReference(PE->getSubExpr(),
-                                                   Found, Fn);
-    if (SubExpr == PE->getSubExpr())
+    ExprResult SubExpr =
+        FixOverloadedFunctionReference(PE->getSubExpr(), Found, Fn);
+    if (SubExpr.isInvalid())
+      return ExprError();
+    if (SubExpr.get() == PE->getSubExpr())
       return PE;
 
-    return new (Context) ParenExpr(PE->getLParen(), PE->getRParen(), SubExpr);
+    return new (Context)
+        ParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.get());
   }
 
   if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
-    Expr *SubExpr = FixOverloadedFunctionReference(ICE->getSubExpr(),
-                                                   Found, Fn);
+    ExprResult SubExpr =
+        FixOverloadedFunctionReference(ICE->getSubExpr(), Found, Fn);
+    if (SubExpr.isInvalid())
+      return ExprError();
     assert(Context.hasSameType(ICE->getSubExpr()->getType(),
-                               SubExpr->getType()) &&
+                               SubExpr.get()->getType()) &&
            "Implicit cast type cannot be determined from overload");
     assert(ICE->path_empty() && "fixing up hierarchy conversion?");
-    if (SubExpr == ICE->getSubExpr())
+    if (SubExpr.get() == ICE->getSubExpr())
       return ICE;
 
-    return ImplicitCastExpr::Create(Context, ICE->getType(), ICE->getCastKind(),
-                                    SubExpr, nullptr, ICE->getValueKind(),
-                                    CurFPFeatureOverrides());
+    return BuildImplicitCastExpr(SubExpr.get(), ICE->getType(),
+                                 ICE->getCastKind(), ICE->getValueKind(),
+                                 CurFPFeatureOverrides());
   }
 
   if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) {
     if (!GSE->isResultDependent()) {
-      Expr *SubExpr =
+      ExprResult SubExpr =
           FixOverloadedFunctionReference(GSE->getResultExpr(), Found, Fn);
-      if (SubExpr == GSE->getResultExpr())
+      if (SubExpr.isInvalid())
+        return ExprError();
+      if (SubExpr.get() == GSE->getResultExpr())
         return GSE;
 
       // Replace the resulting type information before rebuilding the generic
@@ -15028,7 +15056,7 @@
       ArrayRef<Expr *> A = GSE->getAssocExprs();
       SmallVector<Expr *, 4> AssocExprs(A.begin(), A.end());
       unsigned ResultIdx = GSE->getResultIndex();
-      AssocExprs[ResultIdx] = SubExpr;
+      AssocExprs[ResultIdx] = SubExpr.get();
 
       return GenericSelectionExpr::Create(
           Context, GSE->getGenericLoc(), GSE->getControllingExpr(),
@@ -15052,15 +15080,17 @@
         // Fix the subexpression, which really has to be an
         // UnresolvedLookupExpr holding an overloaded member function
         // or template.
-        Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(),
-                                                       Found, Fn);
-        if (SubExpr == UnOp->getSubExpr())
+        ExprResult SubExpr =
+            FixOverloadedFunctionReference(UnOp->getSubExpr(), Found, Fn);
+        if (SubExpr.isInvalid())
+          return ExprError();
+        if (SubExpr.get() == UnOp->getSubExpr())
           return UnOp;
 
-        assert(isa<DeclRefExpr>(SubExpr)
-               && "fixed to something other than a decl ref");
-        assert(cast<DeclRefExpr>(SubExpr)->getQualifier()
-               && "fixed to a member ref with no nested name qualifier");
+        assert(isa<DeclRefExpr>(SubExpr.get()) &&
+               "fixed to something other than a decl ref");
+        assert(cast<DeclRefExpr>(SubExpr.get())->getQualifier() &&
+               "fixed to a member ref with no nested name qualifier");
 
         // We have taken the address of a pointer to member
         // function. Perform the computation here so that we get the
@@ -15073,20 +15103,23 @@
         if (Context.getTargetInfo().getCXXABI().isMicrosoft())
           (void)isCompleteType(UnOp->getOperatorLoc(), MemPtrType);
 
-        return UnaryOperator::Create(
-            Context, SubExpr, UO_AddrOf, MemPtrType, VK_RValue, OK_Ordinary,
-            UnOp->getOperatorLoc(), false, CurFPFeatureOverrides());
+        return UnaryOperator::Create(Context, SubExpr.get(), UO_AddrOf,
+                                     MemPtrType, VK_RValue, OK_Ordinary,
+                                     UnOp->getOperatorLoc(), false,
+                                     CurFPFeatureOverrides());
       }
     }
-    Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(),
-                                                   Found, Fn);
-    if (SubExpr == UnOp->getSubExpr())
+    ExprResult SubExpr =
+        FixOverloadedFunctionReference(UnOp->getSubExpr(), Found, Fn);
+    if (SubExpr.isInvalid())
+      return ExprError();
+    if (SubExpr.get() == UnOp->getSubExpr())
       return UnOp;
 
-    return UnaryOperator::Create(Context, SubExpr, UO_AddrOf,
-                                 Context.getPointerType(SubExpr->getType()),
-                                 VK_RValue, OK_Ordinary, UnOp->getOperatorLoc(),
-                                 false, CurFPFeatureOverrides());
+    return UnaryOperator::Create(
+        Context, SubExpr.get(), UO_AddrOf,
+        Context.getPointerType(SubExpr.get()->getType()), VK_RValue,
+        OK_Ordinary, UnOp->getOperatorLoc(), false, CurFPFeatureOverrides());
   }
 
   if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
@@ -15154,9 +15187,3 @@
 
   llvm_unreachable("Invalid reference to overloaded function");
 }
-
-ExprResult Sema::FixOverloadedFunctionReference(ExprResult E,
-                                                DeclAccessPair Found,
-                                                FunctionDecl *Fn) {
-  return FixOverloadedFunctionReference(E.get(), Found, Fn);
-}
Index: clang/lib/Sema/SemaOpenMP.cpp
===================================================================
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -15589,12 +15589,12 @@
       if (!BasePath.empty()) {
         LHS = S.DefaultLvalueConversion(LHS.get());
         RHS = S.DefaultLvalueConversion(RHS.get());
-        LHS = ImplicitCastExpr::Create(
-            Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
-            LHS.get()->getValueKind(), FPOptionsOverride());
-        RHS = ImplicitCastExpr::Create(
-            Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
-            RHS.get()->getValueKind(), FPOptionsOverride());
+        LHS = S.BuildImplicitCastExpr(
+            LHS.get(), PtrRedTy, CK_UncheckedDerivedToBase,
+            LHS.get()->getValueKind(), FPOptionsOverride(), &BasePath);
+        RHS = S.BuildImplicitCastExpr(
+            RHS.get(), PtrRedTy, CK_UncheckedDerivedToBase,
+            RHS.get()->getValueKind(), FPOptionsOverride(), &BasePath);
       }
       FunctionProtoType::ExtProtoInfo EPI;
       QualType Params[] = {PtrRedTy, PtrRedTy};
Index: clang/lib/Sema/SemaObjCProperty.cpp
===================================================================
--- clang/lib/Sema/SemaObjCProperty.cpp
+++ clang/lib/Sema/SemaObjCProperty.cpp
@@ -1464,25 +1464,24 @@
           DeclRefExpr(Context, SelfDecl, false, SelfDecl->getType(), VK_LValue,
                       PropertyDiagLoc);
       MarkDeclRefReferenced(SelfExpr);
-      Expr *LoadSelfExpr = ImplicitCastExpr::Create(
-          Context, SelfDecl->getType(), CK_LValueToRValue, SelfExpr, nullptr,
-          VK_RValue, FPOptionsOverride());
-      Expr *IvarRefExpr =
-        new (Context) ObjCIvarRefExpr(Ivar,
-                                      Ivar->getUsageType(SelfDecl->getType()),
-                                      PropertyDiagLoc,
-                                      Ivar->getLocation(),
-                                      LoadSelfExpr, true, true);
-      ExprResult Res = PerformCopyInitialization(
-          InitializedEntity::InitializeResult(PropertyDiagLoc,
-                                              getterMethod->getReturnType(),
-                                              /*NRVO=*/false),
-          PropertyDiagLoc, IvarRefExpr);
-      if (!Res.isInvalid()) {
-        Expr *ResExpr = Res.getAs<Expr>();
-        if (ResExpr)
-          ResExpr = MaybeCreateExprWithCleanups(ResExpr);
-        PIDecl->setGetterCXXConstructor(ResExpr);
+      ExprResult LoadSelfExpr = BuildImplicitCastExpr(
+          SelfExpr, SelfDecl->getType(), CK_LValueToRValue, VK_RValue,
+          FPOptionsOverride());
+      if (!LoadSelfExpr.isInvalid()) {
+        Expr *IvarRefExpr = new (Context) ObjCIvarRefExpr(
+            Ivar, Ivar->getUsageType(SelfDecl->getType()), PropertyDiagLoc,
+            Ivar->getLocation(), LoadSelfExpr.get(), true, true);
+        ExprResult Res = PerformCopyInitialization(
+            InitializedEntity::InitializeResult(PropertyDiagLoc,
+                                                getterMethod->getReturnType(),
+                                                /*NRVO=*/false),
+            PropertyDiagLoc, IvarRefExpr);
+        if (!Res.isInvalid()) {
+          Expr *ResExpr = Res.getAs<Expr>();
+          if (ResExpr)
+            ResExpr = MaybeCreateExprWithCleanups(ResExpr);
+          PIDecl->setGetterCXXConstructor(ResExpr);
+        }
       }
     }
     if (property->hasAttr<NSReturnsNotRetainedAttr>() &&
@@ -1527,39 +1526,39 @@
           DeclRefExpr(Context, SelfDecl, false, SelfDecl->getType(), VK_LValue,
                       PropertyDiagLoc);
       MarkDeclRefReferenced(SelfExpr);
-      Expr *LoadSelfExpr = ImplicitCastExpr::Create(
-          Context, SelfDecl->getType(), CK_LValueToRValue, SelfExpr, nullptr,
-          VK_RValue, FPOptionsOverride());
-      Expr *lhs =
-        new (Context) ObjCIvarRefExpr(Ivar,
-                                      Ivar->getUsageType(SelfDecl->getType()),
-                                      PropertyDiagLoc,
-                                      Ivar->getLocation(),
-                                      LoadSelfExpr, true, true);
-      ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
-      ParmVarDecl *Param = (*P);
-      QualType T = Param->getType().getNonReferenceType();
-      DeclRefExpr *rhs = new (Context)
-          DeclRefExpr(Context, Param, false, T, VK_LValue, PropertyDiagLoc);
-      MarkDeclRefReferenced(rhs);
-      ExprResult Res = BuildBinOp(S, PropertyDiagLoc,
-                                  BO_Assign, lhs, rhs);
-      if (property->getPropertyAttributes() &
-          ObjCPropertyAttribute::kind_atomic) {
-        Expr *callExpr = Res.getAs<Expr>();
-        if (const CXXOperatorCallExpr *CXXCE =
-              dyn_cast_or_null<CXXOperatorCallExpr>(callExpr))
-          if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
-            if (!FuncDecl->isTrivial())
-              if (property->getType()->isReferenceType()) {
-                Diag(PropertyDiagLoc,
-                     diag::err_atomic_property_nontrivial_assign_op)
-                    << property->getType();
-                Diag(FuncDecl->getBeginLoc(), diag::note_callee_decl)
-                    << FuncDecl;
-              }
+      ExprResult LoadSelfExpr =
+          BuildImplicitCastExpr(SelfExpr, SelfDecl->getType(),
+                                CK_LValueToRValue, VK_RValue,
+                                FPOptionsOverride())
+              .get();
+      if (!LoadSelfExpr.isInvalid()) {
+        Expr *lhs = new (Context) ObjCIvarRefExpr(
+            Ivar, Ivar->getUsageType(SelfDecl->getType()), PropertyDiagLoc,
+            Ivar->getLocation(), LoadSelfExpr.get(), true, true);
+        ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
+        ParmVarDecl *Param = (*P);
+        QualType T = Param->getType().getNonReferenceType();
+        DeclRefExpr *rhs = new (Context)
+            DeclRefExpr(Context, Param, false, T, VK_LValue, PropertyDiagLoc);
+        MarkDeclRefReferenced(rhs);
+        ExprResult Res = BuildBinOp(S, PropertyDiagLoc, BO_Assign, lhs, rhs);
+        if (property->getPropertyAttributes() &
+            ObjCPropertyAttribute::kind_atomic) {
+          Expr *callExpr = Res.getAs<Expr>();
+          if (const CXXOperatorCallExpr *CXXCE =
+                  dyn_cast_or_null<CXXOperatorCallExpr>(callExpr))
+            if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
+              if (!FuncDecl->isTrivial())
+                if (property->getType()->isReferenceType()) {
+                  Diag(PropertyDiagLoc,
+                       diag::err_atomic_property_nontrivial_assign_op)
+                      << property->getType();
+                  Diag(FuncDecl->getBeginLoc(), diag::note_callee_decl)
+                      << FuncDecl;
+                }
+        }
+        PIDecl->setSetterCXXAssignment(Res.getAs<Expr>());
       }
-      PIDecl->setSetterCXXAssignment(Res.getAs<Expr>());
     }
   }
 
Index: clang/lib/Sema/SemaLambda.cpp
===================================================================
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -679,13 +679,14 @@
     ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(retValue);
 
     Expr *E = (cleanups ? cleanups->getSubExpr() : retValue);
-    E = ImplicitCastExpr::Create(S.Context, returnType, CK_IntegralCast, E,
-                                 /*base path*/ nullptr, VK_RValue,
-                                 FPOptionsOverride());
-    if (cleanups) {
-      cleanups->setSubExpr(E);
-    } else {
-      ret->setRetValue(E);
+    ExprResult IC = S.BuildImplicitCastExpr(E, returnType, CK_IntegralCast,
+                                            VK_RValue, FPOptionsOverride());
+    if (!IC.isInvalid()) {
+      if (cleanups) {
+        cleanups->setSubExpr(E);
+      } else {
+        ret->setRetValue(E);
+      }
     }
   }
 }
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -2881,48 +2881,40 @@
       PromotedCharTy = Context.getPromotedIntegerType(CharTy);
     unsigned PromotedCharTyWidth = Context.getTypeSize(PromotedCharTy);
 
+    uint64_t StrLen;
+    std::string TmpStr;
+    StringRef StrRef;
     if (StringLiteral *SL = dyn_cast<StringLiteral>(SubExpr)) {
       // Get the length of the string.
-      uint64_t StrLen = SL->getLength();
-      if (cast<ConstantArrayType>(AT)->getSize().ult(StrLen))
-        StrLen = cast<ConstantArrayType>(AT)->getSize().getZExtValue();
-      StructuredList->resizeInits(Context, StrLen);
-
-      // Build a literal for each character in the string, and put them into
-      // the init list.
-      for (unsigned i = 0, e = StrLen; i != e; ++i) {
-        llvm::APInt CodeUnit(PromotedCharTyWidth, SL->getCodeUnit(i));
-        Expr *Init = new (Context) IntegerLiteral(
-            Context, CodeUnit, PromotedCharTy, SubExpr->getExprLoc());
-        if (CharTy != PromotedCharTy)
-          Init =
-              ImplicitCastExpr::Create(Context, CharTy, CK_IntegralCast, Init,
-                                       nullptr, VK_RValue, FPOptionsOverride());
-        StructuredList->updateInit(Context, i, Init);
-      }
+      StrRef = SL->getString();
+      StrLen = SL->getLength();
     } else {
       ObjCEncodeExpr *E = cast<ObjCEncodeExpr>(SubExpr);
-      std::string Str;
-      Context.getObjCEncodingForType(E->getEncodedType(), Str);
+      Context.getObjCEncodingForType(E->getEncodedType(), TmpStr);
+      StrRef = TmpStr;
 
       // Get the length of the string.
-      uint64_t StrLen = Str.size();
-      if (cast<ConstantArrayType>(AT)->getSize().ult(StrLen))
-        StrLen = cast<ConstantArrayType>(AT)->getSize().getZExtValue();
-      StructuredList->resizeInits(Context, StrLen);
-
-      // Build a literal for each character in the string, and put them into
-      // the init list.
-      for (unsigned i = 0, e = StrLen; i != e; ++i) {
-        llvm::APInt CodeUnit(PromotedCharTyWidth, Str[i]);
-        Expr *Init = new (Context) IntegerLiteral(
-            Context, CodeUnit, PromotedCharTy, SubExpr->getExprLoc());
-        if (CharTy != PromotedCharTy)
-          Init =
-              ImplicitCastExpr::Create(Context, CharTy, CK_IntegralCast, Init,
-                                       nullptr, VK_RValue, FPOptionsOverride());
-        StructuredList->updateInit(Context, i, Init);
-      }
+      StrLen = TmpStr.size();
+    }
+
+    if (cast<ConstantArrayType>(AT)->getSize().ult(StrLen))
+      StrLen = cast<ConstantArrayType>(AT)->getSize().getZExtValue();
+    StructuredList->resizeInits(Context, StrLen);
+
+    // Build a literal for each character in the string, and put them into
+    // the init list.
+    for (unsigned i = 0, e = StrLen; i != e; ++i) {
+      llvm::APInt CodeUnit(PromotedCharTyWidth, StrRef[i]);
+      ExprResult Init = new (Context) IntegerLiteral(
+          Context, CodeUnit, PromotedCharTy, SubExpr->getExprLoc());
+      if (CharTy != PromotedCharTy)
+        Init =
+            SemaRef.BuildImplicitCastExpr(Init.get(), CharTy, CK_IntegralCast,
+                                          VK_RValue, FPOptionsOverride());
+      if (Init.isInvalid())
+        hadError = true;
+      else
+        StructuredList->updateInit(Context, i, Init.get());
     }
   }
 
@@ -8182,9 +8174,9 @@
               (Step->Kind == SK_CastDerivedToBaseXValue ?
                    VK_XValue :
                    VK_RValue);
-      CurInit = ImplicitCastExpr::Create(S.Context, Step->Type,
-                                         CK_DerivedToBase, CurInit.get(),
-                                         &BasePath, VK, FPOptionsOverride());
+      CurInit =
+          S.BuildImplicitCastExpr(CurInit.get(), Step->Type, CK_DerivedToBase,
+                                  VK, FPOptionsOverride(), &BasePath);
       break;
     }
 
@@ -8325,9 +8317,9 @@
       if (CreatedObject && checkAbstractType(CurInit.get()->getType()))
         return ExprError();
 
-      CurInit = ImplicitCastExpr::Create(
-          S.Context, CurInit.get()->getType(), CastKind, CurInit.get(), nullptr,
-          CurInit.get()->getValueKind(), S.CurFPFeatureOverrides());
+      CurInit = S.BuildImplicitCastExpr(CurInit.get(), CurInit.get()->getType(),
+                                        CastKind, CurInit.get()->getValueKind(),
+                                        S.CurFPFeatureOverrides());
 
       if (shouldBindAsTemporary(Entity))
         // The overall entity is temporary, so this expression should be
@@ -8676,9 +8668,9 @@
       break;
 
     case SK_ProduceObjCObject:
-      CurInit = ImplicitCastExpr::Create(
-          S.Context, Step->Type, CK_ARCProduceObject, CurInit.get(), nullptr,
-          VK_RValue, FPOptionsOverride());
+      CurInit = S.BuildImplicitCastExpr(CurInit.get(), Step->Type,
+                                        CK_ARCProduceObject, VK_RValue,
+                                        FPOptionsOverride());
       break;
 
     case SK_StdInitializerList: {
@@ -8732,9 +8724,10 @@
           // Case 1b and 1c
           // No cast from integer to sampler is needed.
           if (!Var->hasGlobalStorage()) {
-            CurInit = ImplicitCastExpr::Create(
-                S.Context, Step->Type, CK_LValueToRValue, Init,
-                /*BasePath=*/nullptr, VK_RValue, FPOptionsOverride());
+            CurInit =
+                S.BuildImplicitCastExpr(Init, Step->Type, CK_LValueToRValue,
+                                        VK_RValue, FPOptionsOverride())
+                    .get();
             break;
           }
           // Case 1a
Index: clang/lib/Sema/SemaExprObjC.cpp
===================================================================
--- clang/lib/Sema/SemaExprObjC.cpp
+++ clang/lib/Sema/SemaExprObjC.cpp
@@ -4466,13 +4466,18 @@
     return ACR_okay;
 
   // If the result is +1, consume it here.
-  case ACC_plusOne:
-    castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(),
-                                        CK_ARCConsumeObject, castExpr, nullptr,
-                                        VK_RValue, FPOptionsOverride());
+  case ACC_plusOne: {
+    ExprResult ImpCast = BuildImplicitCastExpr(castExpr, castExpr->getType(),
+                                               CK_ARCConsumeObject, VK_RValue,
+                                               FPOptionsOverride())
+                             .get();
+    if (ImpCast.isInvalid())
+      return ACR_error;
+    castExpr = ImpCast.get();
     Cleanup.setExprNeedsCleanups(true);
     return ACR_okay;
   }
+  }
 
   // If this is a non-implicit cast from id or block type to a
   // CoreFoundation type, delay complaining in case the cast is used
@@ -4693,12 +4698,17 @@
       SubExpr = maybeUndoReclaimObject(SubExpr);
       break;
 
-    case OBC_BridgeRetained:
+    case OBC_BridgeRetained: {
       // Produce the object before casting it.
-      SubExpr = ImplicitCastExpr::Create(Context, FromType, CK_ARCProduceObject,
-                                         SubExpr, nullptr, VK_RValue,
-                                         FPOptionsOverride());
+      ExprResult ImpCast =
+          BuildImplicitCastExpr(SubExpr, FromType, CK_ARCProduceObject,
+                                VK_RValue, FPOptionsOverride())
+              .get();
+      if (ImpCast.isInvalid())
+        return ExprError();
+      SubExpr = ImpCast.get();
       break;
+    }
 
     case OBC_BridgeTransfer: {
       bool br = isKnownName("CFBridgingRetain");
@@ -4729,14 +4739,13 @@
     return ExprError();
   }
 
-  Expr *Result = new (Context) ObjCBridgedCastExpr(LParenLoc, Kind, CK,
-                                                   BridgeKeywordLoc,
-                                                   TSInfo, SubExpr);
+  ExprResult Result = new (Context) ObjCBridgedCastExpr(
+      LParenLoc, Kind, CK, BridgeKeywordLoc, TSInfo, SubExpr);
 
   if (MustConsume) {
     Cleanup.setExprNeedsCleanups(true);
-    Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,
-                                      nullptr, VK_RValue, FPOptionsOverride());
+    Result = BuildImplicitCastExpr(Result.get(), T, CK_ARCConsumeObject,
+                                   VK_RValue, FPOptionsOverride());
   }
 
   return Result;
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -3958,11 +3958,11 @@
     if (Result.isInvalid())
       return ExprError();
     // Record usage of conversion in an implicit cast.
-    Result = ImplicitCastExpr::Create(S.Context, Result.get()->getType(),
-                                      CK_UserDefinedConversion, Result.get(),
-                                      nullptr, Result.get()->getValueKind(),
-                                      S.CurFPFeatureOverrides());
-
+    Result = S.BuildImplicitCastExpr(
+        Result.get(), Result.get()->getType(), CK_UserDefinedConversion,
+        Result.get()->getValueKind(), S.CurFPFeatureOverrides());
+    if (Result.isInvalid())
+      return ExprError();
     return S.MaybeBindToTemporary(Result.get());
   }
   }
@@ -4123,7 +4123,10 @@
     if (DiagnoseUseOfDecl(Fn, From->getBeginLoc()))
       return ExprError();
 
-    From = FixOverloadedFunctionReference(From, Found, Fn);
+    ExprResult OverloadResult = FixOverloadedFunctionReference(From, Found, Fn);
+    if (OverloadResult.isInvalid())
+      return ExprError();
+    From = OverloadResult.get();
     FromType = From->getType();
   }
 
@@ -4141,9 +4144,10 @@
   case ICK_Identity:
     if (const AtomicType *FromAtomic = FromType->getAs<AtomicType>()) {
       FromType = FromAtomic->getValueType().getUnqualifiedType();
-      From = ImplicitCastExpr::Create(Context, FromType, CK_AtomicToNonAtomic,
-                                      From, /*BasePath=*/nullptr, VK_RValue,
-                                      FPOptionsOverride());
+      ExprResult FromRes = BuildImplicitCastExpr(
+          From, FromType, CK_AtomicToNonAtomic, VK_RValue, FPOptionsOverride());
+      assert(!FromRes.isInvalid() && "Can't perform identity conversion?!");
+      From = FromRes.get();
     }
     break;
 
@@ -4311,6 +4315,8 @@
     if (Kind == CK_BlockPointerToObjCPointerCast) {
       ExprResult E = From;
       (void) PrepareCastToObjCObjectPointer(E);
+      if (E.isInvalid())
+        return ExprError();
       From = E.get();
     }
     if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
@@ -6334,8 +6340,12 @@
       return QualType();
     }
 
-    LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy));
-    RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy));
+    CastKind LHSCK = PrepareScalarCast(LHS, ResTy);
+    CastKind RHSCK = PrepareScalarCast(RHS, ResTy);
+    if (LHS.isInvalid() || RHS.isInvalid())
+      return QualType();
+    LHS = ImpCastExprToType(LHS.get(), ResTy, LHSCK);
+    RHS = ImpCastExprToType(RHS.get(), ResTy, RHSCK);
 
     return ResTy;
   }
@@ -6892,8 +6902,8 @@
 
     CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
                                    : CK_ARCReclaimReturnedObject);
-    return ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr,
-                                    VK_RValue, FPOptionsOverride());
+    return BuildImplicitCastExpr(E, E->getType(), ck, VK_RValue,
+                                 FPOptionsOverride());
   }
 
   if (E->getType().isDestructedType() == QualType::DK_nontrivial_c_struct)
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -714,16 +714,19 @@
   // C++ [conv.lval]p3:
   //   If T is cv std::nullptr_t, the result is a null pointer constant.
   CastKind CK = T->isNullPtrType() ? CK_NullToPointer : CK_LValueToRValue;
-  Res = ImplicitCastExpr::Create(Context, T, CK, E, nullptr, VK_RValue,
-                                 CurFPFeatureOverrides());
+  Res = BuildImplicitCastExpr(E, T, CK, VK_RValue, CurFPFeatureOverrides());
+  if (Res.isInvalid())
+    return Res;
 
   // C11 6.3.2.1p2:
   //   ... if the lvalue has atomic type, the value has the non-atomic version
   //   of the type of the lvalue ...
   if (const AtomicType *Atomic = T->getAs<AtomicType>()) {
     T = Atomic->getValueType().getUnqualifiedType();
-    Res = ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic, Res.get(),
-                                   nullptr, VK_RValue, FPOptionsOverride());
+    Res = BuildImplicitCastExpr(Res.get(), T, CK_AtomicToNonAtomic, VK_RValue,
+                                CurFPFeatureOverrides());
+    if (Res.isInvalid())
+      return Res;
   }
 
   return Res;
@@ -984,8 +987,11 @@
     return ExprError();
 
   // Copy blocks to the heap.
-  if (ExprRes.get()->getType()->isBlockPointerType())
+  if (ExprRes.get()->getType()->isBlockPointerType()) {
     maybeExtendBlockObject(ExprRes);
+    if (ExprRes.isInvalid())
+      return ExprError();
+  }
 
   E = ExprRes.get();
 
@@ -7018,9 +7024,9 @@
   // Only do this in an r-value context.
   if (!getLangOpts().ObjCAutoRefCount) return;
 
-  E = ImplicitCastExpr::Create(
-      Context, E.get()->getType(), CK_ARCExtendBlockObject, E.get(),
-      /*base path*/ nullptr, VK_RValue, FPOptionsOverride());
+  E = BuildImplicitCastExpr(E.get(), E.get()->getType(),
+                            CK_ARCExtendBlockObject, VK_RValue,
+                            FPOptionsOverride());
   Cleanup.setExprNeedsCleanups(true);
 }
 
@@ -7248,6 +7254,12 @@
   llvm_unreachable("Unhandled scalar cast");
 }
 
+ExprResult Sema::BuildImplicitCastExpr(Expr *Src, QualType DstTy, CastKind CK,
+                                       ExprValueKind VK, FPOptionsOverride FPOO,
+                                       const CXXCastPath *CastPath) {
+  return ImplicitCastExpr::Create(Context, DstTy, CK, Src, CastPath, VK, FPOO);
+}
+
 static bool breakDownVectorType(QualType type, uint64_t &len,
                                 QualType &eltType) {
   // Vectors are simple.
@@ -7556,8 +7568,12 @@
       ExprResult Literal = DefaultLvalueConversion(exprs[0]);
       if (Literal.isInvalid())
         return ExprError();
-      Literal = ImpCastExprToType(Literal.get(), ElemTy,
-                                  PrepareScalarCast(Literal, ElemTy));
+      CastKind CK = PrepareScalarCast(Literal, ElemTy);
+      if (Literal.isInvalid())
+        return ExprError();
+      Literal = ImpCastExprToType(Literal.get(), ElemTy, CK);
+      if (Literal.isInvalid())
+        return ExprError();
       return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.get());
     }
     else if (numExprs < numElems) {
@@ -7578,8 +7594,10 @@
         ExprResult Literal = DefaultLvalueConversion(exprs[0]);
         if (Literal.isInvalid())
           return ExprError();
-        Literal = ImpCastExprToType(Literal.get(), ElemTy,
-                                    PrepareScalarCast(Literal, ElemTy));
+        CastKind CK = PrepareScalarCast(Literal, ElemTy);
+        if (Literal.isInvalid())
+          return ExprError();
+        Literal = ImpCastExprToType(Literal.get(), ElemTy, CK);
         return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.get());
     }
 
@@ -8203,8 +8221,12 @@
       return QualType();
     }
 
-    LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy));
-    RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy));
+    CastKind LHSCK = PrepareScalarCast(LHS, ResTy);
+    CastKind RHSCK = PrepareScalarCast(RHS, ResTy);
+    if (LHS.isInvalid() || RHS.isInvalid())
+      return QualType();
+    LHS = ImpCastExprToType(LHS.get(), ResTy, LHSCK);
+    RHS = ImpCastExprToType(RHS.get(), ResTy, RHSCK);
 
     return ResTy;
   }
@@ -9126,7 +9148,7 @@
       !(getLangOpts().CPlusPlus && LHSType->isEnumeralType())) {
     if (ConvertRHS)
       Kind = PrepareScalarCast(RHS, LHSType);
-    return Compatible;
+    return RHS.isInvalid() ? Incompatible : Compatible;
   }
 
   // Conversions to normal pointers.
@@ -9387,6 +9409,8 @@
       RHS = ImpCastExprToType(RHS.get(), it->getType(), Kind);
       InitField = it;
       break;
+    } else if (RHS.isInvalid()) {
+      return Incompatible;
     }
   }
 
@@ -9463,9 +9487,11 @@
     // functions need to be resolved here.
     DeclAccessPair DAP;
     if (FunctionDecl *FD = ResolveAddressOfOverloadedFunction(
-            RHS.get(), LHSType, /*Complain=*/false, DAP))
-      RHS = FixOverloadedFunctionReference(RHS.get(), DAP, FD);
-    else
+            RHS.get(), LHSType, /*Complain=*/false, DAP)) {
+      RHS = FixOverloadedFunctionReference(RHS, DAP, FD);
+      if (RHS.isInvalid())
+        return Incompatible;
+    } else
       return Incompatible;
   }
 
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1197,10 +1197,12 @@
 
     //   e is an lvalue if the type of the entity is an lvalue reference and
     //   an xvalue otherwise
-    if (!Src->getType()->isLValueReferenceType())
-      E = ImplicitCastExpr::Create(S.Context, E.get()->getType(), CK_NoOp,
-                                   E.get(), nullptr, VK_XValue,
-                                   FPOptionsOverride());
+    if (!Src->getType()->isLValueReferenceType()) {
+      E = S.BuildImplicitCastExpr(E.get(), E.get()->getType(), CK_NoOp,
+                                  VK_XValue, FPOptionsOverride());
+      if (E.isInvalid())
+        return true;
+    }
 
     TemplateArgumentListInfo Args(Loc, Loc);
     Args.addArgument(
@@ -14929,9 +14931,9 @@
   // (since it's unusable otherwise); in the case where we inline the
   // block literal, it has block literal lifetime semantics.
   if (!BuildBlock.isInvalid() && !getLangOpts().ObjCAutoRefCount)
-    BuildBlock = ImplicitCastExpr::Create(
-        Context, BuildBlock.get()->getType(), CK_CopyAndAutoreleaseBlockObject,
-        BuildBlock.get(), nullptr, VK_RValue, FPOptionsOverride());
+    BuildBlock = BuildImplicitCastExpr(
+        BuildBlock.get(), BuildBlock.get()->getType(),
+        CK_CopyAndAutoreleaseBlockObject, VK_RValue, FPOptionsOverride());
 
   if (BuildBlock.isInvalid()) {
     Diag(CurrentLocation, diag::note_lambda_to_block_conv);
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -3799,14 +3799,15 @@
                             clang::CK_ArrayToPointerDecay)
               .get();
     if (E->getType()->isFunctionType())
-      E = ImplicitCastExpr::Create(Context,
-                                   Context.getPointerType(E->getType()),
-                                   clang::CK_FunctionToPointerDecay, E, nullptr,
-                                   VK_RValue, FPOptionsOverride());
+      E = BuildImplicitCastExpr(E, Context.getPointerType(E->getType()),
+                                CK_FunctionToPointerDecay, VK_RValue,
+                                FPOptionsOverride(), nullptr)
+              .get();
     if (E->isLValue())
-      E = ImplicitCastExpr::Create(Context, E->getType().getNonReferenceType(),
-                                   clang::CK_LValueToRValue, E, nullptr,
-                                   VK_RValue, FPOptionsOverride());
+      E = BuildImplicitCastExpr(E, E->getType().getNonReferenceType(),
+                                CK_LValueToRValue, VK_RValue,
+                                FPOptionsOverride(), nullptr)
+              .get();
 
     Expr::EvalResult Eval;
     Notes.clear();
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -18207,10 +18207,13 @@
 
     // Adjust the Expr initializer and type.
     if (ECD->getInitExpr() &&
-        !Context.hasSameType(NewTy, ECD->getInitExpr()->getType()))
-      ECD->setInitExpr(ImplicitCastExpr::Create(
-          Context, NewTy, CK_IntegralCast, ECD->getInitExpr(),
-          /*base paths*/ nullptr, VK_RValue, FPOptionsOverride()));
+        !Context.hasSameType(NewTy, ECD->getInitExpr()->getType())) {
+      ExprResult ImpCast = BuildImplicitCastExpr(
+          ECD->getInitExpr(), NewTy, CK_IntegralCast, VK_RValue,
+          FPOptionsOverride(), /*base paths*/ nullptr);
+      if (!ImpCast.isInvalid())
+        ECD->setInitExpr(ImpCast.get());
+    }
     if (getLangOpts().CPlusPlus)
       // C++ [dcl.enum]p4: Following the closing brace of an
       // enum-specifier, each enumerator has the type of its
Index: clang/lib/Sema/SemaCast.cpp
===================================================================
--- clang/lib/Sema/SemaCast.cpp
+++ clang/lib/Sema/SemaCast.cpp
@@ -105,10 +105,12 @@
       // If this is an unbridged cast, wrap the result in an implicit
       // cast that yields the unbridged-cast placeholder type.
       if (IsARCUnbridgedCast) {
-        castExpr = ImplicitCastExpr::Create(
-            Self.Context, Self.Context.ARCUnbridgedCastTy, CK_Dependent,
-            castExpr, nullptr, castExpr->getValueKind(),
-            Self.CurFPFeatureOverrides());
+        ExprResult ImpCast = Self.BuildImplicitCastExpr(
+            castExpr, Self.Context.ARCUnbridgedCastTy, CK_Dependent,
+            castExpr->getValueKind(), Self.CurFPFeatureOverrides());
+        if (ImpCast.isInvalid())
+          return ExprError();
+        castExpr = cast<CastExpr>(ImpCast.get());
       }
       updatePartOfExplicitCastFlags(castExpr);
       return castExpr;
@@ -1052,6 +1054,8 @@
   TryCastResult tcr =
     TryReinterpretCast(Self, SrcExpr, DestType,
                        /*CStyle*/false, OpRange, msg, Kind);
+  if (SrcExpr.isInvalid())
+    return;
   if (tcr != TC_Success && msg != 0) {
     if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
       return;
@@ -2345,6 +2349,8 @@
     Kind = CK_LValueBitCast;
   } else if (DestType->isObjCObjectPointerType()) {
     Kind = Self.PrepareCastToObjCObjectPointer(SrcExpr);
+    if (SrcExpr.isInvalid())
+      return TC_Failed;
   } else if (DestType->isBlockPointerType()) {
     if (!SrcType->isBlockPointerType()) {
       Kind = CK_AnyPointerToBlockPointerCast;
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -606,8 +606,8 @@
     }
   }
 
-  return ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK,
-                                  CurFPFeatureOverrides());
+  return BuildImplicitCastExpr(E, Ty, Kind, VK, CurFPFeatureOverrides(),
+                               BasePath);
 }
 
 /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -3760,9 +3760,6 @@
                       unsigned DiagIDForComplaining = 0);
 
 
-  Expr *FixOverloadedFunctionReference(Expr *E,
-                                       DeclAccessPair FoundDecl,
-                                       FunctionDecl *Fn);
   ExprResult FixOverloadedFunctionReference(ExprResult,
                                             DeclAccessPair FoundDecl,
                                             FunctionDecl *Fn);
@@ -5377,6 +5374,12 @@
                                  Expr *Op);
   CastKind PrepareScalarCast(ExprResult &src, QualType destType);
 
+  /// Build an implicit cast expression, giving Sema a chance to make
+  /// modifications where appropriate.
+  ExprResult BuildImplicitCastExpr(Expr *Src, QualType DstTy, CastKind CK,
+                                   ExprValueKind VK, FPOptionsOverride FPOO,
+                                   const CXXCastPath *CastPath = nullptr);
+
   /// Build an altivec or OpenCL literal.
   ExprResult BuildVectorLiteral(SourceLocation LParenLoc,
                                 SourceLocation RParenLoc, Expr *E,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D96196: [Sema][NFC... Félix Cloutier via Phabricator via cfe-commits

Reply via email to