diff options
author | Justin Bogner <mail@justinbogner.com> | 2014-07-21 18:01:53 +0000 |
---|---|---|
committer | Justin Bogner <mail@justinbogner.com> | 2014-07-21 18:01:53 +0000 |
commit | d2b971aa5e42a2d09603085a3b2ab2b5820ef707 (patch) | |
tree | 8d03ecc3685b29c7cffe88a18f15fea88d33ffed | |
parent | e559847c3d4cf821fee268eafee4ac355ca834cd (diff) |
Sema: Handle C11 atomics when diagnosing out of range comparisons
This fixes a couple of asserts when analyzing comparisons involving
C11 atomics that were uncovered by r205608 when we extended the
applicability of -Wtautological-constant-out-of-range-compare.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213573 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 6 | ||||
-rw-r--r-- | test/Sema/atomic-compare.c | 21 | ||||
-rw-r--r-- | test/Sema/atomic-expr.c | 3 |
3 files changed, 30 insertions, 0 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index d8b801bf0a..f6bb8370d5 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -4943,6 +4943,8 @@ struct IntRange { T = VT->getElementType().getTypePtr(); if (const ComplexType *CT = dyn_cast<ComplexType>(T)) T = CT->getElementType().getTypePtr(); + if (const AtomicType *AT = dyn_cast<AtomicType>(T)) + T = AT->getValueType().getTypePtr(); // For enum types, use the known bit width of the enumerators. if (const EnumType *ET = dyn_cast<EnumType>(T)) { @@ -4978,6 +4980,8 @@ struct IntRange { T = VT->getElementType().getTypePtr(); if (const ComplexType *CT = dyn_cast<ComplexType>(T)) T = CT->getElementType().getTypePtr(); + if (const AtomicType *AT = dyn_cast<AtomicType>(T)) + T = AT->getValueType().getTypePtr(); if (const EnumType *ET = dyn_cast<EnumType>(T)) T = C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr(); @@ -5380,6 +5384,8 @@ static void DiagnoseOutOfRangeComparison(Sema &S, BinaryOperator *E, // TODO: Investigate using GetExprRange() to get tighter bounds // on the bit ranges. QualType OtherT = Other->getType(); + if (const AtomicType *AT = dyn_cast<AtomicType>(OtherT)) + OtherT = AT->getValueType(); IntRange OtherRange = IntRange::forValueOfType(S.Context, OtherT); unsigned OtherWidth = OtherRange.Width; diff --git a/test/Sema/atomic-compare.c b/test/Sema/atomic-compare.c new file mode 100644 index 0000000000..2eed091260 --- /dev/null +++ b/test/Sema/atomic-compare.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only + +void f(_Atomic(int) a, _Atomic(int) b) { + if (a > b) {} // no warning + if (a < b) {} // no warning + if (a >= b) {} // no warning + if (a <= b) {} // no warning + if (a == b) {} // no warning + if (a != b) {} // no warning + + if (a == 0) {} // no warning + if (a > 0) {} // no warning + if (a > 1) {} // no warning + if (a > 2) {} // no warning + + if (!a > 0) {} // no warning + if (!a > 1) {} // expected-warning {{comparison of constant 1 with boolean expression is always false}} + if (!a > 2) {} // expected-warning {{comparison of constant 2 with boolean expression is always false}} + if (!a > b) {} // no warning + if (!a > -1) {} // expected-warning {{comparison of constant -1 with boolean expression is always true}} +} diff --git a/test/Sema/atomic-expr.c b/test/Sema/atomic-expr.c index 5602d545cc..997ee90e9f 100644 --- a/test/Sema/atomic-expr.c +++ b/test/Sema/atomic-expr.c @@ -58,3 +58,6 @@ int func_13 (int x, unsigned y) { return x ? data1 : y; } +int func_14 () { + return data1 == 0; +} |