]> granicus.if.org Git - clang/commitdiff
Switch Sema::FindCompositePointerType() over to InitializationSequence.
authorDouglas Gregor <dgregor@apple.com>
Fri, 16 Apr 2010 23:20:25 +0000 (23:20 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 16 Apr 2010 23:20:25 +0000 (23:20 +0000)
This is the last of the uses of TryImplicitConversion outside of
overload resolution and InitializationSequence itself.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101569 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprCXX.cpp

index 3cabb8662f1e1fa82425676983956ddd41dd0c1a..19f878a6a16781ce5304abb071d79cf1c9ba557d 100644 (file)
@@ -4134,7 +4134,7 @@ public:
     Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
   QualType CXXCheckConditionalOperands( // C++ 5.16
     Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
-  QualType FindCompositePointerType(Expr *&E1, Expr *&E2,
+  QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
                                     bool *NonStandardCompositeType = 0);
 
   QualType FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
index 9b2ec58804b269b6e6e5b572890819f9648fe552..9f33d42b47229afae37b6d4c92cd8fc8cab4e3d0 100644 (file)
@@ -5353,7 +5353,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
       // C++ [expr.eq]p1 uses the same notion for (in)equality
       // comparisons of pointers.
       bool NonStandardCompositeType = false;
-      QualType T = FindCompositePointerType(lex, rex,
+      QualType T = FindCompositePointerType(Loc, lex, rex,
                               isSFINAEContext()? 0 : &NonStandardCompositeType);
       if (T.isNull()) {
         Diag(Loc, diag::err_typecheck_comparison_of_distinct_pointers)
@@ -5426,7 +5426,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
       //   that is the union of the cv-qualification signatures of the operand
       //   types.
       bool NonStandardCompositeType = false;
-      QualType T = FindCompositePointerType(lex, rex,
+      QualType T = FindCompositePointerType(Loc, lex, rex,
                               isSFINAEContext()? 0 : &NonStandardCompositeType);
       if (T.isNull()) {
         Diag(Loc, diag::err_typecheck_comparison_of_distinct_pointers)
index 4d85977103a9db0d723ffc7f49c1ad4333d7da00..aa9efed6da154af0b44bc0e6214b65c4426207a4 100644 (file)
@@ -2197,7 +2197,7 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
   //      shall match the cv-qualification of either the second or the third
   //      operand. The result is of the common type.
   bool NonStandardCompositeType = false;
-  QualType Composite = FindCompositePointerType(LHS, RHS,
+  QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS,
                               isSFINAEContext()? 0 : &NonStandardCompositeType);
   if (!Composite.isNull()) {
     if (NonStandardCompositeType)
@@ -2227,11 +2227,15 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
 /// type and returns it.
 /// It does not emit diagnostics.
 ///
+/// \param Loc The location of the operator requiring these two expressions to
+/// be converted to the composite pointer type.
+///
 /// If \p NonStandardCompositeType is non-NULL, then we are permitted to find
 /// a non-standard (but still sane) composite type to which both expressions
 /// can be converted. When such a type is chosen, \c *NonStandardCompositeType
 /// will be set true.
-QualType Sema::FindCompositePointerType(Expr *&E1, Expr *&E2,
+QualType Sema::FindCompositePointerType(SourceLocation Loc, 
+                                        Expr *&E1, Expr *&E2,
                                         bool *NonStandardCompositeType) {
   if (NonStandardCompositeType)
     *NonStandardCompositeType = false;
@@ -2368,44 +2372,70 @@ QualType Sema::FindCompositePointerType(Expr *&E1, Expr *&E2,
     }
   }
 
-  ImplicitConversionSequence E1ToC1 =
-    TryImplicitConversion(E1, Composite1,
-                          /*SuppressUserConversions=*/false,
-                          /*AllowExplicit=*/false,
-                          /*InOverloadResolution=*/false);
-  ImplicitConversionSequence E2ToC1 =
-    TryImplicitConversion(E2, Composite1,
-                          /*SuppressUserConversions=*/false,
-                          /*AllowExplicit=*/false,
-                          /*InOverloadResolution=*/false);
-
-  bool ToC2Viable = false;
-  ImplicitConversionSequence E1ToC2, E2ToC2;
-  if (Context.getCanonicalType(Composite1) !=
-      Context.getCanonicalType(Composite2)) {
-    E1ToC2 = TryImplicitConversion(E1, Composite2,
-                                   /*SuppressUserConversions=*/false,
-                                   /*AllowExplicit=*/false,
-                                   /*InOverloadResolution=*/false);
-    E2ToC2 = TryImplicitConversion(E2, Composite2,
-                                   /*SuppressUserConversions=*/false,
-                                   /*AllowExplicit=*/false,
-                                   /*InOverloadResolution=*/false);
-    ToC2Viable = !E1ToC2.isBad() && !E2ToC2.isBad();
-  }
-
-  bool ToC1Viable = !E1ToC1.isBad() && !E2ToC1.isBad();
-  if (ToC1Viable && !ToC2Viable) {
-    if (!PerformImplicitConversion(E1, Composite1, E1ToC1, Sema::AA_Converting) &&
-        !PerformImplicitConversion(E2, Composite1, E2ToC1, Sema::AA_Converting))
-      return Composite1;
-  }
-  if (ToC2Viable && !ToC1Viable) {
-    if (!PerformImplicitConversion(E1, Composite2, E1ToC2, Sema::AA_Converting) &&
-        !PerformImplicitConversion(E2, Composite2, E2ToC2, Sema::AA_Converting))
-      return Composite2;
+  // Try to convert to the first composite pointer type.
+  InitializedEntity Entity1
+    = InitializedEntity::InitializeTemporary(Composite1);
+  InitializationKind Kind
+    = InitializationKind::CreateCopy(Loc, SourceLocation());
+  InitializationSequence E1ToC1(*this, Entity1, Kind, &E1, 1);
+  InitializationSequence E2ToC1(*this, Entity1, Kind, &E2, 1);
+
+  if (E1ToC1 && E2ToC1) {
+    // Conversion to Composite1 is viable.
+    if (!Context.hasSameType(Composite1, Composite2)) {
+      // Composite2 is a different type from Composite1. Check whether
+      // Composite2 is also viable.
+      InitializedEntity Entity2
+        = InitializedEntity::InitializeTemporary(Composite2);
+      InitializationSequence E1ToC2(*this, Entity2, Kind, &E1, 1);
+      InitializationSequence E2ToC2(*this, Entity2, Kind, &E2, 1);
+      if (E1ToC2 && E2ToC2) {
+        // Both Composite1 and Composite2 are viable and are different;
+        // this is an ambiguity.
+        return QualType();
+      }
+    }
+
+    // Convert E1 to Composite1
+    OwningExprResult E1Result
+      = E1ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,(void**)&E1,1));
+    if (E1Result.isInvalid())
+      return QualType();
+    E1 = E1Result.takeAs<Expr>();
+
+    // Convert E2 to Composite1
+    OwningExprResult E2Result
+      = E2ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,(void**)&E2,1));
+    if (E2Result.isInvalid())
+      return QualType();
+    E2 = E2Result.takeAs<Expr>();
+    
+    return Composite1;
   }
-  return QualType();
+
+  // Check whether Composite2 is viable.
+  InitializedEntity Entity2
+    = InitializedEntity::InitializeTemporary(Composite2);
+  InitializationSequence E1ToC2(*this, Entity2, Kind, &E1, 1);
+  InitializationSequence E2ToC2(*this, Entity2, Kind, &E2, 1);
+  if (!E1ToC2 || !E2ToC2)
+    return QualType();
+  
+  // Convert E1 to Composite2
+  OwningExprResult E1Result
+    = E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, (void**)&E1, 1));
+  if (E1Result.isInvalid())
+    return QualType();
+  E1 = E1Result.takeAs<Expr>();
+  
+  // Convert E2 to Composite2
+  OwningExprResult E2Result
+    = E2ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, (void**)&E2, 1));
+  if (E2Result.isInvalid())
+    return QualType();
+  E2 = E2Result.takeAs<Expr>();
+  
+  return Composite2;
 }
 
 Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {