diff options
| author | John McCall <rjmccall@apple.com> | 2010-02-23 19:22:29 +0000 | 
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2010-02-23 19:22:29 +0000 | 
| commit | ff96ccd3373278ea0d89f4ca9bd2c751b2e3e77b (patch) | |
| tree | fe9d3d848890c941fe3aff25eaf751cded512c40 | |
| parent | e4801e49c9066d85ef9b89725d26dac9d5e3cb95 (diff) | |
| download | bcm5719-llvm-ff96ccd3373278ea0d89f4ca9bd2c751b2e3e77b.tar.gz bcm5719-llvm-ff96ccd3373278ea0d89f4ca9bd2c751b2e3e77b.zip  | |
Don't assert on compound assignment operators that operate in FP types when
the result is integral.  Fixes <rdar://problem/7676608>.
llvm-svn: 96970
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 18 | ||||
| -rw-r--r-- | clang/test/Sema/conversion.c | 8 | 
2 files changed, 23 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 5a2ab2c7ba9..019b79811d1 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1682,13 +1682,13 @@ struct IntRange {    }    // Returns the supremum of two ranges: i.e. their conservative merge. -  static IntRange join(const IntRange &L, const IntRange &R) { +  static IntRange join(IntRange L, IntRange R) {      return IntRange(std::max(L.Width, R.Width),                      L.NonNegative && R.NonNegative);    }    // Returns the infinum of two ranges: i.e. their aggressive merge. -  static IntRange meet(const IntRange &L, const IntRange &R) { +  static IntRange meet(IntRange L, IntRange R) {      return IntRange(std::min(L.Width, R.Width),                      L.NonNegative || R.NonNegative);    } @@ -1806,6 +1806,15 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {      case BinaryOperator::NE:        return IntRange::forBoolType(); +    // The type of these compound assignments is the type of the LHS, +    // so the RHS is not necessarily an integer. +    case BinaryOperator::MulAssign: +    case BinaryOperator::DivAssign: +    case BinaryOperator::RemAssign: +    case BinaryOperator::AddAssign: +    case BinaryOperator::SubAssign: +      return IntRange::forType(C, E->getType()); +      // Operations with opaque sources are black-listed.      case BinaryOperator::PtrMemD:      case BinaryOperator::PtrMemI: @@ -1813,15 +1822,18 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {      // Bitwise-and uses the *infinum* of the two source ranges.      case BinaryOperator::And: +    case BinaryOperator::AndAssign:        return IntRange::meet(GetExprRange(C, BO->getLHS(), MaxWidth),                              GetExprRange(C, BO->getRHS(), MaxWidth));      // Left shift gets black-listed based on a judgement call.      case BinaryOperator::Shl: +    case BinaryOperator::ShlAssign:        return IntRange::forType(C, E->getType());      // Right shift by a constant can narrow its left argument. -    case BinaryOperator::Shr: { +    case BinaryOperator::Shr: +    case BinaryOperator::ShrAssign: {        IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth);        // If the shift amount is a positive constant, drop the width by diff --git a/clang/test/Sema/conversion.c b/clang/test/Sema/conversion.c index 8b93a466282..addedd91f7e 100644 --- a/clang/test/Sema/conversion.c +++ b/clang/test/Sema/conversion.c @@ -279,3 +279,11 @@ void test_7631400(void) {    // This should show up despite the caret being inside a macro substitution    char s = LONG_MAX; // expected-warning {{implicit cast loses integer precision: 'long' to 'char'}}  } + +// <rdar://problem/7676608>: assertion for compound operators with non-integral RHS +void f7676608(int); +void test_7676608(void) { +  float q = 0.7f; +  char c = 5; +  f7676608(c *= q); +}  | 

