]> granicus.if.org Git - clang/commitdiff
[Sema] Fix how we set implicit conversion kinds.
authorGeorge Burgess IV <george.burgess.iv@gmail.com>
Sat, 3 Sep 2016 00:28:25 +0000 (00:28 +0000)
committerGeorge Burgess IV <george.burgess.iv@gmail.com>
Sat, 3 Sep 2016 00:28:25 +0000 (00:28 +0000)
We have invariants we like to guarantee for the
`ImplicitConversionKind`s in a `StandardConversionSequence`. These
weren't being upheld in code that r280553 touched, so Richard suggested
that we should fix that. See D24113.

I'm not entirely sure how to go about testing this, so no test case is
included. Suggestions welcome.

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

lib/Sema/SemaOverload.cpp

index 38144a94a1429c55515f61dda060849425e4dee4..37552b57d6677550e4462a88bc42d26742f00d8c 100644 (file)
@@ -1790,10 +1790,10 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
                                          /*Diagnose=*/false,
                                          /*DiagnoseCFAudited=*/false,
                                          /*ConvertRHS=*/false);
-  ImplicitConversionKind ImplicitConv;
+  ImplicitConversionKind SecondConv;
   switch (Conv) {
   case Sema::Compatible:
-    ImplicitConv = ICK_C_Only_Conversion;
+    SecondConv = ICK_C_Only_Conversion;
     break;
   // For our purposes, discarding qualifiers is just as bad as using an
   // incompatible pointer. Note that an IncompatiblePointer conversion can drop
@@ -1801,18 +1801,24 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
   case Sema::CompatiblePointerDiscardsQualifiers:
   case Sema::IncompatiblePointer:
   case Sema::IncompatiblePointerSign:
-    ImplicitConv = ICK_Incompatible_Pointer_Conversion;
+    SecondConv = ICK_Incompatible_Pointer_Conversion;
     break;
   default:
     return false;
   }
 
-  SCS.setAllToTypes(ToType);
-  // We need to set all three because we want this conversion to rank terribly,
-  // and we don't know what conversions it may overlap with.
-  SCS.First = ImplicitConv;
-  SCS.Second = ImplicitConv;
-  SCS.Third = ImplicitConv;
+  // First can only be an lvalue conversion, so we pretend that this was the
+  // second conversion. First should already be valid from earlier in the
+  // function.
+  SCS.Second = SecondConv;
+  SCS.setToType(1, ToType);
+
+  // Third is Identity, because Second should rank us worse than any other
+  // conversion. This could also be ICK_Qualification, but it's simpler to just
+  // lump everything in with the second conversion, and we don't gain anything
+  // from making this ICK_Qualification.
+  SCS.Third = ICK_Identity;
+  SCS.setToType(2, ToType);
   return true;
 }