]> granicus.if.org Git - clang/commitdiff
Fix handling of atomic shift operations, from Serge Pavlov.
authorDouglas Gregor <dgregor@apple.com>
Tue, 16 Apr 2013 15:41:08 +0000 (15:41 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 16 Apr 2013 15:41:08 +0000 (15:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179600 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/Sema/atomic-expr.c [new file with mode: 0644]

index 8ddc87af53f337625fdfe969748c4a516cafd8cb..e96c5d40a3d71dee395ebaae513414e8c707724d 100644 (file)
@@ -6892,18 +6892,6 @@ QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS,
                                   bool IsCompAssign) {
   checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false);
 
-  // C99 6.5.7p2: Each of the operands shall have integer type.
-  if (!LHS.get()->getType()->hasIntegerRepresentation() || 
-      !RHS.get()->getType()->hasIntegerRepresentation())
-    return InvalidOperands(Loc, LHS, RHS);
-
-  // C++0x: Don't allow scoped enums. FIXME: Use something better than
-  // hasIntegerRepresentation() above instead of this.
-  if (isScopedEnumerationType(LHS.get()->getType()) ||
-      isScopedEnumerationType(RHS.get()->getType())) {
-    return InvalidOperands(Loc, LHS, RHS);
-  }
-
   // Vector shifts promote their scalar inputs to vector type.
   if (LHS.get()->getType()->isVectorType() ||
       RHS.get()->getType()->isVectorType())
@@ -6925,7 +6913,19 @@ QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS,
   RHS = UsualUnaryConversions(RHS.take());
   if (RHS.isInvalid())
     return QualType();
+  QualType RHSType = RHS.get()->getType();
+
+  // C99 6.5.7p2: Each of the operands shall have integer type.
+  if (!LHSType->hasIntegerRepresentation() ||
+      !RHSType->hasIntegerRepresentation())
+    return InvalidOperands(Loc, LHS, RHS);
 
+  // C++0x: Don't allow scoped enums. FIXME: Use something better than
+  // hasIntegerRepresentation() above instead of this.
+  if (isScopedEnumerationType(LHSType) ||
+      isScopedEnumerationType(RHSType)) {
+    return InvalidOperands(Loc, LHS, RHS);
+  }
   // Sanity-check shift operands
   DiagnoseBadShiftValues(*this, LHS, RHS, Loc, Opc, LHSType);
 
diff --git a/test/Sema/atomic-expr.c b/test/Sema/atomic-expr.c
new file mode 100644 (file)
index 0000000..ecc04c4
--- /dev/null
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+// expected-no-diagnostics
+
+_Atomic(unsigned int) data1;
+int _Atomic data2;
+
+// Shift operations
+
+int func_01 (int x) {
+  return data1 << x;
+}
+
+int func_02 (int x) {
+  return x << data1;
+}
+
+int func_03 (int x) {
+  return data2 << x;
+}
+
+int func_04 (int x) {
+  return x << data2;
+}
+
+int func_05 () {
+  return data2 << data1;
+}
+
+int func_06 () {
+  return data1 << data2;
+}
+
+void func_07 (int x) {
+  data1 <<= x;
+}
+
+void func_08 (int x) {
+  data2 <<= x;
+}
+
+void func_09 (int* xp) {
+  *xp <<= data1;
+}
+
+void func_10 (int* xp) {
+  *xp <<= data2;
+}