summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp38
1 files changed, 37 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 60a2e505d88..295ff71eff7 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7578,7 +7578,7 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
// If the source is a constant, use a default-on diagnostic.
// TODO: this should happen for bitfield stores, too.
llvm::APSInt Value(32);
- if (E->isIntegerConstantExpr(Value, S.Context)) {
+ if (E->EvaluateAsInt(Value, S.Context, Expr::SE_AllowSideEffects)) {
if (S.SourceMgr.isInSystemMacro(CC))
return;
@@ -7603,6 +7603,42 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_integer_precision);
}
+ if (TargetRange.Width == SourceRange.Width && !TargetRange.NonNegative &&
+ SourceRange.NonNegative && Source->isSignedIntegerType()) {
+ // Warn when doing a signed to signed conversion, warn if the positive
+ // source value is exactly the width of the target type, which will
+ // 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;
+ }
+ }
+ }
+ // Fall through for non-constants to give a sign conversion warning.
+ }
+
if ((TargetRange.NonNegative && !SourceRange.NonNegative) ||
(!TargetRange.NonNegative && SourceRange.NonNegative &&
SourceRange.Width == TargetRange.Width)) {
OpenPOWER on IntegriCloud