Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -9136,26 +9136,6 @@ return true; } -/// Analyze the given simple or compound assignment for warning-worthy -/// operations. -static void AnalyzeAssignment(Sema &S, BinaryOperator *E) { - // Just recurse on the LHS. - AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc()); - - // We want to recurse on the RHS as normal unless we're assigning to - // a bitfield. - if (FieldDecl *Bitfield = E->getLHS()->getSourceBitField()) { - if (AnalyzeBitFieldAssignment(S, Bitfield, E->getRHS(), - E->getOperatorLoc())) { - // Recurse, ignoring any implicit conversions on the RHS. - return AnalyzeImplicitConversions(S, E->getRHS()->IgnoreParenImpCasts(), - E->getOperatorLoc()); - } - } - - AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc()); -} - /// Diagnose an implicit cast; purely a helper for CheckImplicitConversion. static void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, @@ -9815,6 +9795,28 @@ CheckImplicitConversion(S, E->IgnoreParenImpCasts(), S.Context.BoolTy, CC); } +/// Analyze the given simple or compound assignment for warning-worthy +/// operations. +static void AnalyzeAssignment(Sema &S, BinaryOperator *E) { + // Just recurse on the LHS. + AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc()); + + // We want to recurse on the RHS as normal unless we're assigning to + // a bitfield. + if (FieldDecl *Bitfield = E->getLHS()->getSourceBitField()) { + if (AnalyzeBitFieldAssignment(S, Bitfield, E->getRHS(), + E->getOperatorLoc())) { + // Recurse, ignoring any implicit conversions on the RHS. + return AnalyzeImplicitConversions(S, E->getRHS()->IgnoreParenImpCasts(), + E->getOperatorLoc()); + } + } + + AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc()); + if(E->getRHS()->getType() != E->getLHS()->getType()) + CheckImplicitConversion(S, E->getRHS()->IgnoreParenImpCasts(), E->getLHS()->getType(), E->getOperatorLoc()); +} + /// AnalyzeImplicitConversions - Find and report any interesting /// implicit conversions in the given expression. There are a couple /// of competing diagnostics here, -Wconversion and -Wsign-compare. @@ -9866,8 +9868,8 @@ if (BO->isComparisonOp()) return AnalyzeComparison(S, BO); - // And with simple assignments. - if (BO->getOpcode() == BO_Assign) + // And with assignments. + if (BO->isAssignmentOp()) return AnalyzeAssignment(S, BO); } Index: test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp =================================================================== --- test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp +++ test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp @@ -50,7 +50,7 @@ #pragma omp teams // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} #pragma omp distribute parallel for simd - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target Index: test/OpenMP/distribute_simd_loop_messages.cpp =================================================================== --- test/OpenMP/distribute_simd_loop_messages.cpp +++ test/OpenMP/distribute_simd_loop_messages.cpp @@ -41,7 +41,7 @@ #pragma omp teams // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} #pragma omp distribute simd - for (long long i = 0; i < 10; i+=1.5) { + for (long long i = 0; i < 10; i+=1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target Index: test/OpenMP/for_loop_messages.cpp =================================================================== --- test/OpenMP/for_loop_messages.cpp +++ test/OpenMP/for_loop_messages.cpp @@ -50,7 +50,7 @@ #pragma omp parallel // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} #pragma omp for - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp parallel Index: test/OpenMP/for_simd_loop_messages.cpp =================================================================== --- test/OpenMP/for_simd_loop_messages.cpp +++ test/OpenMP/for_simd_loop_messages.cpp @@ -45,7 +45,7 @@ #pragma omp parallel // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} #pragma omp for simd - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp parallel Index: test/OpenMP/parallel_for_loop_messages.cpp =================================================================== --- test/OpenMP/parallel_for_loop_messages.cpp +++ test/OpenMP/parallel_for_loop_messages.cpp @@ -40,7 +40,7 @@ } // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} #pragma omp parallel for - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp parallel for Index: test/OpenMP/parallel_for_simd_loop_messages.cpp =================================================================== --- test/OpenMP/parallel_for_simd_loop_messages.cpp +++ test/OpenMP/parallel_for_simd_loop_messages.cpp @@ -40,7 +40,7 @@ } // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} #pragma omp parallel for simd - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp parallel for simd Index: test/OpenMP/simd_loop_messages.cpp =================================================================== --- test/OpenMP/simd_loop_messages.cpp +++ test/OpenMP/simd_loop_messages.cpp @@ -31,7 +31,7 @@ } // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} #pragma omp simd - for (long long i = 0; i < 10; i+=1.5) { + for (long long i = 0; i < 10; i+=1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp simd Index: test/OpenMP/target_parallel_for_loop_messages.cpp =================================================================== --- test/OpenMP/target_parallel_for_loop_messages.cpp +++ test/OpenMP/target_parallel_for_loop_messages.cpp @@ -40,7 +40,7 @@ } // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} #pragma omp target parallel for - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target parallel for Index: test/OpenMP/target_parallel_for_simd_loop_messages.cpp =================================================================== --- test/OpenMP/target_parallel_for_simd_loop_messages.cpp +++ test/OpenMP/target_parallel_for_simd_loop_messages.cpp @@ -40,7 +40,7 @@ } // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} #pragma omp target parallel for simd - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target parallel for simd Index: test/OpenMP/target_simd_loop_messages.cpp =================================================================== --- test/OpenMP/target_simd_loop_messages.cpp +++ test/OpenMP/target_simd_loop_messages.cpp @@ -40,7 +40,7 @@ } // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} #pragma omp target simd - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target simd Index: test/OpenMP/target_teams_distribute_loop_messages.cpp =================================================================== --- test/OpenMP/target_teams_distribute_loop_messages.cpp +++ test/OpenMP/target_teams_distribute_loop_messages.cpp @@ -40,7 +40,7 @@ } #pragma omp target teams distribute // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'double'}} - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target teams distribute Index: test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp =================================================================== --- test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp +++ test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp @@ -40,7 +40,7 @@ } #pragma omp target teams distribute parallel for // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'double'}} - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target teams distribute parallel for Index: test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp =================================================================== --- test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp +++ test/OpenMP/target_teams_distribute_parallel_for_simd_loop_messages.cpp @@ -40,7 +40,7 @@ } #pragma omp target teams distribute parallel for simd // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'double'}} - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target teams distribute parallel for simd Index: test/OpenMP/target_teams_distribute_simd_loop_messages.cpp =================================================================== --- test/OpenMP/target_teams_distribute_simd_loop_messages.cpp +++ test/OpenMP/target_teams_distribute_simd_loop_messages.cpp @@ -40,7 +40,7 @@ } #pragma omp target teams distribute simd // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'double'}} - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target teams distribute simd Index: test/OpenMP/taskloop_loop_messages.cpp =================================================================== --- test/OpenMP/taskloop_loop_messages.cpp +++ test/OpenMP/taskloop_loop_messages.cpp @@ -50,7 +50,7 @@ #pragma omp parallel // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} #pragma omp taskloop - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp parallel Index: test/OpenMP/taskloop_simd_loop_messages.cpp =================================================================== --- test/OpenMP/taskloop_simd_loop_messages.cpp +++ test/OpenMP/taskloop_simd_loop_messages.cpp @@ -50,7 +50,7 @@ #pragma omp parallel // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}} #pragma omp taskloop simd - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp parallel Index: test/OpenMP/teams_distribute_loop_messages.cpp =================================================================== --- test/OpenMP/teams_distribute_loop_messages.cpp +++ test/OpenMP/teams_distribute_loop_messages.cpp @@ -45,7 +45,7 @@ #pragma omp target #pragma omp teams distribute // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'double'}} - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target Index: test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp =================================================================== --- test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp +++ test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp @@ -45,7 +45,7 @@ #pragma omp target #pragma omp teams distribute parallel for // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'double'}} - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target Index: test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp =================================================================== --- test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp +++ test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp @@ -45,7 +45,7 @@ #pragma omp target #pragma omp teams distribute parallel for simd // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'double'}} - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target Index: test/OpenMP/teams_distribute_simd_loop_messages.cpp =================================================================== --- test/OpenMP/teams_distribute_simd_loop_messages.cpp +++ test/OpenMP/teams_distribute_simd_loop_messages.cpp @@ -45,7 +45,7 @@ #pragma omp target #pragma omp teams distribute simd // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'double'}} - for (long long i = 0; i < 10; i += 1.5) { + for (long long i = 0; i < 10; i += 1.5) { // expected-warning {{implicit conversion from 'double' to 'long long' changes value from 1.5 to 1}} c[i] = a[i] + b[i]; } #pragma omp target Index: test/Sema/constant-conversion.c =================================================================== --- test/Sema/constant-conversion.c +++ test/Sema/constant-conversion.c @@ -73,7 +73,7 @@ f.twoBits1 = ~1; // no-warning f.twoBits2 = ~2; // expected-warning {{implicit truncation from 'int' to bit-field changes value from -3 to 1}} f.twoBits1 &= ~1; // no-warning - f.twoBits2 &= ~2; // no-warning + f.twoBits2 &= ~2; // expected-warning {{implicit truncation from 'int' to bit-field changes value from -3 to 1}} } void test8() { Index: test/Sema/conversion.c =================================================================== --- test/Sema/conversion.c +++ test/Sema/conversion.c @@ -359,7 +359,7 @@ void test_7676608(void) { float q = 0.7f; char c = 5; - f7676608(c *= q); + f7676608(c *= q); // expected-warning {{implicit conversion turns floating-point number into integer: 'float' to 'char'}} } // Index: test/Sema/shift.c =================================================================== --- test/Sema/shift.c +++ test/Sema/shift.c @@ -27,8 +27,8 @@ c >>= 1; c <<= -1; // expected-warning {{shift count is negative}} c >>= -1; // expected-warning {{shift count is negative}} - c <<= 999999; // expected-warning {{shift count >= width of type}} - c >>= 999999; // expected-warning {{shift count >= width of type}} + c <<= 999999; // expected-warning {{shift count >= width of type}} expected-warning {{implicit conversion from 'int' to 'char' changes value from 999999 to 63}} + c >>= 999999; // expected-warning {{shift count >= width of type}} expected-warning {{implicit conversion from 'int' to 'char' changes value from 999999 to 63}} c <<= CHAR_BIT; // expected-warning {{shift count >= width of type}} c >>= CHAR_BIT; // expected-warning {{shift count >= width of type}} c <<= CHAR_BIT+1; // expected-warning {{shift count >= width of type}} Index: test/SemaCXX/conversion.cpp =================================================================== --- test/SemaCXX/conversion.cpp +++ test/SemaCXX/conversion.cpp @@ -13,6 +13,19 @@ typedef unsigned int uint32_t; typedef unsigned long uint64_t; + +float doubleFloat1(double a) { + return a; // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'float'}} +} +void doubleFloat2(double a, float *b) { + *b += a; // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'float'}} +} + +extern float sinf(float x); +double doubleFloat3(double a) { + return sinf(a); // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'float'}} +} + // namespace test0 { int32_t test1_positive(char *I, char *E) { Index: test/SemaCXX/null_in_arithmetic_ops.cpp =================================================================== --- test/SemaCXX/null_in_arithmetic_ops.cpp +++ test/SemaCXX/null_in_arithmetic_ops.cpp @@ -51,18 +51,18 @@ a = NULL | NULL; // expected-warning{{use of NULL in arithmetic operation}} a = NULL ^ NULL; // expected-warning{{use of NULL in arithmetic operation}} - a += NULL; // expected-warning{{use of NULL in arithmetic operation}} - a -= NULL; // expected-warning{{use of NULL in arithmetic operation}} + a += NULL; // expected-warning{{use of NULL in arithmetic operation}} expected-warning {{implicit conversion of NULL constant to 'int'}} + a -= NULL; // expected-warning{{use of NULL in arithmetic operation}} expected-warning {{implicit conversion of NULL constant to 'int'}} a /= NULL; // expected-warning{{use of NULL in arithmetic operation}} \ - // expected-warning{{division by zero is undefined}} - a *= NULL; // expected-warning{{use of NULL in arithmetic operation}} - a >>= NULL; // expected-warning{{use of NULL in arithmetic operation}} - a <<= NULL; // expected-warning{{use of NULL in arithmetic operation}} + // expected-warning{{division by zero is undefined}} expected-warning {{implicit conversion of NULL constant to 'int'}} + a *= NULL; // expected-warning{{use of NULL in arithmetic operation}} expected-warning {{implicit conversion of NULL constant to 'int'}} + a >>= NULL; // expected-warning{{use of NULL in arithmetic operation}} expected-warning {{implicit conversion of NULL constant to 'int'}} + a <<= NULL; // expected-warning{{use of NULL in arithmetic operation}} expected-warning {{implicit conversion of NULL constant to 'int'}} a %= NULL; // expected-warning{{use of NULL in arithmetic operation}} \ - // expected-warning{{remainder by zero is undefined}} - a &= NULL; // expected-warning{{use of NULL in arithmetic operation}} - a |= NULL; // expected-warning{{use of NULL in arithmetic operation}} - a ^= NULL; // expected-warning{{use of NULL in arithmetic operation}} + // expected-warning{{remainder by zero is undefined}} expected-warning {{implicit conversion of NULL constant to 'int'}} + a &= NULL; // expected-warning{{use of NULL in arithmetic operation}} expected-warning {{implicit conversion of NULL constant to 'int'}} + a |= NULL; // expected-warning{{use of NULL in arithmetic operation}} expected-warning {{implicit conversion of NULL constant to 'int'}} + a ^= NULL; // expected-warning{{use of NULL in arithmetic operation}} expected-warning {{implicit conversion of NULL constant to 'int'}} b = a < NULL || a > NULL; // expected-warning 2{{comparison between NULL and non-pointer ('int' and NULL)}} b = NULL < a || NULL > a; // expected-warning 2{{comparison between NULL and non-pointer (NULL and 'int')}}