Skip to content

Commit 7b1a950

Browse files
committedFeb 21, 2018
[Sema] Classify conversions from enum to float as narrowing
Summary: According to [dcl.init.list]p7: A narrowing conversion is an implicit conversion - ... - from an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type, or - ... Currently clang does not handle the 'unscoped enumeration' case. This patch fixes the corresponding check. Reviewers: faisalv, rsmith, rogfer01 Reviewed By: rogfer01 Subscribers: rogfer01, cfe-commits Differential Revision: https://reviews.llvm.org/D42545 llvm-svn: 325668
1 parent 51f7b63 commit 7b1a950

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed
 

‎clang/lib/Sema/SemaOverload.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,8 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx,
327327
FloatingIntegralConversion:
328328
if (FromType->isRealFloatingType() && ToType->isIntegralType(Ctx)) {
329329
return NK_Type_Narrowing;
330-
} else if (FromType->isIntegralType(Ctx) && ToType->isRealFloatingType()) {
330+
} else if (FromType->isIntegralOrUnscopedEnumerationType() &&
331+
ToType->isRealFloatingType()) {
331332
llvm::APSInt IntConstantValue;
332333
const Expr *Initializer = IgnoreNarrowingConversion(Converted);
333334
assert(Initializer && "Unknown conversion expression");

‎clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ void std_example() {
2424
{ 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level
2525
}
2626

27+
enum UnscopedEnum {
28+
EnumVal = 300
29+
};
30+
2731
// Test each rule individually.
2832

2933
template<typename T>
@@ -115,15 +119,21 @@ void shrink_float() {
115119
void int_to_float() {
116120
// Not a constant expression.
117121
char c = 1;
122+
UnscopedEnum e = EnumVal;
118123

119124
// Variables. Yes, even though all char's will fit into any floating type.
120125
Agg<float> f1 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{silence}}
121126
Agg<double> f2 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{silence}}
122127
Agg<long double> f3 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{silence}}
123128

129+
Agg<float> f4 = {e}; // expected-error {{ cannot be narrowed }} expected-note {{silence}}
130+
Agg<double> f5 = {e}; // expected-error {{ cannot be narrowed }} expected-note {{silence}}
131+
Agg<long double> f6 = {e}; // expected-error {{ cannot be narrowed }} expected-note {{silence}}
132+
124133
// Constants.
125-
Agg<float> f4 = {12345678}; // OK (exactly fits in a float)
126-
Agg<float> f5 = {123456789}; // expected-error {{ cannot be narrowed }} expected-note {{silence}}
134+
Agg<float> f7 = {12345678}; // OK (exactly fits in a float)
135+
Agg<float> f8 = {EnumVal}; // OK
136+
Agg<float> f9 = {123456789}; // expected-error {{ cannot be narrowed }} expected-note {{silence}}
127137

128138
Agg<float> ce1 = { Convert<int>(123456789) }; // expected-error {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{silence}}
129139
Agg<double> ce2 = { ConvertVar<long long>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{silence}}

0 commit comments

Comments
 (0)