[cfe-commits] r149965 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/Sema/enum.c test/SemaObjC/enum-fixed-type.m test/SemaObjC/fixed-enum.m
Eli Friedman
eli.friedman at gmail.com
Mon Feb 6 20:34:39 PST 2012
Author: efriedma
Date: Mon Feb 6 22:34:38 2012
New Revision: 149965
URL: http://llvm.org/viewvc/llvm-project?rev=149965&view=rev
Log:
Fix a couple of nasty bugs involving negative enum constants. <rdar://problem/10760113>.
Removed:
cfe/trunk/test/SemaObjC/fixed-enum.m
Modified:
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/Sema/enum.c
cfe/trunk/test/SemaObjC/enum-fixed-type.m
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=149965&r1=149964&r2=149965&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Feb 6 22:34:38 2012
@@ -9600,23 +9600,6 @@
&EnumVal).take())) {
// C99 6.7.2.2p2: Make sure we have an integer constant expression.
} else {
- if (!getLangOptions().CPlusPlus) {
- // C99 6.7.2.2p2:
- // The expression that defines the value of an enumeration constant
- // shall be an integer constant expression that has a value
- // representable as an int.
-
- // Complain if the value is not representable in an int.
- if (!isRepresentableIntegerValue(Context, EnumVal, Context.IntTy))
- Diag(IdLoc, diag::ext_enum_value_not_int)
- << EnumVal.toString(10) << Val->getSourceRange()
- << (EnumVal.isUnsigned() || EnumVal.isNonNegative());
- else if (!Context.hasSameType(Val->getType(), Context.IntTy)) {
- // Force the type of the expression to 'int'.
- Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).take();
- }
- }
-
if (Enum->isFixed()) {
EltTy = Enum->getIntegerType();
@@ -9632,13 +9615,29 @@
Diag(IdLoc, diag::err_enumerator_too_large) << EltTy;
} else
Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
- } else {
+ } else if (getLangOptions().CPlusPlus) {
// C++11 [dcl.enum]p5:
// If the underlying type is not fixed, the type of each enumerator
// is the type of its initializing value:
// - If an initializer is specified for an enumerator, the
// initializing value has the same type as the expression.
EltTy = Val->getType();
+ } else {
+ // C99 6.7.2.2p2:
+ // The expression that defines the value of an enumeration constant
+ // shall be an integer constant expression that has a value
+ // representable as an int.
+
+ // Complain if the value is not representable in an int.
+ if (!isRepresentableIntegerValue(Context, EnumVal, Context.IntTy))
+ Diag(IdLoc, diag::ext_enum_value_not_int)
+ << EnumVal.toString(10) << Val->getSourceRange()
+ << (EnumVal.isUnsigned() || EnumVal.isNonNegative());
+ else if (!Context.hasSameType(Val->getType(), Context.IntTy)) {
+ // Force the type of the expression to 'int'.
+ Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).take();
+ }
+ EltTy = Val->getType();
}
}
}
@@ -9726,7 +9725,7 @@
if (!EltTy->isDependentType()) {
// Make the enumerator value match the signedness and size of the
// enumerator's type.
- EnumVal = EnumVal.zextOrTrunc(Context.getIntWidth(EltTy));
+ EnumVal = EnumVal.extOrTrunc(Context.getIntWidth(EltTy));
EnumVal.setIsSigned(EltTy->isSignedIntegerOrEnumerationType());
}
Modified: cfe/trunk/test/Sema/enum.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/enum.c?rev=149965&r1=149964&r2=149965&view=diff
==============================================================================
--- cfe/trunk/test/Sema/enum.c (original)
+++ cfe/trunk/test/Sema/enum.c Mon Feb 6 22:34:38 2012
@@ -117,3 +117,5 @@
PR8694(e); // expected-warning {{incompatible pointer types passing 'enum E *' to parameter of type 'int *'}}
}
+typedef enum { NegativeShort = (short)-1 } NegativeShortEnum;
+int NegativeShortTest[NegativeShort == -1 ? 1 : -1];
Modified: cfe/trunk/test/SemaObjC/enum-fixed-type.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/enum-fixed-type.m?rev=149965&r1=149964&r2=149965&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/enum-fixed-type.m (original)
+++ cfe/trunk/test/SemaObjC/enum-fixed-type.m Mon Feb 6 22:34:38 2012
@@ -25,3 +25,13 @@
long value = 2;
Enumeration e = value;
}
+
+// <rdar://10381507>
+typedef enum : long { Foo } IntegerEnum;
+int arr[(sizeof(typeof(Foo)) == sizeof(typeof(IntegerEnum))) - 1];
+int arr1[(sizeof(typeof(Foo)) == sizeof(typeof(long))) - 1];
+int arr2[(sizeof(typeof(IntegerEnum)) == sizeof(typeof(long))) - 1];
+
+// <rdar://problem/10760113>
+typedef enum : long long { Bar = -1 } LongLongEnum;
+int arr3[(long long)Bar == (long long)-1 ? 1 : -1];
Removed: cfe/trunk/test/SemaObjC/fixed-enum.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/fixed-enum.m?rev=149964&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/fixed-enum.m (original)
+++ cfe/trunk/test/SemaObjC/fixed-enum.m (removed)
@@ -1,7 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// rdar://10381507
-
-typedef enum : long { Foo } IntegerEnum;
-int arr[(sizeof(typeof(Foo)) == sizeof(typeof(IntegerEnum))) - 1];
-int arr1[(sizeof(typeof(Foo)) == sizeof(typeof(long))) - 1];
-int arr2[(sizeof(typeof(IntegerEnum)) == sizeof(typeof(long))) - 1];
More information about the cfe-commits
mailing list