diff options
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 24 | ||||
-rw-r--r-- | test/Sema/atomic-expr.c | 47 |
2 files changed, 59 insertions, 12 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 8ddc87af53..e96c5d40a3 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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 index 0000000000..ecc04c4c68 --- /dev/null +++ b/test/Sema/atomic-expr.c @@ -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; +} |