Fix -Wc++11-narrowing warnings for narrowing negative values to larger unsigned
types to actually includes the value, rather than saying <uninitialized>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158745 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 9167650..013af8a 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -397,14 +397,14 @@
if (!Initializer->isIntegerConstantExpr(InitializerValue, Ctx)) {
// Such conversions on variables are always narrowing.
return NK_Variable_Narrowing;
- } else if (FromWidth < ToWidth) {
+ }
+ bool Narrowing = false;
+ if (FromWidth < ToWidth) {
// Negative -> unsigned is narrowing. Otherwise, more bits is never
// narrowing.
if (InitializerValue.isSigned() && InitializerValue.isNegative())
- return NK_Constant_Narrowing;
+ Narrowing = true;
} else {
- ConstantValue = APValue(InitializerValue);
-
// Add a bit to the InitializerValue so we don't have to worry about
// signed vs. unsigned comparisons.
InitializerValue = InitializerValue.extend(
@@ -416,10 +416,13 @@
ConvertedValue = ConvertedValue.extend(InitializerValue.getBitWidth());
ConvertedValue.setIsSigned(InitializerValue.isSigned());
// If the result is different, this was a narrowing conversion.
- if (ConvertedValue != InitializerValue) {
- ConstantType = Initializer->getType();
- return NK_Constant_Narrowing;
- }
+ if (ConvertedValue != InitializerValue)
+ Narrowing = true;
+ }
+ if (Narrowing) {
+ ConstantType = Initializer->getType();
+ ConstantValue = APValue(InitializerValue);
+ return NK_Constant_Narrowing;
}
}
return NK_Not_Narrowing;
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
index e3909cc..9b1727f 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
@@ -169,18 +169,18 @@
Agg<char> ce2 = { ConvertVar<short>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}}
// Negative -> larger unsigned type.
- unsigned long long ll1 = { -1 }; // expected-error {{cannot be narrowed}} expected-note {{override}}
+ unsigned long long ll1 = { -1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{override}}
unsigned long long ll2 = { 1 }; // OK
- unsigned long long ll3 = { s }; // expected-error {{cannot be narrowed}} expected-note {{override}}
+ unsigned long long ll3 = { s }; // expected-error {{cannot be narrowed from type 'short'}} expected-note {{override}}
unsigned long long ll4 = { us }; // OK
- unsigned long long ll5 = { ll }; // expected-error {{cannot be narrowed}} expected-note {{override}}
- Agg<unsigned long long> ll6 = { -1 }; // expected-error {{cannot be narrowed}} expected-note {{override}}
+ unsigned long long ll5 = { ll }; // expected-error {{cannot be narrowed from type 'long long'}} expected-note {{override}}
+ Agg<unsigned long long> ll6 = { -1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{override}}
Agg<unsigned long long> ll7 = { 18446744073709551615ULL }; // OK
- Agg<unsigned long long> ll8 = { __int128(18446744073709551615ULL) + 1 }; // expected-error {{cannot be narrowed}} expected-note {{override}} expected-warning {{changes value}}
+ Agg<unsigned long long> ll8 = { __int128(18446744073709551615ULL) + 1 }; // expected-error {{ 18446744073709551616 which cannot be narrowed}} expected-note {{override}} expected-warning {{changes value}}
signed char c = 'x';
- unsigned short usc1 = { c }; // expected-error {{cannot be narrowed}} expected-note {{override}}
+ unsigned short usc1 = { c }; // expected-error {{non-constant-expression cannot be narrowed from type 'signed char'}} expected-note {{override}}
unsigned short usc2 = { (signed char)'x' }; // OK
- unsigned short usc3 = { (signed char)-1 }; // expected-error {{cannot be narrowed}} expected-note {{override}}
+ unsigned short usc3 = { (signed char)-1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{override}}
}
// Be sure that type- and value-dependent expressions in templates get the error