Author: rtrieu Date: Fri Feb 5 17:02:38 2016 New Revision: 259947 URL: http://llvm.org/viewvc/llvm-project?rev=259947&view=rev Log: Exempt char array initializers from -Wconstant-converion.
Sometimes, char arrays are used as bit storage, with no difference made between signed and unsigned char. Thus, it is reasonable to use 0 to 255 instead of -128 to 127 and not trigger this warning. Modified: cfe/trunk/lib/Sema/SemaChecking.cpp cfe/trunk/test/Sema/constant-conversion.c Modified: cfe/trunk/lib/Sema/SemaChecking.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=259947&r1=259946&r2=259947&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaChecking.cpp (original) +++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Feb 5 17:02:38 2016 @@ -7400,6 +7400,32 @@ static void checkObjCDictionaryLiteral( } } +// Helper function to filter out cases for constant width constant conversion. +// Don't warn on char array initialization or for non-decimal values. +static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, + SourceLocation CC) { + // If initializing from a constant, and the constant starts with '0', + // then it is a binary, octal, or hexadecimal. Allow these constants + // to fill all the bits, even if there is a sign change. + if (auto *IntLit = dyn_cast<IntegerLiteral>(E->IgnoreParenImpCasts())) { + const char FirstLiteralCharacter = + S.getSourceManager().getCharacterData(IntLit->getLocStart())[0]; + if (FirstLiteralCharacter == '0') + return false; + } + + // If the CC location points to a '{', and the type is char, then assume + // assume it is an array initialization. + if (CC.isValid() && T->isCharType()) { + const char FirstContextCharacter = + S.getSourceManager().getCharacterData(CC)[0]; + if (FirstContextCharacter == '{') + return false; + } + + return true; +} + void CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC, bool *ICContext = nullptr) { if (E->isTypeDependent() || E->isValueDependent()) return; @@ -7610,32 +7636,21 @@ void CheckImplicitConversion(Sema &S, Ex // cause a negative value to be stored. llvm::APSInt Value; - if (E->EvaluateAsInt(Value, S.Context, Expr::SE_AllowSideEffects)) { - if (!S.SourceMgr.isInSystemMacro(CC)) { - - IntegerLiteral *IntLit = - dyn_cast<IntegerLiteral>(E->IgnoreParenImpCasts()); - - // If initializing from a constant, and the constant starts with '0', - // then it is a binary, octal, or hexadecimal. Allow these constants - // to fill all the bits, even if there is a sign change. - if (!IntLit || - *(S.getSourceManager().getCharacterData(IntLit->getLocStart())) != - '0') { - - std::string PrettySourceValue = Value.toString(10); - std::string PrettyTargetValue = - PrettyPrintInRange(Value, TargetRange); - - S.DiagRuntimeBehavior( - E->getExprLoc(), E, - S.PDiag(diag::warn_impcast_integer_precision_constant) - << PrettySourceValue << PrettyTargetValue << E->getType() << T - << E->getSourceRange() << clang::SourceRange(CC)); - return; - } + if (E->EvaluateAsInt(Value, S.Context, Expr::SE_AllowSideEffects) && + !S.SourceMgr.isInSystemMacro(CC)) { + if (isSameWidthConstantConversion(S, E, T, CC)) { + std::string PrettySourceValue = Value.toString(10); + std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange); + + S.DiagRuntimeBehavior( + E->getExprLoc(), E, + S.PDiag(diag::warn_impcast_integer_precision_constant) + << PrettySourceValue << PrettyTargetValue << E->getType() << T + << E->getSourceRange() << clang::SourceRange(CC)); + return; } } + // Fall through for non-constants to give a sign conversion warning. } Modified: cfe/trunk/test/Sema/constant-conversion.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/constant-conversion.c?rev=259947&r1=259946&r2=259947&view=diff ============================================================================== --- cfe/trunk/test/Sema/constant-conversion.c (original) +++ cfe/trunk/test/Sema/constant-conversion.c Fri Feb 5 17:02:38 2016 @@ -110,4 +110,6 @@ void test9() { char macro_char_hex = CHAR_MACRO_HEX; #define CHAR_MACRO_DEC 255 char macro_char_dec = CHAR_MACRO_DEC; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 255 to -1}} + + char array_init[] = { 255, 127, 128, 129, 0 }; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits