porglezomp created this revision.
porglezomp added reviewers: aaron.ballman, fhahn.
Herald added a subscriber: StephenFan.
Herald added a project: All.
porglezomp requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The bit-shifting operator builtin support vector vs scalars, but the
operator overloads did not. That mismatch caused an assertion failure
when trying to shift a vector by an enum.

This makes C++ match the behavior of C for these conversions on
bit-shifts.

rdar://108819842
Depends on D151059 <https://reviews.llvm.org/D151059>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D151060

Files:
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaCXX/vector.cpp

Index: clang/test/SemaCXX/vector.cpp
===================================================================
--- clang/test/SemaCXX/vector.cpp
+++ clang/test/SemaCXX/vector.cpp
@@ -726,11 +726,10 @@
   (void)(ea | v2ua); // expected-error{{cannot convert between vector values of different size}}
   (void)(v2ua ^ ea); // expected-error{{cannot convert between vector values of different size}}
   (void)(ea ^ v2ua); // expected-error{{cannot convert between vector values of different size}}
-  // FIXME: Vector/scalar shifts cause an assertion failure
-  // (void)(v2ua << ea);
-  // (void)(ea << v2ua);
-  // (void)(v2ua >> ea);
-  // (void)(ea >> v2ua);
+  (void)(v2ua << ea);
+  (void)(ea << v2ua);
+  (void)(v2ua >> ea);
+  (void)(ea >> v2ua);
 
   v2ua += ea; // expected-error{{cannot convert between vector values of different size}}
   v2ua -= ea; // expected-error{{cannot convert between vector values of different size}}
@@ -740,9 +739,8 @@
   v2ua &= ea; // expected-error{{cannot convert between vector values of different size}}
   v2ua |= ea; // expected-error{{cannot convert between vector values of different size}}
   v2ua ^= ea; // expected-error{{cannot convert between vector values of different size}}
-  // FIXME: Vector/scalar shifts cause an assertion failure
-  // v2ua >>= ea;
-  // v2ua <<= ea;
+  v2ua >>= ea;
+  v2ua <<= ea;
 
   ea += v2ua; // expected-error{{cannot convert between vector values of different size}}
   ea -= v2ua; // expected-error{{cannot convert between vector values of different size}}
@@ -752,9 +750,8 @@
   ea &= v2ua; // expected-error{{cannot convert between vector values of different size}}
   ea |= v2ua; // expected-error{{cannot convert between vector values of different size}}
   ea ^= v2ua; // expected-error{{cannot convert between vector values of different size}}
-  // FIXME: Vector/scalar shifts cause an assertion failure
-  // ea >>= v2ua; // not-expected-error{{assigning to 'enum Enum' from incompatible type 'v2u'}}
-  // ea <<= v2ua; // not-expected-error{{assigning to 'enum Enum' from incompatible type 'v2u'}}
+  ea >>= v2ua; // expected-error{{assigning to 'Enum' from incompatible type 'v2u'}}
+  ea <<= v2ua; // expected-error{{assigning to 'Enum' from incompatible type 'v2u'}}
 }
 
 #if __cplusplus >= 201103L // C++11 or later
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -9024,6 +9024,30 @@
         S.AddBuiltinCandidate(LandR, Args, CandidateSet);
       }
     }
+
+    // Extension: Add the binary bitwise operators for vector types
+    if (!CandidateTypes[0].vector_types().empty() &&
+        !CandidateTypes[1].vector_types().empty()) {
+      // If both candidates have vector types, then add them pairwise...
+      for (QualType Vec1Ty : CandidateTypes[0].vector_types()) {
+        for (QualType Vec2Ty : CandidateTypes[1].vector_types()) {
+          QualType LandR[2] = {Vec1Ty, Vec2Ty};
+          S.AddBuiltinCandidate(LandR, Args, CandidateSet);
+        }
+      }
+    } else {
+      // ...but if only one side has vector candidates, use that set of
+      // vector candidates pairwise for both sides of the operator
+      // (allowing splatting the scalar to a vector).
+      for (unsigned Candidate = 0; Candidate < 2; ++Candidate) {
+        for (QualType Vec1Ty : CandidateTypes[Candidate].vector_types()) {
+          for (QualType Vec2Ty : CandidateTypes[Candidate].vector_types()) {
+            QualType LandR[2] = {Vec1Ty, Vec2Ty};
+            S.AddBuiltinCandidate(LandR, Args, CandidateSet);
+          }
+        }
+      }
+    }
   }
 
   // C++ [over.built]p20:
@@ -9250,6 +9274,25 @@
             });
       }
     }
+
+    // Extension: Add the binary operators %=, <<=, >>=, &=, ^=, |= for vector types.
+    for (QualType Vec1Ty : CandidateTypes[0].vector_types())
+      for (QualType Vec2Ty : CandidateTypes[0].vector_types()) {
+        QualType ParamTypes[2];
+        ParamTypes[1] = Vec2Ty;
+        // Add this built-in operator as a candidate (VQ is empty).
+        ParamTypes[0] = S.Context.getLValueReferenceType(Vec1Ty);
+        S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
+                              /*IsAssignmentOperator=*/false);
+
+        // Add this built-in operator as a candidate (VQ is 'volatile').
+        if (VisibleTypeConversionsQuals.hasVolatile()) {
+          ParamTypes[0] = S.Context.getVolatileType(Vec1Ty);
+          ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]);
+          S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
+                                /*IsAssignmentOperator=*/false);
+        }
+      }
   }
 
   // C++ [over.operator]p23:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to