diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-06-13 01:07:41 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-06-13 01:07:41 +0000 |
commit | cd65f4903dc737d92655a0cf72755c16831ae668 (patch) | |
tree | 951c7e96d5fd0ee80e32486785814a90ae402d33 /lib/Sema/SemaOverload.cpp | |
parent | e0deb035b3e2d07b41ea55db84b110abcb65b753 (diff) |
Add missing narrowing check: converting from a signed integral type to a wider
unsigned type is narrowing if the source is non-constant or negative.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158377 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 994471ab5c..d723d45587 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -389,11 +389,20 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, const unsigned ToWidth = Ctx.getIntWidth(ToType); if (FromWidth > ToWidth || - (FromWidth == ToWidth && FromSigned != ToSigned)) { + (FromWidth == ToWidth && FromSigned != ToSigned) || + (FromSigned && !ToSigned)) { // Not all values of FromType can be represented in ToType. llvm::APSInt InitializerValue; const Expr *Initializer = IgnoreNarrowingConversion(Converted); - if (Initializer->isIntegerConstantExpr(InitializerValue, Ctx)) { + if (!Initializer->isIntegerConstantExpr(InitializerValue, Ctx)) { + // Such conversions on variables are always narrowing. + return NK_Variable_Narrowing; + } else if (FromWidth < ToWidth) { + // Negative -> unsigned is narrowing. Otherwise, more bits is never + // narrowing. + if (InitializerValue.isSigned() && InitializerValue.isNegative()) + return NK_Constant_Narrowing; + } else { ConstantValue = APValue(InitializerValue); // Add a bit to the InitializerValue so we don't have to worry about @@ -411,9 +420,6 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, ConstantType = Initializer->getType(); return NK_Constant_Narrowing; } - } else { - // Variables are always narrowings. - return NK_Variable_Narrowing; } } return NK_Not_Narrowing; |